dbutils API学习
dbutils API介紹
1.簡介
? dbutils就是JDBC操作的類庫,是對JDBC操作的封裝,提供一些簡易的API來操作數(shù)據(jù)庫,提供了數(shù)據(jù)庫增刪改查等通用的JDBC實現(xiàn)。
2.org.apache.commons.dbutils.handlers包
? 這個包里面的類是對ResultSetHandler接口的實現(xiàn)類,主要是用來處理ResultSet(結(jié)果集)的轉(zhuǎn)換,將結(jié)果集轉(zhuǎn)成Object[],List< Object[] >,List< T >,Map< K,V >等的數(shù)據(jù)結(jié)構(gòu)。這些實現(xiàn)類會在做數(shù)據(jù)庫查詢操作時使用,主要有以下類:
- AbstractListHandler 將ResultSet轉(zhuǎn)為List的抽象類
- ArrayHandler 將ResultSet轉(zhuǎn)為一個Object[]的ResultSetHandler實現(xiàn)類
- ArrayListHandler 將ResultSet轉(zhuǎn)換為List< Object[] >的ResultSetHandler實現(xiàn)類
- BeanHandler 將ResultSet行轉(zhuǎn)換為一個JavaBean的ResultSetHandler實現(xiàn)類
- BeanListHandler 將ResultSet轉(zhuǎn)換為List< T >的ResultSetHandler實現(xiàn)類
- ColumnListHandler 將ResultSet的一個列轉(zhuǎn)換為List< Object >的ResultSetHandler實現(xiàn)類
- KeyedHandler 將ResultSet轉(zhuǎn)換為Map< K,V>的ResultSetHandler實現(xiàn)類
- MapHandler 將ResultSet的首行轉(zhuǎn)換為一個Map的ResultSetHandler實現(xiàn)類
- MapListHandler 將ResultSet轉(zhuǎn)換為List< K,V>的ResultSetHandler實現(xiàn)類
- ScalarHandler 將ResultSet的一個列到一個對象。
3.org.apache.commons.dbutils.QueryRunner
? 它與ResultSetHandler組合在一起使用可以完成大部分的數(shù)據(jù)庫操作,是用來執(zhí)行SQL語句的工具類。主要的方法如下。
QueryRunner的無參構(gòu)造函數(shù)和有參構(gòu)造函數(shù):
QueryRunner中一共有6種方法:
- execute(執(zhí)行SQL語句)
- batch(批量處理語句)
- insert(執(zhí)行INSERT語句)
- insertBatch(批量處理INSERT語句)
- query(SQL中 SELECT 語句)
- update(SQL中 INSERT, UPDATE, 或 DELETE 語句)
比較常用就是query和update
3.1 query
query要用到org.apache.commons.dbutils.handlers包下的實現(xiàn)類,這類提供了ResultSet(結(jié)果集)的轉(zhuǎn)換。
ArrayHandler例子:
這個是放回一個Object[]對象,一個Object[]對應一行數(shù)據(jù),如:{1,“zs”}
public static void testArrayHandler() throws SQLException{//自己寫的DataSourceUtil.getDataSourceWithC3P0(),返回datasource//QueryRunner執(zhí)行工具QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());//返回第一個數(shù)據(jù)(ResultSet轉(zhuǎn)成Object[]),一個Object[]對應表查詢的一行數(shù)據(jù)Object[] student = runner.query("select id,name from student where id>?", new ArrayHandler(),1);System.out.println(student[0]+"\t"+student[1]); }ArrayListHandler例子
這個是放回一個List<Object[]>對象,如:[ {1,“zs”},{2,“李”} ]
public static void testArrayHandler() throws SQLException{//自己寫的DataSourceUtil.getDataSourceWithC3P0(),返回datasource//QueryRunner執(zhí)行工具QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());//ResultSet轉(zhuǎn)成list<Object[]>,查詢多行操作List<Object[]> student = runner.query("select id,name from student", new ArrayHandler());System.out.println(student[0]+"\t"+student[1]); }MapHandler例子
這個是放回一個Map<K,V>對象,{ID=1,name=“ZS”}
public void testMapHandler() throws SQLException{ QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "select * from users";//做出mapMap<String,Object> map = qr.query(sql, new MapHandler());for(Map.Entry<String, Object> me : map.entrySet()){System.out.println(me.getKey() + "=" + me.getValue());} }MapListHandler例子
List<Map<K,V>>,如[{ID=1,name=“ZS”},{ID=2,name=“l(fā)s”}]
public void testMapListHandler() throws SQLException{QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "select * from users";List<Map<String,Object>> list = (List) qr.query(sql, new MapListHandler());for(Map<String,Object> map :list){for(Map.Entry<String, Object> me : map.entrySet())System.out.println(me.getKey() + "=" + me.getValue());} }KeyedHandler例子
Map<Integer,Map<String,Object>>,就是Map里面套map,如:{1={ID=1,name=“ZS”},2={ID=2,name=“l(fā)s”}}
public void testKeyedHandler() throws Exception{QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "select * from users";//MAP里面套mapMap<Integer,Map<String,Object>> map = qr.query(sql, new KeyedHandler("id"));for(Map.Entry<Integer, Map> me : map.entrySet()){int id = me.getKey();Map<String,Object> innermap = me.getValue();for(Map.Entry<String, Object> innerme : innermap.entrySet()){String columnName = innerme.getKey();Object value = innerme.getValue();System.out.println(columnName + "=" + value);} } }3.2 update
update會相對簡單很多,用來執(zhí)行數(shù)據(jù)庫的DML操作,因為不涉及ResultSet,所以直接給SQL語句和變量值就可以了。
增操作
public void Insert() throws SQLException{ QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "insert into student(id,name) value(?,?)"; int count = qr.query(sql, new Object[]{"1","zs"}); }刪操作
public void Delete() throws SQLException{ QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "delete from student where id = ?"; qr.query(sql, 1); }改操作
public void Updata() throws SQLException{ QueryRunner qr = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());String sql = "updata from student set name = ? where id = ?"; qr.query(sql, new Object[]{"1","xiaoming"}); }4.事務手動提交
重復一下QueryRunner的構(gòu)造函數(shù),如果我們需要手動提交事務用無參構(gòu)造。
QueryRunner的無參構(gòu)造函數(shù)和有參構(gòu)造函數(shù):
自動提交事務將每個SQL語句都當成一個事務并進行提交,而有時候我們需要把多個SQL語句當成一個事務來處理,舉個簡單的也是最經(jīng)典的例子:銀行轉(zhuǎn)賬。
? 如:A轉(zhuǎn)錢給B,我們需要完成以下操作,A賬戶減去轉(zhuǎn)賬金額,B賬戶加上轉(zhuǎn)賬金額。這個過程涉及多個SQL操作(兩個修改updata),如果我們使用自動提交(每個SQL一個事務),那么就可能發(fā)生以下情況,A賬戶減去轉(zhuǎn)賬金額,但當B賬戶加上轉(zhuǎn)賬金時額發(fā)生錯誤。出現(xiàn)A減錢了B沒加錢。因為是自動提交,B加錢發(fā)生錯誤也只是B的事務回滾,不涉及A。如果我把這個過程涉及多個SQL操作放到一個事務里面,那么任何一邊發(fā)生錯誤,事務都會回滾,因為事務的原子性(Atomicity):事務中的全部操作在數(shù)據(jù)庫中是不可分割的,要么全部完成,要么全部不執(zhí)行。每次手動提交都會將執(zhí)行SQL語句放到同一個事務里面(運行多個SQL語句,然后提交,那么執(zhí)行的SQL語句都放在一個事務里面)。
其中這里與JDBC的基礎有關,可以看以下代碼例子:
public void QueryRunnertest() throws SQLException{ String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&serverTimezone=UTC";String user = "root" ; String password = "root";//這里隨便創(chuàng)建一個連接Connection conn= DriverManager.getConnection(url,user,password);//設置連接為手動提交conn.setAutoCommit(false);//因為用手動提交,所以需要無參構(gòu)造,有參的會幫你自動提交的QueryRunner qr = new QueryRunner();//插入SQLString sql = "insert into student(id,name) value(?,?)"; try{//只需要把連接傳給函數(shù)就行了int count1 = qr.query(conn,sql, new Object[]{"1","zs"}); int count2 = qr.query(conn,sql, new Object[]{"2","ls"});int count3 = qr.query(conn,sql, new Object[]{"3","ww"});//提交事務conn.commit();}catch(Exception e){//操作回滾conn.rollback(); //一旦其中一個操作出錯都將回滾,使全部操作都不成功 (事務原子性)} }在這里例子里面,先獲取連接,然后設置連接為手動提交,并創(chuàng)建QueryRunner工具類,并使用工具里面的函數(shù)通過傳遞連接,SQL語句,變量。
總結(jié)
以上是生活随笔為你收集整理的dbutils API学习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 想要打造整洁而舒适的电脑桌想要打造整洁而
- 下一篇: 小小海贼王一字斩技能分析