dbutils API学习
dbutils API介紹
1.簡(jiǎn)介
? dbutils就是JDBC操作的類庫(kù),是對(duì)JDBC操作的封裝,提供一些簡(jiǎn)易的API來(lái)操作數(shù)據(jù)庫(kù),提供了數(shù)據(jù)庫(kù)增刪改查等通用的JDBC實(shí)現(xiàn)。
2.org.apache.commons.dbutils.handlers包
? 這個(gè)包里面的類是對(duì)ResultSetHandler接口的實(shí)現(xiàn)類,主要是用來(lái)處理ResultSet(結(jié)果集)的轉(zhuǎn)換,將結(jié)果集轉(zhuǎn)成Object[],List< Object[] >,List< T >,Map< K,V >等的數(shù)據(jù)結(jié)構(gòu)。這些實(shí)現(xiàn)類會(huì)在做數(shù)據(jù)庫(kù)查詢操作時(shí)使用,主要有以下類:
- AbstractListHandler 將ResultSet轉(zhuǎn)為L(zhǎng)ist的抽象類
- ArrayHandler 將ResultSet轉(zhuǎn)為一個(gè)Object[]的ResultSetHandler實(shí)現(xiàn)類
- ArrayListHandler 將ResultSet轉(zhuǎn)換為L(zhǎng)ist< Object[] >的ResultSetHandler實(shí)現(xiàn)類
- BeanHandler 將ResultSet行轉(zhuǎn)換為一個(gè)JavaBean的ResultSetHandler實(shí)現(xiàn)類
- BeanListHandler 將ResultSet轉(zhuǎn)換為L(zhǎng)ist< T >的ResultSetHandler實(shí)現(xiàn)類
- ColumnListHandler 將ResultSet的一個(gè)列轉(zhuǎn)換為L(zhǎng)ist< Object >的ResultSetHandler實(shí)現(xiàn)類
- KeyedHandler 將ResultSet轉(zhuǎn)換為Map< K,V>的ResultSetHandler實(shí)現(xiàn)類
- MapHandler 將ResultSet的首行轉(zhuǎn)換為一個(gè)Map的ResultSetHandler實(shí)現(xiàn)類
- MapListHandler 將ResultSet轉(zhuǎn)換為L(zhǎng)ist< K,V>的ResultSetHandler實(shí)現(xiàn)類
- ScalarHandler 將ResultSet的一個(gè)列到一個(gè)對(duì)象。
3.org.apache.commons.dbutils.QueryRunner
? 它與ResultSetHandler組合在一起使用可以完成大部分的數(shù)據(jù)庫(kù)操作,是用來(lái)執(zhí)行SQL語(yǔ)句的工具類。主要的方法如下。
QueryRunner的無(wú)參構(gòu)造函數(shù)和有參構(gòu)造函數(shù):
QueryRunner中一共有6種方法:
- execute(執(zhí)行SQL語(yǔ)句)
- batch(批量處理語(yǔ)句)
- insert(執(zhí)行INSERT語(yǔ)句)
- insertBatch(批量處理INSERT語(yǔ)句)
- query(SQL中 SELECT 語(yǔ)句)
- update(SQL中 INSERT, UPDATE, 或 DELETE 語(yǔ)句)
比較常用就是query和update
3.1 query
query要用到org.apache.commons.dbutils.handlers包下的實(shí)現(xiàn)類,這類提供了ResultSet(結(jié)果集)的轉(zhuǎn)換。
ArrayHandler例子:
這個(gè)是放回一個(gè)Object[]對(duì)象,一個(gè)Object[]對(duì)應(yīng)一行數(shù)據(jù),如:{1,“zs”}
public static void testArrayHandler() throws SQLException{//自己寫的DataSourceUtil.getDataSourceWithC3P0(),返回datasource//QueryRunner執(zhí)行工具QueryRunner runner = new QueryRunner(DataSourceUtil.getDataSourceWithC3P0());//返回第一個(gè)數(shù)據(jù)(ResultSet轉(zhuǎn)成Object[]),一個(gè)Object[]對(duì)應(yīng)表查詢的一行數(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例子
這個(gè)是放回一個(gè)List<Object[]>對(duì)象,如:[ {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例子
這個(gè)是放回一個(gè)Map<K,V>對(duì)象,{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會(huì)相對(duì)簡(jiǎn)單很多,用來(lái)執(zhí)行數(shù)據(jù)庫(kù)的DML操作,因?yàn)椴簧婕癛esultSet,所以直接給SQL語(yǔ)句和變量值就可以了。
增操作
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.事務(wù)手動(dòng)提交
重復(fù)一下QueryRunner的構(gòu)造函數(shù),如果我們需要手動(dòng)提交事務(wù)用無(wú)參構(gòu)造。
QueryRunner的無(wú)參構(gòu)造函數(shù)和有參構(gòu)造函數(shù):
自動(dòng)提交事務(wù)將每個(gè)SQL語(yǔ)句都當(dāng)成一個(gè)事務(wù)并進(jìn)行提交,而有時(shí)候我們需要把多個(gè)SQL語(yǔ)句當(dāng)成一個(gè)事務(wù)來(lái)處理,舉個(gè)簡(jiǎn)單的也是最經(jīng)典的例子:銀行轉(zhuǎn)賬。
? 如:A轉(zhuǎn)錢給B,我們需要完成以下操作,A賬戶減去轉(zhuǎn)賬金額,B賬戶加上轉(zhuǎn)賬金額。這個(gè)過(guò)程涉及多個(gè)SQL操作(兩個(gè)修改updata),如果我們使用自動(dòng)提交(每個(gè)SQL一個(gè)事務(wù)),那么就可能發(fā)生以下情況,A賬戶減去轉(zhuǎn)賬金額,但當(dāng)B賬戶加上轉(zhuǎn)賬金時(shí)額發(fā)生錯(cuò)誤。出現(xiàn)A減錢了B沒加錢。因?yàn)槭亲詣?dòng)提交,B加錢發(fā)生錯(cuò)誤也只是B的事務(wù)回滾,不涉及A。如果我把這個(gè)過(guò)程涉及多個(gè)SQL操作放到一個(gè)事務(wù)里面,那么任何一邊發(fā)生錯(cuò)誤,事務(wù)都會(huì)回滾,因?yàn)槭聞?wù)的原子性(Atomicity):事務(wù)中的全部操作在數(shù)據(jù)庫(kù)中是不可分割的,要么全部完成,要么全部不執(zhí)行。每次手動(dòng)提交都會(huì)將執(zhí)行SQL語(yǔ)句放到同一個(gè)事務(wù)里面(運(yùn)行多個(gè)SQL語(yǔ)句,然后提交,那么執(zhí)行的SQL語(yǔ)句都放在一個(gè)事務(wù)里面)。
其中這里與JDBC的基礎(chǔ)有關(guān),可以看以下代碼例子:
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)建一個(gè)連接Connection conn= DriverManager.getConnection(url,user,password);//設(shè)置連接為手動(dòng)提交conn.setAutoCommit(false);//因?yàn)橛檬謩?dòng)提交,所以需要無(wú)參構(gòu)造,有參的會(huì)幫你自動(dòng)提交的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"});//提交事務(wù)conn.commit();}catch(Exception e){//操作回滾conn.rollback(); //一旦其中一個(gè)操作出錯(cuò)都將回滾,使全部操作都不成功 (事務(wù)原子性)} }在這里例子里面,先獲取連接,然后設(shè)置連接為手動(dòng)提交,并創(chuàng)建QueryRunner工具類,并使用工具里面的函數(shù)通過(guò)傳遞連接,SQL語(yǔ)句,變量。
總結(jié)
以上是生活随笔為你收集整理的dbutils API学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 想要打造整洁而舒适的电脑桌想要打造整洁而
- 下一篇: tld自定义标签