DBUtils的使用

    科技2025-12-27  8

    DbUtils:是对JDBC进行了相对简单的封装, 主要就是能自动封装查询结果集, 需要在代码中写 sql 语句。而JDBC:是原生访问数据库的方式, 其它三个都是对 JDBC 不同程度的封装 访问数据库比较麻烦, 代码重复度极高。 一、commons-dbutils简介    commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。 commons-dbutilsAPI介绍: org.apache.commons.dbutils.QueryRunner org.apache.commons.dbutils.ResultSetHandler 工具类 org.apache.commons.dbutils.DbUtils 二、QueryRunner类使用讲解   该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。   QueryRunner类提供了两个构造方法: ①默认的构造方法 ②需要一个 javax.sql.DataSource 来作参数的构造方法。 2.1、QueryRunner类的主要方法   public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法自行处理 PreparedStatement 和 ResultSet 的创建和关闭。   public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException: 几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource) 或使用的setDataSource 方法中重新获得 Connection。   public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException : 执行一个不需要置换参数的查询操作。   public int update(Connection conn, String sql, Object[] params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。   public int update(Connection conn, String sql) throws SQLException:用来执行一个不需要置换参数的更新操作。 2.2、使用QueryRunner类实现CRUD package wkcto.com.test;

    import java.util.Date; import java.util.List; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.sql.SQLException; import javax.sql.rowset.serial.SerialClob; import wkcto.com.domain.User; import wkcto.com.util.JdbcUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test;

    /**

    @ClassName: DBUtilsCRUDTest@Description:使用dbutils框架的QueryRunner类完成CRUD,以及批处理

    */ public class QueryRunnerCRUDTest {

    /* *---------测试表Start-------------------- create table users( id int primary key auto_increment, name varchar(40), password varchar(40), email varchar(60), birthday date ); *---------测试表end-------------------- */ @Test public void add() throws SQLException { //将数据源传递给QueryRunner,QueryRunner内部通过数据源获取数据库连接 QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into users(name,password,email,birthday) values(?,?,?,?)"; Object params[] = {"巢湖学院官网","123", "www.chu.edu.cn", new Date()}; //Object params[] = {"巢湖学院","123", "www.chu.edu.cn", "1977"}; qr.update(sql, params); } @Test public void delete() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "delete from users where id=?"; qr.update(sql, 1); } @Test public void update() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "update users set name=? where id=?"; Object params[] = { "ccc", 5}; qr.update(sql, params); } @Test public void find() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users where id=?"; Object params[] = {2}; User user = (User) qr.query(sql, params, new BeanHandler(User.class)); System.out.println(user.getBirthday()); } @Test public void getAll() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; List list = (List) qr.query(sql, new BeanListHandler(User.class)); System.out.println(list.size()); } /** * @Method: testBatch * @Description:批处理 * * @throws SQLException */ @Test public void testBatch() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into users(name,password,email,birthday) values(?,?,?,?)"; Object params[][] = new Object[10][]; for (int i = 0; i < 10; i++) { params[i] = new Object[] { "abc" + i, "123", "www.chu.edu.cn", new Date() }; } qr.batch(sql, params); } //用dbutils完成大数据(不建议用) /*************************************************************************** create table testclob ( id int primary key auto_increment, resume text ); **************************************************************************/ @Test public void testclob() throws SQLException, IOException{ QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into testclob(resume) values(?)"; //clob //这种方式获取的路径,其中的空格会被使用“%20”代替 String path = QueryRunnerCRUDTest.class.getClassLoader().getResource("data.txt").getPath(); //将“%20”替换回空格 path = path.replaceAll("%20", " "); FileReader in = new FileReader(path); char[] buffer = new char[(int) new File(path).length()]; in.read(buffer); SerialClob clob = new SerialClob(buffer); Object params[] = {clob}; runner.update(sql, params); }

    } 三、ResultSetHandler接口使用讲解   该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。   ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)

    3.1、ResultSetHandler接口的实现类 ArrayHandler:把结果集中的第一行数据转成对象数组。 ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。 BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。 BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 ColumnListHandler:将结果集中某一列的数据存放到List中。 KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。 MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。 MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List 3.2、测试dbutils各种类型的处理器 package wkcto.com.test;

    import java.sql.SQLException; import java.util.Arrays; import java.util.List; import java.util.Map; import wkcto.com.util.JdbcUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test;

    /**

    @ClassName: ResultSetHandlerTest@Description:测试dbutils各种类型的处理器

    */ public class ResultSetHandlerTest {

    @Test public void testArrayHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; Object result[] = (Object[]) qr.query(sql, new ArrayHandler()); System.out.println(Arrays.asList(result)); //list ---> toString() } @Test public void testArrayListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; List list = (List) qr.query(sql, new ArrayListHandler()); for(Object[] o : list){ System.out.println(Arrays.asList(o)); } } @Test public void testColumnListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; List list = (List) qr.query(sql, new ColumnListHandler("id")); System.out.println(list); } @Test public void testKeyedHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; Map map = (Map) qr.query(sql, new KeyedHandler("id")); for(Map.Entry me : map.entrySet()){ int id = me.getKey(); Map innermap = me.getValue(); for(Map.Entry innerme : innermap.entrySet()){ String columnName = innerme.getKey(); Object value = innerme.getValue(); System.out.println(columnName + "=" + value); } System.out.println("------test----------"); } } @Test public void testMapHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; Map map = (Map) qr.query(sql, new MapHandler()); for(Map.Entry me : map.entrySet()) { System.out.println(me.getKey() + "=" + me.getValue()); } } @Test public void testMapListHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from users"; List list = (List) qr.query(sql, new MapListHandler()); for(Map map :list){ for(Map.Entry me : map.entrySet()) { System.out.println(me.getKey() + "=" + me.getValue()); } } } @Test public void testScalarHandler() throws SQLException{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select count(*) from users"; //[13] list[13] int count = ((Long)qr.query(sql, new ScalarHandler(1))).intValue(); System.out.println(count); }

    } 三.DBUtils+C3P0工具类实现 项目准备 创建项目 导入jar包 工具类 配置文件 dbutils.jar c3p0.jar jdbc.jar 之前项目的info.properties c3p0工具类 实现代码 public class ResultHanlder { ​ @Test public void testArrayHander() throws SQLException { ​ // ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[] QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ Object[] query = runner.query(“select * from day13 where id = ?”, new ArrayHandler(), 9); ​ for (Object object : query) { ​ System.out.println(object); } ​ } ​ @Test public void testArrayListHander() throws SQLException { ​ // ArrayHandler:适合取1条记录。把该条记录的每列值封装到一个数组中Object[] QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ List<Object[]> query = runner.query("select * from day13 ", new ArrayListHandler()); ​ for (Object[] objects : query) { for (Object object : objects) { ​ System.out.println(object); } } ​ } @Test public void testColumnListHander() throws SQLException { ​ // ColumnListHandler:取某一列的数据。封装到List中。 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ List query = runner.query("select * from day13 ", new ColumnListHandler(2)); ​ for (Object objects : query) { ​ System.out.println(objects); } ​ } ​ @Test public void testKeyedHandler() throws SQLException { ​ // KeyedHandler:取多条记录,每一条记录封装到一个Map中,再把这个Map封装到另外一个Map中,key为指定的字段值 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ Map<Object, Map<String, Object>> query = runner.query("select * from day13 “, new KeyedHandler(2)); ​ for (Object key : query.keySet()) { System.out.println(key); for (Entry<String, Object> entry : query.get(key).entrySet()) { System.out.println(“key:” + entry.getKey() + " values:” + entry.getValue()); } } ​ } ​ @Test public void testMapHandler() throws SQLException { ​ // MapHandler:适合取1条记录。把当前记录的列名和列值放到一个Map中 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ Map<String, Object> query = runner.query("select * from day13 “, new MapHandler()); ​ for (Entry<String, Object> entry : query.entrySet()) { System.out.println(“key:” + entry.getKey() + " values:” + entry.getValue()); } ​ } ​ @Test public void testMapListHandler() throws SQLException { ​ // MapListHandler:适合取多条记录。把每条记录封装到一个Map中,再把Map封装到List中 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ List<Map<String, Object>> query = runner.query("select * from day13 “, new MapListHandler()); ​ for (Map<String, Object> entry : query) { ​ for (Entry<String, Object> mapEntr : entry.entrySet()) { System.out.println(“key:” + mapEntr.getKey() + " values:” + mapEntr.getValue()); } } } ​ @Test public void testScalarHandler() throws SQLException { ​ // ScalarHandler:适合取单行单列数据 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); ​ Object query = runner.query("select count(*) from day13 ", new ScalarHandler()); System.out.println(query); } ​ @Test public void testBeanHandler() throws SQLException { // BeanHandler:适合取单行单列数据 QueryRunner runner = new QueryRunner(C3P0Util.getDataSource()); Day13 query = runner.query("select name,age from day13 ", new BeanHandler(Day13.class)); System.out.println(query.toString()); } } 四.关闭资源与事务处理 是否自动关闭Connection资源是由创建QueryRunner时使用的构造器决定的: ①如果传入了数据源,那么Connection会自动关闭,在调用增删查改的方法时就不需要传入Connection。这种方式会导致每次执行SQL都会建立新连接,在SQL执行完毕后会断开连接,无法通过Connection控制事务。 ②如果没有传入数据源,那么Connection需要手动关闭,在调用增删查改方法时需要手动传入Connection。这种方式在执行SQL时不会获取新连接,也不会在SQL执行完毕后断开连接,可以根据传入的Connection控制事务

    Processed: 0.016, SQL: 9