注: 這裏使用mysql數據庫。java
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/數據庫名?useUnicode=true&characterEncoding=utf-8 jdbc.username=root jdbc.password=1234
import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * 使用JDBC進行數據庫鏈接與關閉的工具類 * * @author XIAOHU * @since 2018-04-08 */ public class JDBCUtil { private static String driver; private static String url; private static String username; private static String password; static { init(); try { // 加載一次驅動 Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /** * 初始化數據庫鏈接數據 */ public static void init() { Properties prop = new Properties(); InputStream is = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties"); try { prop.load(is); } catch (IOException e) { e.printStackTrace(); } driver = prop.getProperty("jdbc.driver"); url = prop.getProperty("jdbc.url"); username = prop.getProperty("jdbc.username"); password = prop.getProperty("jdbc.password"); } /** * 獲取數據庫鏈接 * * @return */ public static Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, username, password); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 釋放全部資源 * * @param rs * 結果集 * @param st * Statement對象 * @param conn * 數據庫鏈接 */ public static void closeAll(ResultSet rs, Statement st, Connection conn) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
/** * 字符串處理工具類 * * @author XIAOHU * @since 2018-04-11 */ public class StringUtil { /** * 將字符串首字母轉爲大寫 * @param str 要轉換的字符串 * @return 返回轉換後的首字母大寫的字符串 */ public static String toUpper(String str){ return str.substring(0, 1).toUpperCase() + str.substring(1); } }
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import cn.xiyou.petshopsystem.utils.JDBCUtil; import cn.xiyou.petshopsystem.utils.StringUtil; /** * 封裝JDBC的增刪改查功能 * * @author XIAOHU * @since 2018-04-11 * */ public class BaseDao<T> { /** * 封裝增、刪、改功能 * * @param sql * 須要執行的sql語句 * @param args * 不定參數,是對sql語句中的佔位符「?」傳入的參數 * @return 返回操做所影響的行數 */ public int executeUpdate(String sql, Object... args) { Connection conn = null; PreparedStatement pst = null; int rows = 0; try { conn = JDBCUtil.getConnection(); pst = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { pst.setObject(i + 1, args[i]); } rows = pst.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.closeAll(null, pst, conn); } return rows; } /** * 查詢一條記錄 * * @param sql * 須要執行的sql語句 * @param cls * 由此 Class對象建模的類的類型。若是將被建模的類未知,則使用 Class<?>。 * 例如,String.class 的類型是Class<String>。 * @param args * 不定參數,是對sql語句中的佔位符「?」傳入的參數 * @return 返回操做所影響的行數 */ public T selectOne(String sql, Class<T> cls, Object... args) { List<T> list = this.selectMany(sql, cls, args); return list.isEmpty() ? null : list.get(0); } /** * 查詢全部記錄 * * @param sql * 須要執行的sql語句 * @param cls * 由此 Class對象建模的類的類型。若是將被建模的類未知,則使用 Class<?>。 * 例如,String.class 的類型是Class<String>。 * @param args * 不定參數,是對sql語句中的佔位符「?」傳入的參數 * @return 返回操做所影響的行數 */ public List<T> selectMany(String sql, Class<T> cls, Object... args) { Connection conn = null; PreparedStatement pst = null; ResultSet rs = null; List<T> list = new ArrayList<T>(); try { conn = JDBCUtil.getConnection(); pst = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { pst.setObject(i + 1, args[i]); } rs = pst.executeQuery(); //從結果集中獲取數據庫表的相關信息 ResultSetMetaData metaData = rs.getMetaData(); while (rs.next()) { T obj = cls.newInstance();// 建立cls實例 //metaData.getColumnCount():得到數據庫表中列數(字段數) for (int i = 1; i <= metaData.getColumnCount(); i++) { String columnLabel = metaData.getColumnLabel(i);//獲取字段名 // 動態拼接成該屬性對應實體中的setter方法的方法名(=set字符串拼接首字母大寫 // 的屬性名)。如:setName(Stringname)的方法名爲setName String name = "set" + StringUtil.toUpper(columnLabel); // 獲取實體中全部聲明(私有+公有)的屬性 Field field = cls.getDeclaredField(columnLabel); // 獲取實體中全部聲明(私有+公有)的形參爲field.getType()類型,方法名爲 // name的方法 Method method = cls.getDeclaredMethod(name, field.getType()); // 經過結果集獲取字段名爲fieldName(與實體中的對應屬性名徹底相同)的值 Object realParam = rs.getObject(columnLabel); // 執行obj對象中的method方法,傳入的實參爲realParam method.invoke(obj, realParam); } list.add(obj); } } catch (SQLException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } finally { JDBCUtil.closeAll(null, pst, conn); } return list; } /** * 查詢總記錄數 * * @param sql * 須要執行的sql語句 * @param args * 須要對sql語句中的佔位符「?」傳入的參數數組 * @return 返回操做所影響的行數 */ public int selectCount(String sql, Object... args) { Connection conn = null; PreparedStatement pst = null; ResultSet rs = null; int count = 0; try { conn = JDBCUtil.getConnection(); pst = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { pst.setObject(i + 1, args[i]); } rs = pst.executeQuery(); if (rs.next()) { count = rs.getInt(1); } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.closeAll(null, pst, conn); } return count; } }
說明: 這裏僅作了部分封裝,更多的封裝須要本身去實現。BaseDao.java中的封裝代碼爲重點,相似於一些框架底層的實現,想要更深一步學習封裝的,但願本身去看一些框架源碼和設計模式。mysql