关于泛型反射的案例

1.在创建数据库时创建两个表

CREATE TABLE users(
    id INT PRIMARY KEY AUTO_INCREMENT,
    userName VARCHAR(30),
    pwd VARCHAR(30) 
)

CREATE    TABLE accounts(
    id INT AUTO_INCREMENT PRIMARY KEY,
    money DOUBLE NOT NULL
)

2.编写两个数据库的实体类设计

/**
 * Entity设计类:Accounts
 * @author Han
 *
 */
public class Accounts {
    
    private int id;
    private double money;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
}
/**
 * Entity设计类:Users
 * @author Han
 *
 */
public class Users {
    
    private int id;
    private String userName;
    private String pwd;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

3.两个方法拥有共同的方法:public Users/Accounts findById(int id)的方法,而这两个方法除了数据库表结构不同(表名)和封装的对象(Users,Accounts)不同,其余的地方都是一样的所以可以编写一个相同的父类,将相同的代码抽取出来,所以就会用到泛型反射,编写BaseDao<T>类。(关键)

/**
 * BaseDao方法设计,抽取各个Dao中的公用方法
 * 各个Dao之间的不同有两点:1,表名,2.当前封装对象
 * @author Han
 *
 * @param <T>
 */
public class BaseDao<T> {
    
    /**
     * 当前对象的类
     */
    private Class clazz;
    
    /**
     * 当前数据库表的名字(封装对象的类名)(注:表名和类名相同,表中字段与类中成员变量名字相同)
     */
    private String tableName;
    
    public BaseDao() {

        //this 表示调用该方法对象:UsersDao/AccountsDao
        //this.getClass() 获取当前对象的字节码文件(UsersDao.Class/AccountsDao.Class)
        //this.getClass().getGenericSuperClass 获取当前运行类的父类 
        //即为BaseDao<Users>/Base<Accounts>
        Type type = this.getClass().getGenericSuperclass();
        //强制转化为参数化类型BaseDao<Users>/Base<Accounts>
        ParameterizedType pt = (ParameterizedType) type;
        //获取类型集合types[]{Accounts/Users}
        Type[] types = pt.getActualTypeArguments();
        clazz = (Class) types[0];
        tableName = clazz.getSimpleName();
    }
    
    public T findById(int id){
        
        String sql = "select * from " + tableName + " where id=?";
        
        try {
            //该处使用DBUtils的jar包和C3P0连接池,JdbcUtils工具类就不列出了
            return JdbcUtils.getQuerrRunner().query(sql, new BeanHandler<T>(clazz), id);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
}

4.创建两个对象的Dao方法

/**
 * Dao:Users,将Users对象传入父类BaseDao
 * @author Han
 *
 */
public class UsersDao extends BaseDao<Users> {
    
    
    
}
/**
 * Dao:Accounts,将Accounts对象传入父类BaseDao
 * @author Han
 *
 */
public class AccountsDao extends BaseDao<Accounts> {
    
}

5.测试类

@Test
    public void testDao() throws Exception {
        
        UsersDao dao = new UsersDao();
        
        System.out.println(dao.findById(1));
    }

OK,测试成功!关于泛型和反射,还需要多多磨炼,多做些例子,才能更好的掌握!

原文地址:https://www.cnblogs.com/a294098789/p/5241940.html