前言:
设置通用方法,会用到反射泛型。
先来认识一下Type这个接口:
Type 接口,任何类型默认的接口!
包括: 引用类型、原始类型、参数化类型
List<String> list = new ArrayList<String>();
泛型集合: list
集合元素定义:new ArrayList<String>(); 中的String
参数化类型: ParameterizedType
即:“ArrayList<String> ” 为参数化类型
参数化类型是Type接口的一个实现接口
接下来的栗子就是用到了 :参数化类型。
了解下 我们以前在写dao层的时候其实都是重复代码,比如
根据教师的id,学生的id查找教师和学生的信息
查找教师的全部信息,查找学生的全部信息
在这里面,只有类不一样,其他的代码是完全冗余的,我们需要抽离出来,写一个通用类。这里就用到了参数化类型。
students类:
public class students {
private int id;
private String name;
private int age;
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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return id+":"+name+":"+age;
}
}
users类:
public class users {
private int id;
private String name;
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;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return id + ":" + name;
}
}
注意:实体类和数据库的表类相同,方便操作
子类dao层:users类
public class UserDao extends BasicDao<users>{
}
子类dao层:students类
public class StudentDao extends BasicDao<students>{
}
只要在BasicDao父类中实现通用方法即可。
这里父类就用到了泛型来接收子类传递过来的参数,然后使用参数化类型中提取出运行类的类型。
public class BasicDao<T> {
// 保存当前运行类的参数化类型中的实际的类型
private Class actualClass;
private String table;
// 构造函数:
// 1. 获取当前运行类的参数化类型;
// 2. 获取参数化类型中实际类型的定义(class)
public BasicDao() {
//getGenericSuperclass
//当前运行类(UserDao类)的超类,即为BaseDao<Account>
Type type= this.getClass().getGenericSuperclass();
//其实就是参数化类型 所以强制转换为“参数化类型”
ParameterizedType parameterizedType = (ParameterizedType) type;
//获取全部的参数化类型,本次中只有users或者students
Type[] types = parameterizedType.getActualTypeArguments();
actualClass = (Class) types[0];
//获取实际类的名字 去掉路径
table = actualClass.getSimpleName();
}
public T findById(int id) throws SQLException {
String sql = "SELECT * FROM "+table+" where id = ?";
return JdbcUtilsC3p0.getQueryRunner().query(sql, new BeanHandler<T>(actualClass), id);
}
public List<T> findAll() throws SQLException{
String sql = "SELECT * FROM "+table;
return JdbcUtilsC3p0.getQueryRunner().query(sql, new BeanListHandler<T>(actualClass));
}
}
运行入口:
public class Main {
public static void main(String[] args) throws SQLException {
UserDao userDao = new UserDao();
StudentDao studentDao = new StudentDao();
users user = userDao.findById(1);
List<users> usersOne = userDao.findAll();
students student = studentDao.findById(1);
List<students> studentsOne = studentDao.findAll();
System.out.println(user);
System.out.println(usersOne);
System.out.println(student);
System.out.println(studentsOne);
}
}
输出:
1:我
[1:我, 2:是, 3:你]
1:我:12
[1:我:12, 2:你:33]
注意下:
我这里还用到了 C3p0
public class JdbcUtilsC3p0 {
//创建数据源
private static DataSource dataSource;
static {
dataSource = new ComboPooledDataSource();
}
//获取dbutils操作的核心方法
public static QueryRunner getQueryRunner() {
return new QueryRunner(dataSource);
}
}
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/daynow?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=false</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
</default-config>
</c3p0-config>