JDBC框架入門及DBUtils的入門
一、【數據庫元數據的獲取】(做框架用時非常實用)主要有以下java接口(都在java.sql.*包中):
1>DataBaseMetaData 數據庫元數據
元數據:數據庫本身及表結構、字段類型等的信息,稱之為元數據。
好處:獲取一些數據庫的信息,比如數據庫方言,數據庫版本,建表的一些信息等。
如:DatabaseMetaData md = conn.getMetaData();然后可用md.getDatabaseProductName
2>ParameterMetaData 可獲取 PreparedStatement 對象中每個參數標記的類型和屬性信息的對象
如: ParameterMetaData md = stmt.getParameterMetaData();
md.getParameterCount() 獲取參數?的個數。
md.getParameterTypeName(int index) 獲取指定參數對應數據庫中的類型名稱。
等等。
3>ResultSetMetaData 可獲取ResultSet 對象中列的類型和屬性信息的對象。
如:ResultSetMetaData md = rs.getMetaData();
int count = md.getColumnCount(); 獲取結果集中存在幾列。
md.getColumnName(int index); 獲取指定列的列名名稱。
md.getColumnTypeName(int column); 獲取指定列的數據庫特定的類型名稱。
等等。
二、【自定義框架原理】
1>可通過上面的三個元數據類,獲取比如參數的個數。將需要執行的sql與參數數組傳遞進框架中,然后通過PrepardeStatment stmt=conn.preparedStatement(sql);獲取到stmt對象。那么通過stmt.getParameterMetaData().getParameterCount()獲取到參數的個數后,可以寫相關的循環,用stmt.setObject(index,arg[i])分別設置好參數。直接executeUpdate或executeQuery即可。
對于DML語句來說,是用executeUpdate方法執行的,所以不需要返回值,基本上一個核心方法即可搞定。
2>而對于DQL語句來說,Select出來的結果集,可以被封裝成多個不同類型的java對象。所以可以在執行rs = stmt.executeQuery();(注意前面的設置參數也是上面的提成的,直接用ParameterMetaDate獲取的參數個數后,循環分別將數組中元素用setObject搞定),然后可將rs作為參數傳遞到ResultSetHandler接口的handler方法中。此handler方法返回Object類型,由用戶自行去實現ResultSetHandler接口,這樣用戶可以對rs處理后,封裝成自己想要的對象。
3>當然為了方便實現框架最好提供默認的BeanHandler(Class clazz)類的實現,此類對handler方法的實現只是將rs結果集封裝成傳遞到BeanHandler類構造參數的clazz類實例中。
4>同理還需要提供一個常用的BeanListHandler(Class clazz)類實現,將rs結果集先封裝成指定clazz的javabean中,再將這些javabean全部放入到List容器中。(以上兩個方法必須要用反射實現)。
三、【開源jdbc框架DBUtils】 是apache提供一個優秀的jdbc框架,原理就是上面自定義框架原理。
核心類QueryRunner
1、有2個構造方法,需要一個 javax.sql.DataSource 來作參數的構造方法,通過這個數據源,來獲取Connection
2、QueryRunner主要方法有2個 query和update。來分別提供對DQL與DML語句的支持。
3、對于查詢到的結果集,提供了一個接口 ResultSetHandler
框架中提供了以下對ResultSetHandler接口實現的類
ArrayHandler:將查詢到的某一行封裝到一個數組當中,這個數組中的元素就是這一行中的一列
ArrayListHandler:將查詢到的很多行結果,封裝到一個容器當中,這個容器中存放都是數組
BeanHandler:將查詢到的結果封裝到javaBean中 在創建這個對象的時候,需要指定javaBean的type(ClassName.Class)
BeanListHandler:將查詢到的很多javaBean封裝到一個容器中
ColumnListHandler: 將結果集中某一列的數據存放到List中。 創建對象的時候,參數需要指定列名
將結果集中的每一行數據都封裝到一個Map<列名,列值>里,
再把這些map再存到一個大map里,小map的key作為大map的key
MapHandler:將結果集中的第一行數據封裝到一個Map里,key是列名,value就是對應的值。
MapListHandler:將結果集中的每一行數據都封裝到一個Map里,然后再存放到List
ScalarHandler:取一行中的某一列的值。(用于select count(*) from ...)
示例代碼如下: public class ResultHandlerDemo {
//獲取QueryRunner對象。
private QueryRunner qr = new QueryRunner(DbcpUtil.getDataSource());
@Test
public void test1() throws SQLException{
String sql = "select * from person where id=?";
Object params = 1;
Person person = qr.query(sql, new BeanHandler<Person>(Person.class), params);//執行DQL,用query
System.out.println(person);
}
@Test
public void test2() throws SQLException{
String sql = "delete from person where id=?";
Object params = 1;
qr.update(sql, params);//執行DML,用update
}
}