jdbc框架{
元數據:數據庫、表、列的定義信息——在框架中才涉及到的知識
DataBaseMetaData對象(數據庫){
獲取方法:connection.getMetaData();
使用:
getURL();——返回當前連接的數據庫的URL信息
getUserName();——返回當前連接的數據庫的用戶名
getDatabaseProductName();——數據庫的產品名稱
getDatabaseProductVersion();——數據庫的版本號
getDriverName();——驅動程序的名稱
getDriverVersion();——驅動程序的版本號
isReadOnly();——指示數據庫是否只允許讀的操作
...
例:
Connection conn = JdbcUtils.getConnection(); DatabaseMetaData md = conn.getMetaData(); System.out.println(md.getURL());//輸出:jdbc:mysql://localhost:3306/mydb System.out.println(md.getDatabaseProductName());//輸出:MySQL System.out.println(md.getDriverVersion());//輸出:mysql-connector-java-5.1.22 ( Revision: ${bzr.revision-id} )
}
ParameterMetaData(參數){
獲取方法:preparedStatement.getParameterMetaData();——例如一條select * from user where name=? and password=?;這個對象就是這條sql語句參數(問號)的元數據
使用:
getParameterCount();——獲得指定參數的個數
getParameterType(int param);——指定參數的sql類型
...
例:
Connection conn = JdbcUtils.getConnection(); String sql = "insert into user(id,name) values(?,?)"; PreparedStatement st = conn.prepareStatement(sql); ParameterMetaData md = st.getParameterMetaData(); System.out.println(md.getParameterCount());//輸出:2 // System.out.println(md.getParameterType(1));該方法由於mysql的驅動不支持,會拋異常
}
ResultSetMetaData(結果集){
獲取方法:resultSet.getMetaData();——獲得代表結果集ResultSet對象的元數據,告訴用戶結果集的一些信息
使用:
getColumnCount();——結果集對象的列數
getColumnName(int column);——指定列的名稱
getColumnTypeName(int column);——指定列的類型
...
例:
Connection conn = JdbcUtils.getConnection(); String sql = "select * from user"; PreparedStatement st = conn.prepareStatement(sql); ResultSet rs = st.executeQuery(); ResultSetMetaData md = rs.getMetaData(); System.out.println(md.getColumnCount());//輸出:一共有多少列 System.out.println(md.getColumnName(1));//輸出:第一列的列名 System.out.println(md.getColumnType(1));//輸出:第一列的類型
}
編寫增刪改查的框架(方法){
//增刪改的工具方法,只需要將sql語句和sql中的問號對應的參數用數組形式傳進方法,就可以執行成功 public static void update(String sql, Object params[]) throws SQLException { // 定義基本對象 Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); st = conn.prepareStatement(sql); // 根據傳進來的參數數組填充sql中的問號 for (int i = 0; i < params.length; i++) { st.setObject(i+1, params[i]); } st.executeUpdate(); }finally{ JdbcUtils.release(conn, st, rs); } } // 查的工具方法,還要得到一個用戶想要處理結果集的類,用戶只需要new一個處理類的對象進來即可 public static Object query(String sql, Object params[], ResultSetHandler handler) throws SQLException{ // 定義基本對象 Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try { conn = JdbcUtils.getConnection(); st = conn.prepareStatement(sql); // 根據傳進來的參數數組填充sql中的問號 for (int i = 0; i < params.length; i++) { st.setObject(i+1, params[i]); } // 由於這邊得到的結果集有些內容都不知,可以向用戶暴露一個處理接口的方法,然後直接在該程序中調用這個處理的方法。 // 用戶實現了這個接口並做出了想要的處理,傳遞到本程序中,就能返回用戶想用的數據 rs = st.executeQuery(); return handler.handler(rs); }finally{ JdbcUtils.release(conn, st, rs); } } } // 定義接口 interface ResultSetHandler{ public abstract Object handler(ResultSet rs); } //實現處理單行數據的類,返回封裝了結果數據的對象,如果需要處理的是多行的數據,就需要使用集合,把每行數據封裝成對象,再存入集合。那麼這個方法返回的就是集合對象 class BeanHandler implements ResultSetHandler{ // 通過構造函數獲得對象的字節碼,以備將結果集存到該對象中 private Class clazz = null; public BeanHandler(Class clazz) { super(); this.clazz = clazz; } @Override public Object handler(ResultSet rs) { try { if(rs.next()){ return null; } // 創建封裝結果集的bean對象 Object bean = clazz.newInstance(); // 通過元數據的技術得到結果集的內容 ResultSetMetaData md = rs.getMetaData(); for (int i = 0; i < md.getColumnCount(); i++) { // 獲取結果集每列的名稱 String columnName = md.getColumnName(i+1); // 得到該列的值 Object value = rs.getObject(columnName); // 爲bean對象裏的列名對應的屬性賦value,使用反射技術;也可以使用beanutils庫,這樣就必須導入一個庫,不方便 //獲取bean裏的屬性,需要設置爲私有可見 Field f = bean.getClass().getDeclaredField(columnName); f.setAccessible(true); //進行賦值 f.set(bean, value); } return bean; } catch (Exception e) { throw new RuntimeException(); } }
}
開源框架dbutils{
1.commons-dbutils是Apache組織提供的一個開源jdbc工具類庫,他是對jdbc的簡單封裝,使用dbutils能極大簡化jdbc編碼的工作量同時也不會影響程序性能
2.使用dbutils需要查看api文檔,內部主要是兩個類QueryRunner(用於增刪改查)和ResultSetHandler(用於處理查詢的結果集)
例:
結果集處理器(ResultSetHandler實現類){public void add(){ try { // 使用QueryRunner和ResultSetHandler // 創建一個Queryrunner對象,將數據庫的數據源作爲構造函數傳入 QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); // 定義sql語句和參數對象 String sql = "insert into user(id,name) values(?,?)"; Object params[] = {"1", "aaa"}; // 執行更新操作,將sql和參數傳入 runner.update(sql, params); } catch (Exception e) { throw new RuntimeException(e); } } public void query(){ try { // 使用QueryRunner和ResultSetHandler // 創建一個Queryrunner對象,將數據庫的數據源作爲構造函數傳入 QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); // 定義sql語句和參數對象 String sql = "select * from user"; // 執行更新操作,將sql傳入.並且將結果處理到list容器中 List<User> list = runner.query(sql, new BeanListHandler<User>(User.class)); } catch (Exception e) { throw new RuntimeException(e); } }
ArrayHandler:把結果集的第一行數據封裝到一個數組內,返回數組對象。——new ArrayHandler();
ArrayListHandler:把結果集的每一行數據都封裝到一個數組中,再將每個數組存到list集合內,返回list對象。——new ArrayListHandler();
BeanHandler:將結果集的第一行數據封裝到一個bean對象中,需要將bean的字節碼對象傳入,返回bean對象。——new BeanHandler(User.class);
BeanListHandler:將結果集的每一行數據封裝到一個bean對象中,再存放在list集合內,同樣需要傳入bean的字節碼對象,返回list對象。——new BeanListHandler(User.class);
ColumnListHandler:將結果集的某一列的數據存放在list中,需要將列名傳入,返回list對象。——new ColumnListHandler("id");
KeyedHandler:將結果集的每一行數據都封裝到一個map(key爲列名,value爲該列的值)中,再將這個map存放在另一個map中(key爲傳入的指定列名的值,value就是map),返回map對象。——new KeyedHandler("id");
MapHandler:將結果集的第一行數據封裝到一個map中,key爲列名,value爲該列的值,返回map對象。——new MapHandler();
MapListHandler:將結果集的每一行數據都封裝到一個map中,再存放在list中,返回list對象。——new MapListHandler();
ScalarHandler:將制定的第一行的某一列(可以傳入第幾列或者列名)的值存放在一個對象內,返回該對象。——new ScalarHandler(1);
例:
//查詢總記錄數 QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select count(*) from user"; //// 1.使用arrayhandler處理器 // Object result[] = runner.query(sql, new ArrayHandler()); //// 取出數據,取出的是Long型的數據,需要進行轉型 // int count = ((Long)result[0]).intValue(); // 2.使用scalarhandler處理器,取出第一列的值,指定了封裝到Long對象中,進行轉型 int count = runner.query(sql, new ScalarHandler<Long>(1)).intValue();
}
}
}