第二部分 DbUtils工具包詳解

一:Dbutils是什么?
Dbutils:主要是封裝了JDBC的代碼,簡(jiǎn)化dao層的操作翰绊。
作用:幫助java程序員,開(kāi)發(fā)Dao層代碼的簡(jiǎn)單框架旁壮。
類似于前面的萬(wàn)能查找搜索等工具類

二:為什么需要Dbutils 监嗜?
在使用Dbutils 之前,我們Dao層使用的技術(shù)是JDBC抡谐,那么分析一下JDBC的弊端:
(1)數(shù)據(jù)庫(kù)鏈接對(duì)象裁奇、sql語(yǔ)句操作對(duì)象,封裝結(jié)果集對(duì)象麦撵,這三大對(duì)象會(huì)重復(fù)定義
(2)封裝數(shù)據(jù)的代碼重復(fù)刽肠,而且操作復(fù)雜,代碼量大
(3)釋放資源的代碼重復(fù)

三:Dbutils三個(gè)核心類介紹:
1:DbUtils:連接數(shù)據(jù)庫(kù)對(duì)象----jdbc輔助方法的集合類免胃,線程安全
構(gòu)造方法:DbUtils()
作用:控制連接音五,控制書(shū)屋,控制驅(qū)動(dòng)加載額一個(gè)類羔沙。

 2:QueryRunner:SQL語(yǔ)句的操作對(duì)象躺涝,可以設(shè)置查詢結(jié)果集的封裝策略,線程安全扼雏。
      構(gòu)造方法:
      (1)QueryRunner():創(chuàng)建一個(gè)與數(shù)據(jù)庫(kù)無(wú)關(guān)的QueryRunner對(duì)象坚嗜,后期再操作數(shù)據(jù)庫(kù)的會(huì)后夯膀,需要手動(dòng)給一個(gè)Connection對(duì)象,它可以手動(dòng)控制事務(wù)苍蔬。
                Connection.setAutoCommit(false);     設(shè)置手動(dòng)管理事務(wù)
                Connection.commit();     提交事務(wù)

      (2)QueryRunner(DataSource ds):創(chuàng)建一個(gè)與數(shù)據(jù)庫(kù)關(guān)聯(lián)的queryRunner對(duì)象棍郎,后期再操作數(shù)據(jù)庫(kù)的時(shí)候,不需要Connection對(duì)象银室,自動(dòng)管理事務(wù)涂佃。
                DataSource:數(shù)據(jù)庫(kù)連接池對(duì)象。

      構(gòu)造函數(shù)與增刪改查方法的組合:
 QueryRunner()
       update(Connection conn, String sql, Object... params)
       query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)

 QueryRunner(DataSource ds)     
       update(String sql, Object... params)
       query(String sql, ResultSetHandler<T> rsh, Object... params)

(3)ResultSetHandle:封裝數(shù)據(jù)的策略對(duì)象------將封裝結(jié)果集中的數(shù)據(jù)蜈敢,轉(zhuǎn)換到另一個(gè)對(duì)象
策略:封裝數(shù)據(jù)到對(duì)象的方式(示例:將數(shù)據(jù)庫(kù)保存在User辜荠、保存到數(shù)組、保存到集合)
方法介紹:handle(ResultSet rs)

四:Dbutils快速入門(mén)
使用Dbutils注意事項(xiàng):
(1)需要導(dǎo)入的jar包:①M(fèi)ySql驅(qū)動(dòng) ②c3p0包 ③DbUtils包
(2)添加c3p0配置文件
(3)可以自行添加一個(gè)JDBCUtils工具類:用來(lái)獲取c3p0連接池對(duì)象(有 獲取數(shù)據(jù)源和獲取連接的方法)

代碼演示:
注意:以下代碼演示QueryRunner(JDBCUtils.getDataSource())傳入數(shù)據(jù)源的構(gòu)造函數(shù)來(lái)獲取連接抓狭,這樣不用在每次執(zhí)行sql的時(shí)候傳入連接伯病,效率高

1.增刪改類似 update(String sql, Object... params)

@Test
 
public void test2(){
 
//第一步:創(chuàng)建queryRunner對(duì)象,用來(lái)操作sql語(yǔ)句
 
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
 
//第二步:創(chuàng)建sql語(yǔ)句
 
String sql = "update user set name = ? where id = ?";
 
//第三步:執(zhí)行sql語(yǔ)句,params:是sql語(yǔ)句的參數(shù)
 
//注意否过,給sql語(yǔ)句設(shè)置參數(shù)的時(shí)候午笛,按照user表中字段的順序
 
try {
 
int update = qr.update(sql, 參數(shù)1,參數(shù)2);
 
System.out.println(update);
 
} catch (SQLException e) {
 
e.printStackTrace();
 
}
 
}

2.查
QueryRunner的query方法和ResultSetHandler接口的使用

模擬一個(gè)結(jié)果集處理類

public class MyHandler  {   
//查詢會(huì)調(diào)用結(jié)果集處理方法,就將結(jié)果集存到了list中苗桂,實(shí)際用的反射药磺!
 
   public List<User> handle(ResultSet rs) throws SQLException {
      // 封裝數(shù)據(jù),數(shù)據(jù)從 Resultset 中獲取
      List<User> list = new ArrayList<User>();
       while(rs.next()){
         User u = new User();
         u.setId(rs.getInt( "id"));
         u.setName(rs.getString( "name"));
         u.setPwd(rs.getString( "pwd"));
 
         list.add(u);
      }
       return list;
   }
 
}

由此可知因?yàn)榻Y(jié)果集可能是對(duì)象煤伟,集合等多種類型癌佩,DButils又將結(jié)果集拿出來(lái)進(jìn)行了單獨(dú)的編寫(xiě)。

2.query測(cè)試

@Test
 
public void test4(){
 
//第一步:創(chuàng)建queryRunner對(duì)象便锨,用來(lái)操作sql語(yǔ)句
 
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
 
//第二步:創(chuàng)建sql語(yǔ)句
 
String sql = "select * from user";
 
//第三步:執(zhí)行sql語(yǔ)句,params:是sql語(yǔ)句的參數(shù)
 
//注意围辙,給sql語(yǔ)句設(shè)置參數(shù)的時(shí)候,按照user表中字段的順序
 
try {
 
List<User> list = qr.query(sql, new MyHandler());
 
System.out.println(list);
 
} catch (SQLException e) {
 
e.printStackTrace();
 
}
 
}

注:其實(shí)這個(gè)類似我們自己寫(xiě)的萬(wàn)能查詢工具類放案,只不過(guò)結(jié)果集種類太多姚建,它將結(jié)果集的處理又封裝到了一個(gè)方法之中,調(diào)用查詢方法的時(shí)候吱殉,傳入處理結(jié)果集的方法掸冤,就可以將查詢到的結(jié)果存到結(jié)果集里然后進(jìn)行處理了。

DbUtils給我們提供了10個(gè)ResultSetHandler實(shí)現(xiàn)類考婴,分別是:
①ArrayHandler: 將查詢結(jié)果的第一行數(shù)據(jù)贩虾,保存到Object數(shù)組中
②ArrayListHandler 將查詢的結(jié)果催烘,每一行先封裝到Object數(shù)組中沥阱,然后將數(shù)據(jù)存入List集合
③BeanHandler 將查詢結(jié)果的一行數(shù)據(jù),封裝到user對(duì)象
④BeanListHandler 將查詢結(jié)果的每一行封裝到user對(duì)象伊群,然后再存入List集合
⑤ColumnListHandler 查詢指定字段所有的值封裝到List集合中
⑥MapHandler 將查詢結(jié)果的第一行數(shù)據(jù)封裝到map結(jié)合(key==列名考杉,value==列值)
⑦M(jìn)apListHandler 將查詢結(jié)果的每一行封裝到map集合(key==列名策精,value==列值),再將map集合存入List集合
⑧BeanMapHandler 將查詢結(jié)果的每一行數(shù)據(jù)崇棠,封裝到User對(duì)象咽袜,再存入mao集合中(key==列名,value==列值)
⑨KeyedHandler 將查詢的結(jié)果的每一行數(shù)據(jù)枕稀,封裝到map1(key==列名询刹,value==列值 ),然后將map1集合(有多個(gè))存入map2集合(只有一個(gè))
⑩ScalarHandler 查詢指定對(duì)象的指定字段的值或者是查詢封裝類似count萎坷、avg凹联、max、min哆档、sum......函數(shù)的執(zhí)行結(jié)果

以上10個(gè)ResultSetHandler實(shí)現(xiàn)類蔽挠,常用的是BeanHandler、BeanListHandler和ScalarHandler

1.//需求:測(cè)試查詢單個(gè)對(duì)象的數(shù)據(jù) BeanHandler

 
//BeanHandler:將查詢結(jié)果的第一行數(shù)據(jù)瓜浸,封裝到user對(duì)象
 
@Test
 
public void test7(){
 
//第一步:創(chuàng)建queryRunner對(duì)象澳淑,用來(lái)操作sql語(yǔ)句
 
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
 
//第二步:創(chuàng)建sql語(yǔ)句
 
String sql = "select * from user";
 
//第三步:執(zhí)行sql語(yǔ)句,params:是sql語(yǔ)句的參數(shù)
 
//注意,給sql語(yǔ)句設(shè)置參數(shù)的時(shí)候插佛,按照user表中字段的順序
 
try {
 
User user = qr.query(sql, new BeanHandler<User>(User.class)); 
//利用反射明確返回對(duì)象的類型
 
System.out.println(user);
 
} catch (SQLException e) {
 
e.printStackTrace();
 
}
 
}

2.查詢多個(gè)對(duì)象的數(shù)據(jù) BeanListHandler

//需求:測(cè)試BeanListHandler策略
 
//BeanListHandler:將查詢結(jié)果的每一行封裝到user對(duì)象杠巡,然后,再存入list集合
 
@Test
 
public void test8(){
 
//第一步:創(chuàng)建queryRunner對(duì)象雇寇,用來(lái)操作sql語(yǔ)句
 
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
 
//第二步:創(chuàng)建sql語(yǔ)句
 
String sql = "select * from user";
 
//第三步:執(zhí)行sql語(yǔ)句,params:是sql語(yǔ)句的參數(shù)
 
//注意忽孽,給sql語(yǔ)句設(shè)置參數(shù)的時(shí)候,按照user表中字段的順序
 
try {
 
List<User> list = qr.query(sql, new BeanListHandler<User>(User.class));
 
System.out.println(list);
 
} catch (SQLException e) {
 
e.printStackTrace();
 
}
 
}

3.查詢單個(gè)對(duì)象的單個(gè)字段值谢床,或者聚合函數(shù)的值 ScalarHandler

//需求:測(cè)試ScalarHandler策略
 
//ScalarHandler:封裝類似count兄一、avg、max识腿、min出革、sum。渡讼。骂束。。函數(shù)的執(zhí)行結(jié)果
 
@Test
 
public void test14(){
 
//第一步:創(chuàng)建queryRunner對(duì)象成箫,用來(lái)操作sql語(yǔ)句
 
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
 
//第二步:創(chuàng)建sql語(yǔ)句
 
String sql = "select count(*) from user";
 
//第三步:執(zhí)行sql語(yǔ)句,params:是sql語(yǔ)句的參數(shù)
 
//注意展箱,給sql語(yǔ)句設(shè)置參數(shù)的時(shí)候,按照user表中字段的順序
 
try {
 
Object object = qr.query(sql, new ScalarHandler());
 
System.out.println(object);
 
} catch (SQLException e) {
 
e.printStackTrace();
 
}
 
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蹬昌,一起剝皮案震驚了整個(gè)濱河市混驰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖栖榨,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昆汹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡婴栽,警方通過(guò)查閱死者的電腦和手機(jī)满粗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)愚争,“玉大人映皆,你說(shuō)我怎么就攤上這事『渲Γ” “怎么了劫扒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)狸膏。 經(jīng)常有香客問(wèn)我沟饥,道長(zhǎng),這世上最難降的妖魔是什么湾戳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任贤旷,我火速辦了婚禮,結(jié)果婚禮上砾脑,老公的妹妹穿的比我還像新娘幼驶。我一直安慰自己,他們只是感情好韧衣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布盅藻。 她就那樣靜靜地躺著,像睡著了一般畅铭。 火紅的嫁衣襯著肌膚如雪氏淑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天硕噩,我揣著相機(jī)與錄音假残,去河邊找鬼。 笑死炉擅,一個(gè)胖子當(dāng)著我的面吹牛辉懒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播谍失,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼眶俩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了快鱼?” 一聲冷哼從身側(cè)響起颠印,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纲岭,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后嗽仪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柒莉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年闻坚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兢孝。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窿凤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出跨蟹,到底是詐尸還是另有隱情雳殊,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布窗轩,位于F島的核電站夯秃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痢艺。R本人自食惡果不足惜仓洼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堤舒。 院中可真熱鬧色建,春花似錦、人聲如沸舌缤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)国撵。三九已至陵吸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間介牙,已是汗流浹背走越。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耻瑟,地道東北人旨指。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像喳整,于是被迫代替她去往敵國(guó)和親谆构。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容