# 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链接池在之后介绍。