简介
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
这里用之前的Person例子
1 package com.gh.Dao.impl; 2 3 import java.math.BigDecimal; 4 import java.sql.Connection; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 import java.sql.SQLException; 8 import java.util.ArrayList; 9 import java.util.Arrays; 10 import java.util.List; 11 12 import javax.sound.sampled.Line; 13 14 import org.apache.commons.dbutils.QueryRunner; 15 import org.apache.commons.dbutils.handlers.BeanHandler; 16 import org.apache.commons.dbutils.handlers.BeanListHandler; 17 import org.apache.commons.dbutils.handlers.ScalarHandler; 18 19 import com.gh.Dao.PersonDao; 20 import com.gh.db.JdbcUtil; 21 import com.gh.domain.Person; 22 23 /** 24 * PersonDao接口的实现 25 * 26 * @author ganhang 27 * 28 */ 29 public class PersonDaoImpl implements PersonDao { 30 QueryRunner qr=new QueryRunner(); 31 @Override 32 public void add(Person p) throws SQLException { 33 // oracle 没有主键自动增长 必须用序列和触发器,这边就直接传id了。 34 35 String sql = "insert into Person(id,name,age,description) values(?,?,?,?)"; 36 qr.update(JdbcUtil.getConnection(), sql, p.getId(),p.getName(),p.getAge(),p.getDescription()); 37 } 38 //更新 39 @Override 40 public void update(Person p) throws SQLException { 41 String sql = "update Person set name=?,age=?,description=? where id=?"; 42 qr.update(JdbcUtil.getConnection(), sql, p.getName(),p.getAge(),p.getDescription(),p.getId()); 43 } 44 //删除 45 @Override 46 public void delete(int id) throws SQLException { 47 String sql = "delete Person where id=?"; 48 qr.update(JdbcUtil.getConnection(), sql,id); 49 } 50 //通过id查询 51 @Override 52 public Person findById(int id) throws SQLException { 53 String sql = "select * from Person where id=?"; 54 Person p= qr.query(JdbcUtil.getConnection(), sql, new BeanHandler<Person>(Person.class), id); 55 return p; 56 } 57 //查询所有 58 @Override 59 public List<Person> findAll() throws SQLException { 60 String sql = "select * from Person"; 61 List<Person> persons=qr.query(JdbcUtil.getConnection(), sql, new BeanListHandler<Person>(Person.class)); 62 return persons; 63 } 64 @Override 65 public int personCount() throws SQLException{ 66 String sql="select count(*) from Person"; 67 //这里查出来只能返回BigDecimal 68 BigDecimal i= qr.query(JdbcUtil.getConnection(), sql, new ScalarHandler<BigDecimal>()); 69 return i.intValue(); 70 } 71 }
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
测试
1 package com.gh.db; 2 3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.util.ArrayList; 8 import java.util.Iterator; 9 import java.util.List; 10 11 import com.gh.Dao.impl.PersonDaoImpl; 12 import com.gh.domain.Person; 13 /** 14 * 测试 15 * 使用DbUtils工具domain必须符合JavaBean规范 16 * BeanHandler必须在bean的属性名和对应表的字段相同情况下可以处理,否者会导致属性为null; 17 * @author ganhang 18 * 19 */ 20 public class test { 21 public static void main(String[] args) { 22 PersonDaoImpl pd=new PersonDaoImpl(); 23 Person p=new Person(4,"小绿",7,"哈哈哈哈哈"); 24 try { 25 //pd.add(p); 26 //pd.delete(3); 27 //p=pd.findById(1); 28 List<Person> ps=pd.findAll(); 29 System.out.println(ps); 30 //System.out.println(p); 31 //System.out.println(pd.personCount()); 32 } catch (SQLException e) { 33 e.printStackTrace(); 34 } 35 } 36 }
三、DbUtils类使用讲解
DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:
public static void close(…) throws java.sql.SQLException: DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
public static void closeQuietly(…): 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
public static void commitAndCloseQuietly(Connection conn): 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。
public static boolean loadDriver(java.lang.String driverClassName):这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。