1、导包
2、使用
提供以下类
org.apache.commons.dbutils.QueryRunner、ResultSetHandler、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。
QueryRunner类
该类能简单化SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量
•
QueryRunner
类提供了两个构造方法:
// 自己实现了一个ResultSetHandler接口
class MyResultSetHandler implements ResultSetHandler<User>{
public User handle(ResultSet resultSet) throws SQLException {
User user = new User();
if (resultSet.next()) {
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
int age = resultSet.getInt("age");
user.setId(id);
user.setUsername(username);
user.setPassword(password);
user.setAge(age);
}
return user;
}
----------------------------------------------------------------------------------------------------------------------
默认的构造方法
//不传数据源、直接传connection
@Test
public void testQueryRunnerWithOutDatasource() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection connection = DruidUtils.getConnection();
User user = queryRunner.query(connection,"select * from user where id = 33029", new MyResultSetHandler());
System.out.println(user);
connection.close();
}
}
需要一个 javax.sql.DataSource
来作参数的构造方法
// 传数据源
@Test
public void testQueryRunnerWithDatasource() throws SQLException {
// 获取到数据源
DataSource dataSource = DruidUtils.getDataSource();
QueryRunner queryRunner = new QueryRunner(dataSource);
User user = queryRunner.query("select * from user where id = 33029", new MyResultSetHandler());
System.out.println(user);
}
API
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:用来执行一个不需要置换参数的更新操作。
PS:query方法里带params底层可能是用预编译实现的
对比:
传数据源对于我们来说,我们看不到connection对象,所以我们没有办法执行 `connection.setAutoCommit(false);` 所以我们假如在创建QueryRunner这个类的时候,传递进去了数据源
`QueryRunner queryRunner = new QueryRunner(dataSource);`
这种构造方法就没办法自己去使用事务控制。
假如我们使用的是无参构造,那么在我们调用
queryRunner.query(Connection conn, String sql, Objects ...)
这个API的时候,就可以使用事务控制起来
但是query方法是查询方法,也不需要事务
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
ScarlarHandler:将单个值封装,可以用来统计聚合函数count(),max(),min(),avg()等方法返回的值
// queryRunner.update()
@Test
public void testQueryRunnerUpdate() throws SQLException {
QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
String sql = "update user set username = ? where id = ?";
int affectedRows = queryRunner.update(sql,"景天",33209);
System.out.println("affectedRows:" +affectedRows);
}
// queryRunner.update()
@Test
public void testQueryRunnerUpdate2() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
Connection connection = DruidUtils.getConnection();
String sql = "update user set username = ? where id = ?";
int affectedRows = queryRunner.update(connection,sql,"长风",33209);
System.out.println("affectedRows:" +affectedRows);
}
// BeanHandler 可以帮助我们去封装单个bean
@Test
public void testBeanHandler() throws SQLException {
// 创建QueryRunner
QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
// 执行sql
String sql = "select * from user where id = ?";
User user = queryRunner.query(sql, new BeanHandler<User>(User.class), 33209);
System.out.println(user);
}
// BeanListHandler 可以帮助我们把结果封装为一个BeanList
@Test
public void testBeanListHandler() throws SQLException {
// 创建QueryRunner
QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
// 执行sql
String sql = "select * from user where id in (?,?,?)";
// 注意:直接传对象
BeanListHandler<User> beanListHandler = new BeanListHandler<User>(User.class);
List<User> userList = queryRunner.query(sql, beanListHandler,33209,33210,33211);
System.out.println(userList);
}
// ColumnListHandler 直接把一列的数据封装到一个List里面去
@Test
public void testColumnListHandler() throws SQLException {
// 创建QueryRunner
QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
// 执行sql
String sql = "select username from user where id in (?,?,?)";
// 注意:直接传对象
ColumnListHandler<String> columnListHandler = new ColumnListHandler<String>();
List<String> usernameList = queryRunner.query(sql, columnListHandler,33209,33210,33211);
for (String s : usernameList) {
System.out.println("username:" + s);
}
}
// ScalarHandler 这个是查一个数值的时候用的
@Test
public void testScarlarHandler() throws SQLException {
// 创建QueryRunner
QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
// 执行sql
String sql = "select count(1) from user where id in (?,?,?)";
ScalarHandler<Long> scalarHandler = new ScalarHandler<Long>();
Long rows = queryRunner.query(sql, scalarHandler,33209,33210,33211);
System.out.println("行数:" + rows);
}