DBUtils详细介绍+实例

    科技2025-08-22  25

    DBUtils详细介绍+实例

    1)简介:   DBUtils是一个小型的类库,它使JDBC编程更加方便,简单。在JDBC编程中,资源的关闭是显式的,极易导致编程出现错误,DBUtils把这些工作抽象出来,使得程序员编程时仅需要关心正真的问题,即对数据库的增删改查。      2)优点:   杜绝资源泄露。修正JDBC代码并不困难,但是这是耗时而乏味的,这通常导致连接泄露并且难以跟踪到。   清洁干净的持久化代码。大段的持久化数据到数据库代码彻底精简,剩下的代码清晰地表达了编码的意图。   从ResultSet里自动组装JavaBean。你不再需要手工set每一行每一列的值到bean中,每一行数据都将会以一个Bean实例的形式出现

    3)适用场景:   通常初学者用JDBC比较多,只是初学者为了打实基础,练习阶段少用框架和帮助类库。   小型项目,小型项目不需要太多的数据库操作,不需要考虑跨数据库兼容问题,用框架并不会让编码更简单。   需要高效率的项目,无论iBatis、Hibernate,到了底下还是JDBC,直接用JDBC访问数据库无疑是最优的效率最高的方案。      4)准备:   下载下来后(当然也可以使用maven工程),名称为commons-dbutils-1.6.jar,下面总共包含三个包,分别是:   DBUtils的包结构      其中的org.apache.commons.dbutils包主要有如下的接口和类:   ResultSetHandler——将ResultSet转换为别的对象的工具。   BeanProcessor——匹配列名到Bean属性名,转换结果集列到Bean对象的属性。   DbUtils——一个JDBC辅助工具集合。   ProxyFactory——产生JDBC接口的代理实现。   QueryLoader——属性文件加载器,用于加载属性文件中的SQL到内存中。   QueryRunner——使用可插拔的策略执行SQL查询并处理结果集。   ResultSetIterator——包装结果集为一个迭代器。      其中的org.apache.commons.dbutils.handlers包为第一个包中ResultSetHandler接口的实现类:   AbstractListHandler——将ResultSet转化为List类型的抽象类。   ArrayHandler——将ResultSet转化为Object[]类型的实现类。   ArrayListHandler——将ResultSet转化为List<Object[]>类型的实现类。   BeanHandler——将ResultSet转化为JavaBean类型的实现类。   BeanListHandler——将ResultSet转化为List类型的实现类。   ColumnListHandler ——将ResultSet转化为List类型的实现类。   MapHandler ——将ResultSet转换为Map类型的实现类。   MapListHandler ——将ResultSet转换为List类型的实现类。   KeyedHandler——将ResultSet转换为Map类型的实现类。   ScalarHandler ——将ResultSet的一个列转化到一个对象。

    其中的org.apache.commons.dbutils.wrappers包:   SqlNullCheckedResultSet——在每个getXXX方法上检查SQLNULL值的包装类。   StringTrimmedResultSet——取出结果集中字符串左右空格的ResultSet包装类。

    在使用过程中只需要熟悉DbUtils、QueryRunner和ResultSetHandler的用法就足够了。      DbUtils是一个做关闭连接,装载JDBC驱动程序等工作的类,它里面所有的方法都是静态的:   Close():DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭连接(Connection)、声明(Statement)和结果集(ResultSet)。   CloseQuietly():CloseQuietly这一方法不仅能在连接(Connection)、声明(Statement)和结果集(ResultSet)为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。如果你不想捕捉这些异常的话,这对你是非常有用的。   CommitAndCloseQuietly:这一方法用来提交连接,然后关闭连接,并且在关闭连接时不向上抛出在关闭时发生的一些SQL异常。   LoadDriver():这一方法装载并注册JDBC驱动程序,如果成功就返回TRUE。使用这种方法,你不需要去捕捉这个异常ClassNotFoundException。使用loadDriver()方法,编码就变得更容易理解,你也就得到了一个很好的Boolean返回值,这个返回值会告诉你驱动类是不是已经加载成功了。      ResultSetHandler接口处理一个java.sql.ResultSet,将数据转变为其它的形式,该接口提供ArrayHandler、ArrayListHandler、BeanHandler、BeanListHandler、MapHandler、MapListHandler、ScalarHandler等执行程序。ResultSetHandler的执行需要一个结果集(ResultSet)作为参数传入,然后才能处理这个结果集,再返回一个对象。因为返回类型是java.lang.Object,所以除了不能返回一个原始的Java类型之外,其它的返回类型并没有什么限制。如果你发现这七个执行程序中没有任何一个提供了你想要的服务,你可以自己写执行程序并使用它。      QueryRunner使执行SQL查询简单化了,它与ResultSetHandler串联在一起有效地履行着一些平常的任务,它能够大大减少你所要写的编码。它包含以下重要的方法:   query(Connection conn,String sql,Object[] params,ResultSetHandler rsh):这一方法执行一个选择查询,对象数组(Object[] params)中的值被用来作为查询语句sql的置换参数。该方法会内在地处理Statement和ResultSet的创建和关闭。ResultSetHandler对把从ResultSet得来的数据转变成一个更容易的或是应用程序特定的格式来使用。   query(String sql,Object[] params,ResultSetHandler rsh):这几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,它是从提供给构造器的数据源(DataSource) 或使用的setDataSource 方法中重新获得的。   query(Connection conn,String sql,ResultSetHandler rsh):该方法是执行一个不需要参数的查询操作。   update(Connection conn,String sql,Object[] params):该方法用来执行插入、更新或者删除操作,对象数组(Object[] params)中的值被用来作为更新语句sql的置换参数。    5)核心类及使用方法

    核心类:QueryRunner; ResultSetHandler(是一个接口,主要是完成ORM映射,把结果街转化成我们需要的java对象) 核心方法:

    update();用来执行DDL(DDL:create alert,drop;);query();用来执行DML(DML:insert update delete;);batch(); 用来执行批处理; 调用本方法之前,需要先创建对象,代码如下: QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource()); //当使用的是无参的构造器时,可以不提供连接池对象,但是在接下来的调用方法是,必须为方法提供Connection 对象。

    对于结果集的处理有以下几个结果集处理器: *BenaHandler //把单行结果集的数据封装成javaBean对象,返回值是ResultSetHandler ResultSetHandler <javaBean类型> rsh = new BeanHandler<javaBean类型>(javaBean.class); 本方法多用于在 处理把单行结果集封装成JavaBean对象。(对象时通过反射完成创建的)

    *BeanListHandler List<javaBean类型> list = <List<javaBean类型>> new BeanListHandler<javaBean类型>(javaBean.class); 本方法多用于把多行结果集封装成对象,并且把对象添加到集合中,新版本中可能不需要进行类型的转换, 的到集合可以通过foreach循环来进行遍历。

    *MapHandler Map <String,Object> map = new MapHandler(); 本方法是用来吧单行结果集封装到一个Map中其中map的键是表中的列名称,值对应表的列值。

    *MapListHandler List<Map<String,Object>> listmap = new MapListHandler(); 本方法是用来多行结果集的处理,把每行的结果封装成一个map,最后把所有的,安排都装刀片一个集合中 返回值是一个集合,但是集合中存放的是map,

    *ColumnHandler List nameList = new ColumnHandler(); 本方法是用来出来单列,单行 或者多行的数据

    *ScalarHandler 本方法是用于处理单行单列的数据,多用于聚合函数的查询,但是以一个点需要注意,就是当聚合函数是涉及到 数字类型的时候,一定要注意返回值类型的转换。有的人会选用Integer,long等类型,这些严格来说都是不合法 的,例如,long类型最大只能容纳20的阶乘,21的阶乘就会包异常,所以我们要选用Number(这个是所有数据类型) 的父类,并且对外提供的有Number.intValue(),和Number.LongValue(),等方法。

    具体的代码如下: import java.sql.SQLException; import java.util.List; import java.util.Map; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; public class Demo1 { //总结:使用DBUtils工具的步骤就是, /**

    首先要创建一个QueryRunner对象 然后给出sql语句 通过QueryRunner对象来执行SQL语句,并且针对不用的SQL语句使用不同的结果集处理器。 并且本对象会自动关闭连接。 / /* 测试增删改(她们的模板差不多)@throws SQLException */ public void fun1() throws SQLException { student stu = new student(); stu.setSid(“1007”); stu.setSname(“蒋干”); stu.setSage(“35”); stu.setSgender(“男”); add(stu); }

    /**

    增加方法@throws SQLException */ //创建一个QueryRunner 对象,并且传递一个连接池参数,这样以后调用的本方法时候就不用 //再提供Connection了,如果没有提供,那么调用本方法时,就必须要提供Connection public void add(student stu) throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “insert into student values(?,?,?,?)”; qr.update(sql, stu.getSid(),stu.getSname(),stu.getSage(),stu.getSgender());

    } public void fun2() throws SQLException { student stu = new student(); stu.setSid(“1007”); stu.setSname(“蒋干 不知不觉”); stu.setSage(“35”); stu.setSgender(“男”); update(stu); } //修改 public void update(student stu) throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “update set sname=?,sage=?,sgender=? where sid =d?”; qr.update(sql, stu.getSid(),stu.getSname(),stu.getSage(),stu.getSgender());

    } public void fun3() throws SQLException { delete(“1007”); } //删除方法 public void delete(String id) throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “delete from studnt where id=?”; qr.update(sql, id); }

    /**

    查询语句@throws SQLException */ //BeanHandler结果集处理器用来处理,把单行查询得到的结果集抓换成对象 public void fun4() throws SQLException { //创建对象 QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); ResultSetHandler rsh = new BeanHandler(student.class); String sql = “select * from student where sid=?”; student stu = qr.query(sql, rsh, “1007”);

    } //BeanListHandler用于处理多行结果集,把多个结果分别封装成对象,并且添加到一个集合中 //不过得到的结果需要进行强转,可以使用增强for循环集合的遍历。 public void fun5() { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “select * from student”; List rshList = (List) new BeanListHandler(student.class); for(student L:rshList) { System.out.println(L); } } //MapHandler是把得到的单行结果集封装到一个map中 //其中map的键对应的是列名称,值对应的是列的值 。 public void fun6() throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “select * from student where id=?”; Map<String,Object> map = qr.query(sql, new MapHandler(),“1003”); System.out.println(map); }

    //MapListHandler用来处理多行结果集,是把多行结果集中的每行数据封装成一个对象在map中,然后把多个Map //封装到一个集合中,写成了List<Map<String,Object>> public void fun7() throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “select * from student”; List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler()); for(Map<String,Object> map:mapList) { System.out.println(map); } } //用来处理单列多(单)行的数据,封装到集合中 public void fun8() throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “select sname from student”; List nameList = qr.query(sql, new ColumnListHandler()); System.out.println(nameList); } //scalarHandler通常用在聚合函数查询的结果集处理,对单列单行进行处理 public void fun9() throws SQLException { QueryRunner qr = new QueryRunner(JDBCUtils.getDataSouse()); String sql = “select count(1) from student”; //这是个重点如果你此时强转用的是Integer 或者long类型的话,都是不行的,因为数据类型的大小可能 //不够使用发的,比如long类型的可以容纳20的阶乘,但是21的阶乘就超出范围,但是数据类型共同的父类 //就是Number,用这个是绝对不会出现超出范围的情况 //处理方法可以是,number.intValue(),或者是number.LongValue(); Number num = (Number)qr.query(sql, new ScalarHandler()); System.out.println(num.intValue()); } }

    Processed: 0.013, SQL: 9