JDBC学习DayTwo
一、利用反射及JDBC元數據編寫通用的查詢方法
1.ResultSetMetaData
定義:描述ResultSet的元數據對象,即從中可以獲取到結果集中有多少列、列名是什么。
獲取 ResultSetMetaData 對象:
調用 ResultSet 的 getMetaData() 方法
方法:
int getColumnCount():SQL語句中包含的列數
String getColumnLabel(int column):獲取指定的列的別名,其中索引從1開始
2.通用的查詢方法
/*** 通用的查詢方法:可以根據傳入的SQL、Class對象返回SQL對應的對象* * @param clazz:* 描述對象的類型* @param sql:* SQL語句,可能帶占位符* @param args:* 填充占位符的可變參數*/public <T> T get(Class<T> clazz, String sql, Object... args) {T entity = null;Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {// 1.獲得ResultSet對象conn = getConnection();ps = conn.prepareStatement(sql);for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery();// 2.得到ResultSetMetaData對象ResultSetMetaData rsmd = rs.getMetaData();// 3.創建一個Map<String, Object>對象,鍵:SQL查詢的列的別名;值:列的值Map<String, Object> values = new HashMap<>();// 4.處理結果集,利用ResultSetMetaData填充3對應的Map對象if (rs.next()) {for (int i = 0; i < rsmd.getColumnCount(); i++) {String columnLabel = rsmd.getColumnLabel(i + 1);Object columnValue = rs.getObject(i + 1);values.put(columnLabel, columnValue);}}// 5.若Map不為空集,利用反射創建 clazz 對應的對象if (values.size() > 0) {entity = clazz.newInstance();// 6.遍歷Map對象,利用反射為Class對象的對應的屬性賦值。for (Map.Entry<String, Object> entry : values.entrySet()) {String fieldName = entry.getKey();Object value = entry.getValue();setFieldValue(entity, fieldName, value);}}} catch (Exception e) {e.printStackTrace();} finally {try {rs.close();} catch (SQLException e) {e.printStackTrace();}try {ps.close();} catch (SQLException e) {e.printStackTrace();}try {conn.close();} catch (SQLException e) {e.printStackTrace();}}return entity;} /*** 利用反射給具體對象的屬性賦值*/public void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Class<? extends Object> clazz = obj.getClass();Field field = clazz.getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);} 使用該通用方法:
/*** 使用通用的查詢方法*/public void testGet(){String sql = "select id, name, email, birth " + "from customers where id = ?";Customer customer = get(Customer.class, sql, 5);System.out.println(customer);} ?二、DAO設計模式
1.定義:
DAO即 Data Access Object ,訪問數據信息的類,包含了對數據的CRUD(create, read, update, delete),而不包含任何業務相關的信息。
2.作用:
實現功能的模塊化,更有利于代碼的保護和升級。
3.方法:
void update(String sql, Object ... args); //INSERT,UPDATE,DELETE操作都可以包含在其中
// INSERT,UPDATE,DELETE操作都可以包含在其中public void update(String sql, Object... args) {Connection conn = null;PreparedStatement ps = null;try {conn = JDBCTools.getConnection();ps = conn.prepareStatement(sql);for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {JDBCTools.releaseDB(ps, null, conn);}} public class JDBCTools {public static void releaseDB(Statement stat, ResultSet rs, Connection conn){if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}}if (stat != null) {try {stat.close();} catch (SQLException e) {e.printStackTrace();}}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}public static Connection getConnection() throws Exception{// 1.準備連接數據庫的基本信息String driver = null;String jdbcUrl = null;String user = null;String password = null;// 讀取類路徑下的jdbc.properties文件InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");Properties properties = new Properties();properties.load(in);driver = properties.getProperty("driver");jdbcUrl = properties.getProperty("jdbcUrl");user = properties.getProperty("user");password = properties.getProperty("password");// 2.加載數據庫驅動程序(對應的Driver實現類中有注冊驅動的靜態代碼塊)// DriverManager// .registerDriver(Class.forName(driverClass).newInstance));
Class.forName(driver);// 3.通過DriverManager的getConnection()方法 獲取數據庫連接Connection conn = DriverManager.getConnection(jdbcUrl, user, password);return conn;}
} <T> T get(Class<T> calzz, String sql, Object ... args); //查詢一條記錄,返回對應的對象
// 查詢一條記錄,返回對應的對象public <T> T get(Class<T> clazz, String sql, Object... args) {List<T> result = getForList(clazz, sql, args);//查詢多條記錄的方法if(result.size() > 0){return result.get(0);}return null;} <T> List<T> getForList(Class<T> clazz, String sql, Object ... args); //查詢多條記錄,返回對應的對象的集合
// 查詢多條記錄,返回對應的對象的集合public <T> List<T> getForList(Class<T> clazz, String sql, Object... args) {List<T> list = new ArrayList<>();Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {//1.得到結果集conn = JDBCTools.getConnection();ps = conn.prepareStatement(sql);for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery();//2.處理結果集,得到Map的List,其中一個Map對象對應一條記錄List<Map<String, Object>> values = handleResultSetToMapList(rs);//3.把Map的List轉為clazz對應的Listlist = transferMapListToBeanList(clazz, values);} catch (Exception e) {e.printStackTrace();} finally {JDBCTools.releaseDB(ps, rs, conn);}return list;}/*** 將Map對應的List轉換為clazz對應的List* @param clazz* @param values* @return* @throws Exception*/private <T> List<T> transferMapListToBeanList(Class<T> clazz, List<Map<String, Object>> values)throws Exception {List<T> result = new ArrayList<T>();T bean = null;if (values.size() > 0) {for (Map<String, Object> m : values) {bean = clazz.newInstance();for (Map.Entry<String, Object> entry : m.entrySet()) {String fieldName = entry.getKey();Object value = entry.getValue();JdbcTest.setFieldValue(bean, fieldName, value);}result.add(bean);}}return result;}/*** 處理結果集,得到Map的一個List,其中一個Map對象代表一條記錄* * @param rs* @return* @throws SQLException*/private List<Map<String, Object>> handleResultSetToMapList(ResultSet rs) throws SQLException {List<String> columnLabels = getColumnLabels(rs);List<Map<String, Object>> values = new ArrayList<>();Map<String, Object> map = null;while (rs.next()) {map = new HashMap<>();for (String label : columnLabels) {Object ColumnValue = rs.getObject(label);map.put(label, ColumnValue);}values.add(map);}return values;}/*** 獲取結果集的ColumnLabel(列的別名) 對應的List* * @param rs* @return* @throws SQLException*/private List<String> getColumnLabels(ResultSet rs) throws SQLException {List<String> labels = new ArrayList<>();ResultSetMetaData rsmd = rs.getMetaData();for (int i = 0; i < rsmd.getColumnCount(); i++) {labels.add(rsmd.getColumnLabel(i + 1));}return labels;} <E> E getForValue(String sql, Object ... args); //返回某條記錄的某一個字段的值或者一個統計的值(統計一共有多少條記錄等)
// 返回某條記錄的某一個字段的值或者一個統計的值(統計一共有多少條記錄或最大的值等)public <E> E getForValue(String sql, Object... args) {// 得到結果集:該結果集應該只有一行,且只有一列Connection conn = null;PreparedStatement ps = null;ResultSet rs = null;try {conn = JDBCTools.getConnection();ps = conn.prepareStatement(sql);for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}rs = ps.executeQuery();if (rs.next()) {return (E) rs.getObject(1);}} catch (Exception e) {e.printStackTrace();} finally {JDBCTools.releaseDB(ps, rs, conn);}return null;} 4.使用Beanutils工具類操作JavaBean
JavaBean 通過提供符合一致性設計模式的公共方法將內部域暴露成員屬性,通過getter和setter方法來定義屬性的get和set方法。
可以通過一個apache的開源工具包 beanutils 來操作Java類的屬性。
要先導入commons-logging包和commons-beanutils包到類路徑下。
方法:setProperty(Object bean, String name, Object value):給對象bean的名字為name的屬性賦value的值
? getProperty(Object bean, String name):返回對象bean的名為name的屬性的值
實例:
public void BeanutilsTest() throws Exception{Object obj = new Customer();System.out.println(obj);//Customer [id=0, name=null, email=null, birth=null]BeanUtils.setProperty(obj, "id", "123");System.out.println(obj);//Customer [id=123, name=null, email=null, birth=null]Object value = BeanUtils.getProperty(obj, "id");System.out.println(value);//123} 注:上面DAO的方法中利用反射給對象的屬性賦值都可以換成beanutils的方法來賦值
//JdbcTest.setFieldValue(entity, fieldName, value);
BeanUtils.setProperty(entity, fieldName, value); ?三、JDBC的元數據
1.DataBaseMetaData
是在Connection對象上獲得的(DataBaseMetaData dbmd = connnection.getMetaData()),DataBaseMetaData類的對象實現了獲得有關數據庫管理系統的各種信息的方法 ,包括數據庫的各個表,表中的各個列,數據類型,觸發器,存儲方面等各方面信息。
2.ResultSetMetaData
是在ResultSet對象上獲得的,實現了獲得結果集的列數和列的別名等方法。
四、處理Blob
1.定義:
LOB,即Large Objects(大對象),是用來存儲大量的二進制和文本數據的一種數據類型(一個LOB字段可以存儲多達4GB的數據)
2.分類:
內部LOB:
BLOB(二進制數據)
CLOB(單字節字符數據)
NCLOB(多字節字符數據)
CLOB和NCLOB適合存儲超長的文本數據。BLOB適合處理大量的二進制數據,如圖像,視頻,音頻,文件等。
外部LOB:
BFILE
BFILE的數據是只讀的,不參與事務。可幫助用戶管理大量的由外部程序訪問的文件。
3.實例:
/*** 插入Blob類型的數據必須用PreparedStatement,因為Blob類型的數據無法使用字符串拼寫*/public void testInsertBlob() {Connection conn = null;PreparedStatement ps = null;try {conn = JDBCTools.getConnection();String sql = "INSERT INTO customers (NAME, EMAIL, BIRTH,PICTURE) " + "VALUES(?,?,?,?)";ps = conn.prepareStatement(sql);ps.setString(1, "AAA");ps.setString(2, "abc@163.com");ps.setDate(3, new Date(new java.util.Date().getTime()));InputStream is = new FileInputStream("123.jpg");ps.setBlob(4, is);// 2)調用executeUpdate(sql)
ps.executeUpdate();} catch (Exception e) {e.printStackTrace();} finally {JDBCTools.releaseDB(null, ps, conn);}} ?
轉載于:https://www.cnblogs.com/lsf2576/p/10673103.html
總結
以上是生活随笔為你收集整理的JDBC学习DayTwo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring 基于XML的申明式Aspe
- 下一篇: 轿车变速箱油换一次多少钱