未优化
先写一个DAO的基类,声明为抽象类,无法用它来生成对象
import com.atguigu3.util.JDBCUtils;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
/**
* 封装了针对数据表的通用操作
*
* 声明为抽象类 不能造对象
* **/
public abstract class BaseDAO {
//通用增删改 2.0
public void update(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps);//从外面传进来的连接,也不必关
}
}
public <T> ArrayList<T> getForList(Connection conn, Class<T> cl, String sql, Object...args)
{
//Connection conn= null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
conn = JDBCUtils.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
for(int i=0;i<args.length;i++)
{
ps.setObject(i+1,args[i]);
}
resultSet = ps.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount=metaData.getColumnCount();
//创建集合对象
ArrayList<T> list=new ArrayList<>();
while (resultSet.next())
{
//创建一个对象,属于cl类
T t = cl.newInstance();
for(int i=0;i<columnCount;i++) {
Object columnValue = resultSet.getObject(i + 1);
String columnLabel = metaData.getColumnLabel(i + 1);
Field field = cl.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
// conn.close();
// ps.close();
// resultSet.close();
JDBCUtils.closeResource(null,ps,resultSet);
}
return null;
}
public <E> E getValue(Connection conn,String sql,Object... args)
{
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
ps = conn.prepareStatement(sql);
for(int i=0;i<args.length;i++)
{
ps.setObject(i+1,args[i]);
}
resultSet = ps.executeQuery();
if(resultSet.next())
{
return (E)resultSet.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null,ps,resultSet);
}
return null;
}
}
针对customers表,定义接口 用于规范针对于customers表的常用操作
import java.sql.Connection;
import java.util.Date;
import java.util.List;
/**
* 定义针对customers表的规范
* 此接口用于规范针对于customers表的常用操作
* **/
public interface CustomerDAO {
//将cust对象添加到数据库中
void insert(Connection conn,Customer cust);
void delete(Connection conn,int id);
//针对内存中的cust对象,修改数据表中指定的记录
void update(Connection conn,Customer cust);
Customer getCustomerById(Connection conn, int id) throws Exception;
List<Customer> getAll(Connection conn);
Long getCount(Connection conn);
Date getMaxBirthday(Connection conn);
}
最后新建一个CustomerDAOImpl类,可以生成对象
public class CustomerDAOImpl extends BaseDAO implements CustomerDAO
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class CustomerDAOImpl extends BaseDAO implements CustomerDAO{
@Override
public void insert(Connection conn, Customer cust) {
String sql="insert into customers(name,email,birth)values(?,?,?)";
update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth());
}
@Override
public void delete(Connection conn, int id) {
String sql="delete from customers where id=?";
update(conn,sql,id);
}
@Override
public void update(Connection conn, Customer cust) {
String sql="update customers set name=?,email=?,birth=? where id=?";
update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth(),cust.getId());
}
@Override
public Customer getCustomerById(Connection conn, int id) {
String sql="select name,email,birth from customers where id=?";
ArrayList<Customer> list = getForList(conn, Customer.class,sql,id);
return list.get(0);
}
@Override
public List<Customer> getAll(Connection conn) {
String sql="select name,email,birth from customers";
ArrayList<Customer> customers=getForList(conn,Customer.class,sql);
return customers;
}
@Override
public Long getCount(Connection conn) {
String sql="select count(*) from customers";
Long count=getValue(conn,sql);
return null;
}
@Override
public Date getMaxBirthday(Connection conn) {
String sql="select max(birth) from customers";
Date date=getValue(conn,sql);
return date;
}
}
优化
把Class类参数给省略了~
综合泛型、反射的知识
import com.atguigu3.util.JDBCUtils;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
/**
* 封装了针对数据表的通用操作
*
* 声明为抽象类 不能造对象
* **/
public abstract class BaseDAO<T> {
private Class<T> cl=null; //这个cl取决于子类CustomerDAO需要的类型 。在子类中,想办法调父类的属性,作赋值;但是子类中每次都要调有点麻烦,就写在父类里面吧
//注意!子类中调用了以下代码块 获取父类的class
{
//获取当前BaseDAO的子类继承的父类中的泛型
Type genericSuperclass = this.getClass().getGenericSuperclass(); //父类泛型
ParameterizedType paraType=(ParameterizedType)genericSuperclass;
Type[] typeArguments = paraType.getActualTypeArguments();//获取父类泛型参数
cl=(Class<T>) typeArguments[0];//泛型的第一个参数
}
//通用增删改 2.0
public void update(Connection conn, String sql, Object... args) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null, ps);//从外面传进来的连接,也不必关
}
}
public ArrayList<T> getForList(Connection conn, String sql, Object...args) //此时不是泛型方法了,这个T用的是父类中的泛型T
{
//Connection conn= null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
conn = JDBCUtils.getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql);
for(int i=0;i<args.length;i++)
{
ps.setObject(i+1,args[i]);
}
resultSet = ps.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount=metaData.getColumnCount();
//创建集合对象
ArrayList<T> list=new ArrayList<>();
while (resultSet.next())
{
//创建一个对象,属于cl类
T t = cl.newInstance();
for(int i=0;i<columnCount;i++) {
Object columnValue = resultSet.getObject(i + 1);
String columnLabel = metaData.getColumnLabel(i + 1);
Field field = cl.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(t, columnValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
} finally {
// conn.close();
// ps.close();
// resultSet.close();
JDBCUtils.closeResource(null,ps,resultSet);
}
return null;
}
public T getValue(Connection conn,String sql,Object... args)
{
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
ps = conn.prepareStatement(sql);
for(int i=0;i<args.length;i++)
{
ps.setObject(i+1,args[i]);
}
resultSet = ps.executeQuery();
if(resultSet.next())
{
return (T)resultSet.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(null,ps,resultSet);
}
return null;
}
}