Apache-DBUtils简介
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
API介绍:
org.apache.commons.dbutils.QueryRunner
org.apache.commons.dbutils.ResultSetHandler
工具类:org.apache.commons.dbutils.DbUtils
API包说明:
主要API的使用
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 commitAndClose(Connection conn)throws SQLException
:用来提交连接的事务,然后关闭连接。 -
public static void commitAndCloseQuietly(Connection conn)
:用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。 -
public static void rollback(Connection conn)throws SQLException
:允许conn为null,因为方法内部做了判断 -
public static void rollbackAndClose(Connection conn)throws SQLException
-
rollbackAndCloseQuietly(Connection)
-
public static boolean loadDriver(java.lang.String driverClassName)
:这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。
QueryRunner类
该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
QueryRunner类提供了两个构造器:
-
默认的构造器
-
需要一个
javax.sql.DataSource
来作参数的构造器
QueryRunner类的主要方法:
//更新
//用来执行一个更新(插入、更新或删除)操作
public int update(Connection conn, String sql, Object... params) throws SQLException
//插入
//只支持INSERT语句,其中 rsh表示:用于从自动生成的键的ResultSet创建结果对象的处理程序。返回值:自动生成的键值。
public <T> T insert(Connection conn,String sql,ResultSetHandler<T> rsh, Object... params) throws SQLException
//批处理
//INSERT、UPDATE、DELETE语句
public int[] batch(Connection conn,String sql,Object params)throws SQLException
//只支持INSERT语句
public <T> T insertBatch(Connection conn,String sql,ResultSetHandler<T> rsh,Object params)throws SQLException
//查询
//执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException
ResultSetHandler接口及实现类
该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。
接口的主要实现类:
-
ArrayHandler:把结果集中的第一行数据转成对象数组。
-
ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
-
**BeanHandler:**将结果集中的第一行数据封装到一个对应的JavaBean实例中。
-
**BeanListHandler:**将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
-
ColumnListHandler:将结果集中某一列的数据存放到List中。
-
KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
-
**MapHandler:**将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
-
**MapListHandler:**将结果集中的每一行数据都封装到一个Map里,然后再存放到List
-
**ScalarHandler:**查询单个值对象
使用C3P0和DBUtils进行DAO层操作
1、创建项目,导入jar包:c3p0、dbutils、mysql-connector-java
。
c3p0-0.9.1.2.jar、mysql-connector-java-5.1.0-bin.jar
2、导入c3p0配置文件:c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="user">root</property>
<property name="password">root123</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/数据库名?useUnicode=true&characterEncoding=UTF-8</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- 连接池初始化的时候的连接数 -->
<property name="initialPoolSize">1</property>
<!--连接池中连接的最大个数 -->
<property name="maxPoolSize">5</property>
<!--用户获得连接Connection的时候,如果有连接就获得,没有就等待的时间,如果超时就报异常 -->
<property name="maxIdleTime">1000</property>
<!--连接池中连接的最小个数 -->
<property name="minPoolSize">5</property>
</default-config>
</c3p0-config>
3、编写c3p0的工具类
package com.coydone.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class C3P0Utils {
//在成员位置创建一个静态的ComboPooledDataSource对象
private static DataSource dataSource = new ComboPooledDataSource();
//放置c3p0-config.xml文件
//私有化构造方法
private DBUtils(){}
//返回一个连接池对象,给QueryRunner使用
public static DataSource getDataSource(){
return dataSource;
}
//获取数据库连接对象 Connection并返回
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
4、在domain包下编写数据库映射在java中的实体类。
package com.coydone.domain;
import java.io.Serializable;
import java.util.Date;
//员工实体类
public class Employee implements Serializable {
private Integer empno;//员工编号
private String ename;//员工姓名
private String job;//工作
private Integer mgr;//上级编号
private Date hiredate;//入职日期
private Double sal;//工资
private Double comm;//奖金
//private BigDecimal sal;
//private BigDecimal comm;
private Integer deptno;//部门编号
//省略构造方法、getter、setter、toString方法
}
5、编写实体类对应的dao层接口。
package com.coydone.dao;
import com.coydone.domain.EmpVo;
import com.coydone.domain.Employee;
import java.util.List;
public interface EmployeeDao {
//添加员工
int addEmp(Employee emp);
//通过员工编号删除员工
int delEmp(int empno);
//通过员工编号修改员工
int updateEmp(int empno,Employee emp);
//查询所有员工
List<Employee> findAll();
//查询一个
Employee findById(int empno);
//查询总记录数
Long selectCounts();
//带条件的分页查询
List<Employee> selectByEmpLimit(Employee emp,Integer pageNo,Integer pageSize);
//查询员工信息以及员工所在的部门信息
//List<EmpVo> selectByEmpAndDept();
List<EmpVo> selectByEmpAndDept();
}
6、编写dao层的实现类
package com.coydone.dao.impl;
import com.coydone.dao.EmployeeDao;
import com.coydone.domain.Dept;
import com.coydone.domain.EmpVo;
import com.coydone.domain.Employee;
import com.coydone.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.SQLException;
import java.util.List;
public class EmployeeDaoImpl implements EmployeeDao {
private QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
@Override
public int addEmp(Employee emp) {
String sql = "insert into employee(ename,job,mgr,hiredate,sal,comm,deptno) values(?,?,?,?,?,?,?) ";
try {
int i = qr.update(sql, emp.getEname(), emp.getJob(), emp.getMgr(), emp.getHiredate(), emp.getSal(), emp.getComm(), emp.getDeptno());
return i;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int delEmp(int empno) {
String sql = " delete from employee where empno = ? ";
try {
return qr.update(sql, empno);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public int updateEmp(int empno, Employee emp) {
String sql = " update employee set ename = ? , job = ? , mgr = ? ,hiredate = ? ,sal = ?,comm = ?,deptno = ? where empno = ? ";
try {
return qr.update(sql, emp.getEname(), emp.getJob(), emp.getMgr(), emp.getHiredate(), emp.getSal(), emp.getComm(), emp.getDeptno(), empno);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
@Override
public List<Employee> findAll() {
String sql = "select * from employee";
try {
List<Employee> list = qr.query(sql, new BeanListHandler<Employee>(Employee.class));
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public Employee findById(int empno) {
String sql = "select * from employee where empno = ?";
try {
return qr.query(sql, new BeanHandler<Employee>(Employee.class),empno);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public Long selectCounts() {
String sql = " select count(1) from employee";
try {
Long count = qr.query(sql, new ScalarHandler<Long>());
return count;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<Employee> selectByEmpLimit(Employee emp, Integer pageNo, Integer pageSize) {
//select * from employee where 1=1
// and ename like '%张%' and job = '文员' and mgr = 1004 and hiredate = '2001-12-03' limit ?,?
StringBuffer sql = new StringBuffer();
sql.append(" select * from employee where 1=1 ");
if (emp.getEname()!= null && !(emp.getEname().equals(""))){
sql.append(" and ename like '%"+emp.getEname()+"%'");
}
if (emp.getJob()!= null && !(emp.getJob().equals(""))){
sql.append(" and job ='"+emp.getJob()+"'");
}
if (emp.getMgr()!= null && !(emp.getMgr().equals(""))){
sql.append(" and mgr ="+emp.getJob());
}
if (emp.getHiredate()!= null && !(emp.getHiredate().equals(""))){
sql.append(" and hiredate = '"+emp.getHiredate()+"'");
}
sql.append(" limit ?,? ");
System.out.println(sql.toString());
try {
List<Employee> list = qr.query(sql.toString(), new BeanListHandler<Employee>(Employee.class), (pageNo - 1) * pageSize, pageSize);
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
@Override
public List<EmpVo> selectByEmpAndDept() {
//String sql = "select * from employee left join dept on employee.deptno = dept.deptno";
String sql01 = " select * from employee ";
try {
List<EmpVo> list = qr.query(sql01, new BeanListHandler<EmpVo>(EmpVo.class));
for (int i = 0; i < list.size(); i++) {
String sql02 = "select * from dept where deptno = ? ";
Dept dept = qr.query(sql02, new BeanHandler<Dept>(Dept.class), list.get(i).getDeptno());
list.get(i).setDept(dept);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
7、编写测试类
package com.coydone.test;
import com.coydone.dao.EmployeeDao;
import com.coydone.dao.impl.EmployeeDaoImpl;
import com.coydone.domain.EmpVo;
import com.coydone.domain.Employee;
import org.junit.Test;
import java.util.Date;
import java.util.List;
public class EmployeeTest {
EmployeeDao employeeDao = new EmployeeDaoImpl();
//添加员工
@Test
public void addEmpTest(){
Employee emp = new Employee(null,"永恩","剑士",1006,new Date(),80000.00,2000.00,20);
int i = employeeDao.addEmp(emp);
System.out.println(i);
}
//通过员工编号删除员工
@Test
public void delEmpTest(){
int i = employeeDao.delEmp(1020);
System.out.println(i);
}
//通过员工编号修改员工
@Test
public void updateEmpTest(){
Employee emp = new Employee(null,"瑞文","剑士",1006,new Date(),8000.00,2000.00,20);
int i = employeeDao.updateEmp(1020, emp);
System.out.println(i);
}
//查询所有员工
@Test
public void findAllTest(){
List<Employee> list = employeeDao.findAll();
for (Employee employee : list) {
System.out.println(employee);
}
}
//查询一个
@Test
public void findByIdTest(){
Employee employee = employeeDao.findById(1018);
System.out.println(employee);
}
//查询总记录数
@Test
public void selectCountsTest(){
Long counts = employeeDao.selectCounts();
System.out.println(counts);
}
//带条件的分页查询
@Test
//select * from employee where 1=1
// and ename like '%张%' and job = '文员' and mgr = 1004 and hiredate = '2001-12-03' limit ?,?
public void selectByEmpLimitTest(){
Employee emp = new Employee();
//emp.setEname("张");
emp.setJob("文员");
List<Employee> list = employeeDao.selectByEmpLimit(emp, 1, 10);
for (Employee employee : list) {
System.out.println(employee);
}
}
//查询员工信息以及员工所在的部门信息
@Test
public void selectByEmpAndDeptTest(){
List<EmpVo> empVos = employeeDao.selectByEmpAndDept();
for (EmpVo empVo : empVos) {
System.out.println(empVo);
}
}
}
评论区