# JAVA學習日誌——DBUtils工具類和鏈接池 #
在進行數據庫的操做時,若是隻使用JDBC進行開發,每每會形成冗餘代碼過多的現象,爲了簡化JDBC的開發,咱們會用到一些工具包。DBUtils就是JDBC的簡化開發工具包。
一:DBUtils的概述
DBUtils是Apache組織提供的一個開源的JDBC工具類庫。其內部封裝了JDBC的代碼,從而簡化了JDBC的操做。
DBUtils有三個核心功能:
1.QueryRunner中提供對sql語句操做的API。
update(Connection conn, String sql, Object... params) ,用來完成表數據的增長、刪除、更新操做
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用來完成表數據的查詢操做
2.ResultSetHandler接口,用於定義select操做後,如何封裝結果集。
3.DbUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法。
二:QueryRunner類的update方法
update(Connection conn, String sql, Object... params) ,用來完成表數據的增長、刪除、更新操做
使用QueryRunner類,實現對數據表的insert,delete和update
調用QueryRunner類的方法 update (Connection con,String sql,Object...param)
* Object...param 可變參數,Object類型,SQL語句會出現?佔位符
* 數據庫鏈接對象,自定義的工具類傳遞
1.QueryRunner類實現insert添加數據java
例如:mysql
package com.zuikc.DBUtils; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; public class QueryRunnerDemo { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args)throws SQLException { insert(); } // 定義方法,使用QueryRunner類的方法update向數據表中,添加數據 public static void insert()throws SQLException{ //建立QueryRunner類對象 QueryRunner qr = new QueryRunner(); String sql = "INSERT INTO sort (sname,sprice,sdesc)VALUES(?,?,?)"; //將三個?佔位符的實際參數寫在數組中 Object[] params = {"學習用品",290,"日本原裝進口"}; //調用QueryRunner類的方法update執行SQL語句 int row = qr.update(con, sql, params); System.out.println(row); DbUtils.closeQuietly(con); } }
2.QueryRunner類實現update修改數據
例如:sql
package com.zuikc.DBUtils; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; public class QueryRunnerDemo { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args)throws SQLException { update(); } //定義方法,使用QueryRunner類的方法update將數據表的數據修改 public static void update()throws SQLException{ //建立QueryRunner類對象 QueryRunner qr = new QueryRunner(); //寫修改數據的SQL語句 String sql = "UPDATE sort SET sname=?,sprice=?,sdesc=? WHERE sid=?"; //定義Object數組,存儲佔位符?中的參數 Object[] params = {"鋼琴",9999.9,"學習鋼琴",3}; //調用QueryRunner方法update int row = qr.update(con, sql, params); System.out.println(row); DbUtils.closeQuietly(con); } }
3.QueryRunner類實現delete刪除數據
例如:數據庫
package com.zuikc.DBUtils; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; public class QueryRunnerDemo { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args)throws SQLException { delete(); } //定義方法,使用QueryRunner類的方法delete將數據表的數據刪除 public static void delete()throws SQLException{ //建立QueryRunner類對象 QueryRunner qr = new QueryRunner(); //寫刪除的SQL語句 String sql = "DELETE FROM sort WHERE sid=?"; //調用QueryRunner方法update int row = qr.update(con, sql, 5); System.out.println(row); DbUtils.closeQuietly(con); } }
三:QueryRunner類的方法query
QueryRunner類方法query(Connection con,String sql,ResultSetHandler rs, Object..params),實現數據查詢操做。
ResultSetHandler rs 是結果集的處理方式,傳遞ResultSetHandler接口實現類
在這個查詢中,對象數組中的每一個元素值被用來做爲查詢語句的置換參數。該方法會自行處理 PreparedStatement 和 ResultSet 的建立和關閉。
四:ResultSetHandler結果集處理類
1.ArrayHandler:它是結果集中的第一條記錄封裝到一個Object[]數組中,數組中的每個元素就是這條記錄中的每個字段的值。
例如:apache
package com.zuikc.DBUtils; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.ArrayHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { arrayHandler(); } public static void arrayHandler() throws SQLException{ //建立QueryRunner對象 QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用方法query的查詢方法,傳遞參數對象,SQL語句,結果集處理方式的實現類 Object[] result = qr.query(con, sql, new ArrayHandler()); //對數組進行遍歷,獲得結果集 for (Object obj : result) { System.out.println(obj); } } }
2.ArrayListHandler:是將結果集中的每一條記錄都封裝到一個Object[]數組中,將這些數組在封裝到List集合中。
例如:數組
import java.sql.Connection; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { arrayListHandler(); } public static void arrayListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用query方法,結果集處理的參數傳遞給實現類ArrayListHandler //方法返回值每行是一個對象組,存儲到List集合 List<Object[]> result = qr.query(con, sql, new ArrayListHandler()); for (Object[] objs : result) {//遍歷集合獲得數組 for (Object obj : objs) {//遍歷數組獲得數據庫的記錄 System.out.print(obj+" "); } System.out.println(); } } }
3.BeanHandler:它是將結果集中第一條記錄封裝到一個指定的javaBean中。
注:JavaBean就是一個類,在開發中經常使用於封裝數據。具備如下幾個特性
1)須要實現接口:java.io.Serializable,而一般實現接口這步驟省略了,不會影響程序的進程。
2)提供私有字段:private 類型 字段名;
3)提供getter/setter方法:
4)提供無參構造
例如:dom
package com.zuikc.domain; public class Sort { private int sid; private String sname; private double sprice; private String sdesc; public Sort() { super(); } public Sort(int sid, String sname, double sprice, String sdesc) { super(); this.sid = sid; this.sname = sname; this.sprice = sprice; this.sdesc = sdesc; } public int getSid() { return sid; } public void setSid(int sid) { this.sid = sid; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public double getSprice() { return sprice; } public void setSprice(double sprice) { this.sprice = sprice; } public String getSdesc() { return sdesc; } public void setSdesc(String sdesc) { this.sdesc = sdesc; } @Override public String toString() { return"Sort [sid=" + sid+", sname=" +sname +", sprice=" + sprice +", sdesc=" + sdesc +"]"; } }
結果集處理案例:ide
import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { beanHandler(); } public static void beanHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用方法,傳遞結果集實現類BeanHandler //BeanHandler(Class<T> type) Sort s = qr.query(con, sql, new BeanHandler<Sort>(Sort.class)); System.out.println(s); } }
4.BeanListHandler:它是將結果集中每一條記錄封裝到指定的javaBean中,將這些javaBean在封裝到List集合中。
例如:工具
import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.BeanListHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { beanListHandler(); } public static void beanListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用方法,傳遞結果集處理實現類BeanListHandler List<Sort> list = qr.query(con, sql, new BeanListHandler<Sort>(Sort.class)); for (Sort s : list) { System.out.println(s); } } }
5.ColumnListHandler:它是將結果集中指定的列的字段值,封裝到一個List集合中。
例如:性能
import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.ColumnListHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { columnListHandler(); } public static void columnListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用方法query,傳遞結果集實現類ColumnListHandler //實現類構造方法中使用字符串的列名 List<Object> list = qr.query(con, sql, new ColumnListHandler<Object>("sname")); for (Object obj : list) { System.out.println(obj); } } }
6.ScalarHandler:它是用於單數據。返回值數據類型是long型。
例如:
import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.ScalarHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { scalarHandler(); } public static void scalarHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT COUNT(*) FROM sort"; //調用方法,傳遞結果集處理實現類ScalarHandler Long count = qr.query(con, sql, new ScalarHandler<Long>()); System.out.println(count); } }
7.MapHandler:它是將結果集第一行封裝到Map集合中,Key是列名, Value是該列數據。
例如:
import java.util.Map; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.MapHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { mapHandler(); } public static void mapHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用方法,傳遞結果集實現類MapHandler //返回值:Map集合 Map<String, Object> map = qr.query(con, sql, new MapHandler()); for(String key : map.keySet()){//獲取鍵 System.out.println(key+"..."+map.get(key)); } } }
8.MapListHandlerr:它是將結果集第一行封裝到Map集合中,Key是列名, Value是該列數據,Map集合存儲到List集合中。
例如:
import java.util.Map; import java.util.List; import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbutils.QueryRunner; import com.zuikc.JDBCUtils.JDBCUtilsConfig; import org.apache.commons.dbutils.handlers.MapListHandler; public class QueryRunnerDemo01 { private static Connection con = JDBCUtilsConfig.getConnection(); public static void main(String[] args) throws SQLException { mapListHandler(); } public static void mapListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(); String sql = "SELECT * FROM sort"; //調用query方法,傳遞結果集實現類MapListHandler //返回值List集合,存儲的是Map集合 List<Map<String,Object>> list = qr.query(con, sql, new MapListHandler()); //遍歷集合 for (Map<String, Object> map : list) { for(String key : map.keySet()){ System.out.print(key+"..."+map.get(key)); } System.out.println(); } } }
五:鏈接池
1.概念:
用池來管理Connection,這樣能夠重複使用Connection。有了池,因此咱們就不用本身來建立Connection,而是經過池來獲取Connection對象。當使用完Connection後,調用Connection的close()方法也不會真的關閉Connection,而是把Connection「歸還」給連接池。這樣池就能夠再利用這個Connection對象了。
2.規範:
Java爲數據庫鏈接池提供了公共的接口:javax.sql.DataSource,各個廠商須要讓本身的鏈接池實現這個接口。
常見的鏈接池:DBCP、C3P0
3.DBCP鏈接池的使用
3.1 導入jar包,jar包有:connector包,用於數據庫驅動;dbutils包,提供QueryRunner類方便進行增刪改查操做;dbcp包;pool包,提供高效的數據庫鏈接池技術。導完包後還須要建立Build Path。
3.2 編寫工具類
DataSource : 它是java中提供的鏈接池,做爲 DriverManager 工具的替代項。在DBCP包中提供了DataSource接口的實現類,咱們要用的具體的鏈接池 BasicDataSource類
例如:
package com.zuikc.DataSource; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import com.zuikc.JDBCUtils.JDBCUtilsConfig; /*鏈接池jar包中,定義好一個類 BasicDataSource *實現類數據源的規範接口 javax.sql.DataSource */ public class DataSoruceDemo { public static void main(String[] args) { //建立DataSource接口的實現類對象 //實現類, org.apache.commons.dbcp BasicDataSource dataSource = new BasicDataSource(); //鏈接數據庫的4個最基本信息,經過對象方法setxxx()設置進來 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mybase"); dataSource.setUsername("root"); dataSource.setPassword("root"); try{ //調用對象方法getConnection獲取數據庫的鏈接 Connection con = dataSource.getConnection(); System.out.println(con); }catch(SQLException ex){ throw new RuntimeException("數據庫鏈接失敗"); } } }
3.3 BasicDataSource類的常見配置
a.必須項
driverClassName 數據庫驅動名稱
url 數據庫的地址
username 用戶名
password 密碼
b.基本項(擴展)
maxActive 最大鏈接數量
minIdle 最小空閒鏈接
maxIdle 最大空閒鏈接
initialSize 初始化鏈接
3.4 實現數據庫鏈接池工具類
例如:
package com.zuikc.DataSource; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; public class JDBCUtils{ //建立出BasicDataSource類對象 private static BasicDataSource datasource = new BasicDataSource(); //靜態代碼塊,BasicDataSource對象中的配置 static{ //數據庫鏈接信息,必須的 datasource.setDriverClassName("com.mysql.jdbc.Driver"); datasource.setUrl("jdbc:mysql://localhost:3306/mybase"); datasource.setUsername("root"); datasource.setPassword("root"); //對象鏈接池中的鏈接數量配置,可選的 datasource.setInitialSize(8);//初始化的鏈接數 datasource.setMaxActive(6);//最大鏈接數量 datasource.setMaxIdle(5);//最大空閒數 datasource.setMinIdle(1);//最小空閒 } //定義靜態方法,返回BasicDataSource類的對象 public static DataSource getDataSource(){ return datasource; } }
3.5 測試工具類
package com.zuikc.DataSource; /* * 測試寫好的工具類, * 提供的是一個DataSource接口的數據源 * QueryRunner類構造方法,接收DataSource接口的實現類 * 以後調用方法update,query,這時不須要傳遞他們Connection鏈接對象 */ import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayListHandler; import cn.zuikc.jdbcutils.JDBCUtils; public class QueryRunnerDemo02{ public static void main(String[] args) { select(); } //定義2個方法,實現數據表的添加,數據表查詢 //QueryRunner類對象,寫在類成員位置 private static QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); //數據表查詢 public static void select(){ String sql = "SELECT * FROM sort"; try{ List<Object[]> list = qr.query(sql, new ArrayListHandler()); for(Object[] objs : list){ for(Object obj : objs){ System.out.print(obj+"\t"); }catch(SQLException ex){ throw new RuntimeException("數據查詢失敗"); } } //數據表添加數據 public static void insert(){ String sql = "INSERT INTO sort (sname,sprice,sdesc)VALUES(?,?,?)"; Object[] params = {"西瓜",30,"轉基因西瓜"}; try{ int row = qr.update(sql, params); System.out.println(row); }catch(SQLException ex){ throw new RuntimeException("數據添加失敗"); } } }
六:總結 DBUtils工具簡化了JDBC的操做,而鏈接池能解決「得到鏈接」或「釋放資源」是這很是消耗系統資源過程的性能問題,其自身維護了多個Connection鏈接對象。以上只介紹了DBCP鏈接池,而C3P0鏈接池在之後介紹。