使用BaseDAO类实现数据库的基本操作时的一个问题
package com.atguigu.myssm.basedao;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseDAO<T> {
public final String DRIVER = "com.mysql.cj.jdbc.Driver" ;
public final String URL = "jdbc:mysql://localhost:3306/fruitdb";
public final String USER = "root";
public final String PWD = "123456" ;
protected Connection conn = null;
protected PreparedStatement psmt = null;
protected ResultSet rs = null;
//T的Class对象
private Class entityClass;
public BaseDAO(){
//getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
//那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
//因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
//所以getGenericSuperclass()获取到的是BaseDAO的Class
Type genericType = getClass().getGenericSuperclass();
//ParameterizedType参数化类型
Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
//获取到的<T>中的T的真实的类型
Type actualType = actualTypeArguments[0];
try {
entityClass = Class.forName(actualType.getTypeName());
} catch (Exception e) {
e.printStackTrace();
}
}
上面的代码是BaseDAO类的构造函数。
主要是为了在初始化子类时,可以利用反射得到字类的类。
所以字类的声明需要这样写
public class FruitDAOImpl extends BaseDAO<Fruit> implements FruitDAO {
@Override
public List<Fruit> getFruitList() {
return super.executeQuery("select * from t_fruit");
}
@Override
public Fruit getFruitById(int id) {
return (Fruit) super.load("select * from t_fruit where fid = ?", id);
}
}
因为将上面代码中的BaseDAO<Fruit>直接写为BaseDAO,导致本人找了三天多的bug,做此纪录铭记!