一: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();
}
}