DAO封装
DAO概念
DAO(Data Access Object),意为数据库访问对象。
Java 是面向对象语言,数据在 Java 中通常以对象的形式存在,一张表对应一个实体类,一张表的操作就对应一个 DAO 对象。
在 Java 操作数据库时,通常会将一张表的增删改查操作统一维护起来,维护的这个类就叫做 DAO 层。DAO 层只关注对数据库的操作,供业务层 Service 调用。
BaseDAO
基本上每一张数据表都会对应一个 DAO接口及其实现类,可以发现所有表的增删改查代码重复度很高,所以可以抽取公共代码到 BaseDAO 中。
java
public class BaseDAO {
/**
* 增、删、改通用方法
*
* @param sql 要执行的SQL语句
* @param params 赋值占位符要填入的值
* @return 返回执行成功后的影响行数
* @throws SQLException SQL执行异常
*/
public int executeUpdate(String sql, Object... params) throws SQLException {
// 获取连接池对象
Connection connection = JDBCUtilV2.getConnection();
// 预编译SQL语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 为占位符赋值,执行SQL语句
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i + 1, params[i]);
}
}
int row = preparedStatement.executeUpdate();
// 释放资源
preparedStatement.close();
JDBCUtilV2.release();
return row;
}
/**
* 查询通用方法
*
* @param clazz 泛型对象(由调用者传入)
* @param sql 要执行的 SQL 语句
* @param params 赋值占位符要填入的值
* @param <T> 泛型类型
* @return 查询到的结果集
* @throws Exception SQL执行异常
*/
public <T> List<T> executeQuery(Class<T> clazz, String sql, Object... params) throws Exception {
// 获取连接池对象
Connection connection = JDBCUtilV2.getConnection();
// 预编译执行语句
PreparedStatement preparedStatement = connection.prepareStatement(sql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
preparedStatement.setObject(i + 1, params[i]);
}
}
// 执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
// 获取结果集中的元数据对象(包含了列的数量、列的名称)
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
List<T> list = new ArrayList<>();
while (resultSet.next()) {
// 通过反射创建类对象
T t = clazz.newInstance();
for (int i = 1; i <= columnCount; i++) {
// 获取列的名称
String fieldName = metaData.getColumnLabel(i);
// 获取列的值
Object fieldValue = resultSet.getObject(i);
// 通过列名和类对象,获取要封装类的属性名
Field declaredField = clazz.getDeclaredField(fieldName);
// 突破 private 私有的封装(因为要给 private 属性赋值)
declaredField.setAccessible(true);
// 赋值
declaredField.set(t, fieldValue);
}
list.add(t);
}
// 释放资源
resultSet.close();
preparedStatement.close();
JDBCUtilV2.release();
return list;
}
/**
* 查询单条数据通用方法
*
* @param clazz 泛型对象(由调用者传入)
* @param sql 要执行的 SQL 语句
* @param params 赋值占位符要填入的值
* @param <T> 泛型类型
* @return 查询到的单条结果
* @throws Exception SQL执行异常
*/
public <T> T executeQueryBean(Class<T> clazz, String sql, Object... params) throws Exception {
List<T> list = this.executeQuery(clazz, sql, params);
if (list == null || list.isEmpty()) {
return null;
}
return list.getFirst();
}
}
BaseDAO的使用
创建员工增删改查 DAO 接口和实现类:
java
public interface EmployeeDao {
List<Employee> selectAll();
Employee selectById(Integer empId);
int insert(Employee employee);
int update(Employee employee);
int delete(Integer empId);
}
java
public class EmployeeDaoImpl extends BaseDAO implements EmployeeDao {
@Override
public List<Employee> selectAll() {
try {
// 查询的时候,为了让列名和字段名对应,需要起别名
String sql = "select emp_id empId, emp_name empName, emp_age empAge, emp_salary empSalary from t_emp";
return executeQuery(Employee.class, sql, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public Employee selectById(Integer empId) {
try {
String sql = "select emp_id empId, emp_name empName, emp_age empAge, emp_salary empSalary from t_emp where emp_id = ?";
return executeQueryBean(Employee.class, sql, empId);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public int insert(Employee employee) {
try {
String sql = "insert into t_emp (emp_name, emp_salary, emp_age) values (?,?,?)";
return executeUpdate(sql, employee.getEmpName(), employee.getEmpSalary(), employee.getEmpAge());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public int update(Employee employee) {
try {
String sql = "update t_emp set emp_name = ? where emp_id = ?";
return executeUpdate(sql, employee.getEmpName(), employee.getEmpId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public int delete(Integer empId) {
try {
String sql = "delete from t_emp where emp_id = ?";
return executeUpdate(sql, empId);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
java
public class JDBCTest {
@Test
public void testSelectAll() {
EmployeeDao employeeDao = new EmployeeDaoImpl();
List<Employee> employees = employeeDao.selectAll();
for (Employee employee : employees) {
System.out.println("employee = " + employee);
}
}
@Test
public void testSelectById() {
EmployeeDao employeeDao = new EmployeeDaoImpl();
Employee employee = employeeDao.selectById(1);
System.out.println("employee = " + employee);
}
@Test
public void testInsert() {
EmployeeDao employeeDao = new EmployeeDaoImpl();
Employee employee = new Employee(null, "张三丰", 108, 2000.00);
int insert = employeeDao.insert(employee);
System.out.println("insert = " + insert);
}
@Test
public void testUpdate() {
EmployeeDao employeeDao = new EmployeeDaoImpl();
Employee employee = new Employee(1, "张无忌", 58, 12345.00);
int update = employeeDao.update(employee);
System.out.println("update = " + update);
}
@Test
public void testDelete() {
EmployeeDao employeeDao = new EmployeeDaoImpl();
int delete = employeeDao.delete(1);
System.out.println("delete = " + delete);
}
}