07、DAO及相关实现类
-
DAO
:Data Access Object
访问数据信息的类和接口,包括了对数据的CRUD
(Create
、Retrival
、Update
、Delete
),而不包含任何业务相关的信息。有时也称作:BaseDAO
-
作用:为了实现功能的模块化,更有利于代码的维护和升级。
-
下面是项目中
DAO
的体现:
-
层次结构:
【BaseDAO.java】
package com.jdbc1.dao;
import com.jdbc.util.JDBCUtil;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
/**
* DAO:Data(base) Access Object
* 封装了针对于数据表通用的操作
*/
public abstract class BaseDAO<T> {
private Class<T> clazz = null;
/*public BaseDAO() {
}*/
{
//获取当前BaseDAO的子类继承的父类中的泛型
Type genericSuperclass = this.getClass().getGenericSuperclass();
ParameterizedType type = (ParameterizedType) genericSuperclass;
Type[] typeArguments = type.getActualTypeArguments();
clazz = (Class<T>) typeArguments[0];//泛型的第一个参数
}
//通用的增删改操作,使用可变形参-----version2.0 (考虑事务)
public int update(Connection con, String sql, Object... args) {
PreparedStatement psm = null;
try {
//1、预编译SQL语句,返回PreparedStatement实例
psm = con.prepareStatement(sql);
//2、填充占位符
for (int i = 0; i < args.length; i++) {
//小心参数的声明错误
psm.setObject(i + 1, args[i]);
}
//3、执行
return psm.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
//4、资源的关闭
JDBCUtil.closeResource(null, psm);
}
return 0;
}
/**
* 通用查询操作,返回表中的一条记录(version2.0 考虑上事务)
*
*/
public T getInstance(Connection con, String sql, Object ... args) {
PreparedStatement psm = null;
ResultSet rs = null;
try {
psm = con.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
psm.setObject(i + 1, args[i]);
}
rs = psm.executeQuery();
//获取结果集的元数据 String name = "Tom"; Tom是关键,String和name是修饰name的两个元数据
ResultSetMetaData rsmd = rs.getMetaData();
//通过ResultSetMetaData获取结果集中的列表
int columnCount = rsmd.getColumnCount();
if (rs.next()) {
T t = clazz.newInstance();
//处理结果集一行数据中的每一个列
for (int i = 0; i < columnCount; i++) {
Object columnValue = rs.getObject(i + 1);
//获取每个列的别名
String columnLabel = rsmd.getColumnLabel(i + 1);
//给t对象指定的columnName属性赋值columnValue,通过反射
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
return t;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.closeResource(null, psm, rs);
}
return null;
}
/**
* 通用查询操作,用于返回表中的多条记录构成的集合(version2.0,考虑上事务)
*/
public List<T> getForList(Connection con, String sql, Object ... args) {
PreparedStatement psm = null;
ResultSet rs = null;
try {
psm = con.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
psm.setObject(i + 1, args[i]);
}
rs = psm.executeQuery();
//获取结果集的元数据 String name = "Tom"; Tom是关键,String和name是修饰name的两个元数据
ResultSetMetaData rsmd = rs.getMetaData();
//通过ResultSetMetaData获取结果集中的列表
int columnCount = rsmd.getColumnCount();
//创建集合对象
ArrayList<T> list = new ArrayList<>();
while (rs.next()) {
T t = clazz.newInstance();
//处理结果集一行数据中的每一个列;给t对象指定的属性赋值
for (int i = 0; i < columnCount; i++) {
Object columnValue = rs.getObject(i + 1);
//获取每个列的别名
String columnLabel = rsmd.getColumnLabel(i + 1);
//给t对象指定的columnName属性赋值columnValue,通过反射
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.closeResource(null, psm, rs);
}
return null;
}
/**
* 用于查询特殊值的通用的方法
*/
public <E>E getValue(Connection con, String sql, Object ... args) {
PreparedStatement psm = null;
ResultSet rs = null;
try {
psm = con.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
psm.setObject(i + 1, args[i]);
}
rs = psm.executeQuery();
if (rs.next()) {
return (E) rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.closeResource(null, psm, rs);
}
return null;
}
}
【CustomerDAO.java】
package com.jdbc1.dao;
import com.jdbc.bean.Customer;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
/**
* 此接口用于规范针对于customers表的常用操作
*/
public interface CustomerDAO {
/**
* 将 customer对象添加到数据库中
* @param con
* @param customer
*/
void insert(Connection con, Customer customer);
/**
* 针对指定Id,删除表中的一条记录
* @param con
* @param id
*/
void deleteById(Connection con, int id);
/**
* 针对于内存中的customer对象,修改数据库表中指定的记录
* @param con
* @param customer
*/
void update(Connection con, Customer customer);
/**
* 根据指定的Id查询得到对应的Customer对象
* @param con
* @param id
*/
Customer getCustomerById(Connection con, int id);
/**
* 查询表中的所有记录构成的集合
* @param con
* @return
*/
List<Customer> getAll(Connection con);
/**
* 返回数据表中的数据的条目数
* @param con
* @return
*/
Long getCount(Connection con);
/**
* 返回数据表中最大的生日
* @param con
* @return
*/
Date getMaxBirth(Connection con);
}
【CustomerDAOImpl.java】
package com.jdbc1.dao;
import com.jdbc.bean.Customer;
import java.sql.Connection;
import java.sql.Date;
import java.util.List;
public class CustomerDAOImpl extends BaseDAO<Customer> implements CustomerDAO {
@Override
public void insert(Connection con, Customer customer) {
String sql = "insert into customers(name, email, birth) values(?,?,?)";
update(con, sql, customer.getName(), customer.getEmail(), customer.getBirth());
}
@Override
public void deleteById(Connection con, int id) {
String sql = "delete from customers where id = ?";
update(con, sql, id);
}
@Override
public void update(Connection con, Customer customer) {
String sql = "update customers set name = ?,email = ?,birth = ? where id = ?";
update(con, sql, customer.getName(), customer.getEmail(), customer.getBirth(), customer.getId());
}
@Override
public Customer getCustomerById(Connection con, int id) {
String sql = "select id,name,email,birth from customers where id = ?";
Customer customer = getInstance(con, sql, id);
return customer;
}
@Override
public List<Customer> getAll(Connection con) {
String sql = "select id,name,email,birth from customers";
List<Customer> list = getForList(con, sql);
return list;
}
@Override
public Long getCount(Connection con) {
String sql = "select count(*) from customers";
return getValue(con, sql);
}
@Override
public Date getMaxBirth(Connection con) {
String sql = "select max(birth) from customers";
return getValue(con, sql);
}
}
【Customer.java】
package com.jdbc.bean;
import java.sql.Date;
/**
* ORM编程思想:Object Relational Mapping
* 一个数据表对应一个Java类
* 表中的一条记录对应Java类的一个对象
* 表中的一个字段对应Java类的一个属性
*/
public class Customer {
private int id;
private String name;
private String email;
private Date birth;
public Customer() {
super();
}
public Customer(int id, String name, String email, Date birth) {
this.id = id;
this.name = name;
this.email = email;
this.birth = birth;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", birth=" + birth +
'}';
}
}