• java泛型反射总结


    引入:

          在需求中,数据库有两张表user,admin。我们要查询里面的id,name等信息通常都是写两个dao,然后分别给每个查询字段写一套方法。

         然而其实查询这些字段的方法都大同小异,所以产生了一个更好的解决办法,就是写一个通用的dao,然后把相同的方法写在通用的dao(genericDao)里,然后然实体dao去继     承它。

       

        下面通过模拟 贴出一般做法 和 优化后的做法:

        首先 在数据库里建好两张表,分别为user和admin,再插入一些数据

       

    CREATE TABLE USER(
    	id INT PRIMARY KEY,
    	userName VARCHAR(20),
    	age INT
    	);
    CREATE TABLE admin(
    	id INT PRIMARY KEY,
    	adminName VARCHAR(20),
    	status_ INT
    	);
    	
    INSERT INTO USER VALUES(1,'李四',21);
    INSERT INTO USER VALUES(2,'张三',20);
    
    INSERT INTO admin VALUES(1,'超级管理员',1);
    INSERT INTO admin VALUES(2,'普通管理员',0);
            截下来写两个实体类

    public class admin {
    	private int id;
    	private String adminName;
    	private int status_;
    	public admin() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	public int getId() {
    		return id;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public String getAdminName() {
    		return adminName;
    	}
    	public void setAdminName(String adminName) {
    		this.adminName = adminName;
    	}
    	public int getStatus_() {
    		return status_;
    	}
    	public void setStatus_(int status_) {
    		this.status_ = status_;
    	}
    	@Override
    	public String toString() {
    		return "admin [id=" + id + ", adminName=" + adminName + ", status_=" + status_ + "]";
    	}
    	
    }

    public class user {
    	private int id;
    	private String userName;
    	private int age;
    	public user() {
    		super();
    		// TODO Auto-generated constructor stub
    	}
    	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 int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@Override
    	public String toString() {
    		return "userDao [id=" + id + ", userName=" + userName + ", age=" + age + "]";
    	}
    	
    }
    

    一般做法

       
    public class adminDao{
    	
    	public admin getById(int id)
    	{
    		QueryRunner qr=jdbcUtil.getQueryRunner();
    		try {
    			return (admin)qr.query("select * from admin where id=", new BeanHandler(admin.class),new Object[]{id});
    		} catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    	
    	@Test
    	public void testId()
    	{
    		adminDao adminDao = new adminDao();
    		admin byId = adminDao.getById(2);
    		System.out.println(byId);
    	}
    }

    public class userDao extends genericDao<user>{
    	public user getById(int id)
    	{
    		QueryRunner qr=jdbcUtil.getQueryRunner();
    		try {
    			return (user)qr.query("select * from user where id=?", new BeanHandler(user.class),new Object[]{id});
    		} catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    
    	@Test
    	public void testId()
    	{
    		userDao userDao = new userDao();
    		user byId = userDao.getById(2);
    		System.out.println(byId);
    	}
    	
    }

    利用泛型优化后的做法:

        首先写一个genericDao
      
    **
     * 通用的dao方法
     * @author Administrator
     *
     */
    public class genericDao <T>{
    	private Class clazz;
    	private String tableName;
    	
    	public genericDao(Class clazz,String tableName)
    	{
    		this.clazz=clazz;
    		this.tableName=tableName;
    	}
    	public  T getById(int id)
    	{
    		QueryRunner qr=jdbcUtil.getQueryRunner();
    		try {
    			return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(clazz),new Object[]{id});
    		} catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    }
    然后让实体Dao类分别继承它
    public class adminDao extends genericDao<admin>{	
    	public adminDao() {
    		super(admin.class, "admin");
    	}
    
    	@Test
    	public void testId()
    	{
    		adminDao adminDao = new adminDao();
    		admin byId = adminDao.getById(2);
    		System.out.println(byId);
    	}
    }

    public class userDao extends genericDao<user>{
    
    	public userDao() {
    		super(user.class, "user");
    	}
    
    	@Test
    	public void testId()
    	{
    		userDao userDao = new userDao();
    		user byId = userDao.getById(2);
    		System.out.println(byId);
    	}
    	
    }
    



    利用泛型反射技术优化后的做法


    generic类
    /**
     * 通用的dao方法
     * @author Administrator
     *
     */
    public class genericDao <T>{
    	private Class clazz;
    	private String tableName;
    	
    	public genericDao()
    	{
    		System.out.println(this);//this 指当前运行的类对象  如果有子类继承它,则它指的是子类,而不是generic本身类
    		System.out.println(this.getClass());//获得当前运行类的字节码
    		System.out.println(this.getClass().getSimpleName());//获得当前运行类的类名
    		System.out.println(this.getClass().getSuperclass());//获得当前运行类的父类的字节码
    		System.out.println(this.getClass().getGenericSuperclass());//获得参数化类型  reflect.genericDao<reflect.admin>
    		/**
    		 * 参数化类型:genericDao<reflect.admin>
    		 * 实体类型:reflect.admin
    		 */
    		//1.先获得当前运行类的泛型父类类型
    		Type type = this.getClass().getGenericSuperclass();
    		//2.强转为参数化类型
    		ParameterizedType p=(ParameterizedType)type;
    		//3.获取参数化类型中,实际类型的定义
    		Type[] actualTypeArguments = p.getActualTypeArguments();
    		//获取数组的第一个元素,即我们想要的实际类型的字节码类型
    		clazz=(Class<T>) actualTypeArguments[0];
    		
    		//给表名赋值
    		tableName=clazz.getSimpleName();
    		
    	}
    	public  T getById(int id)
    	{
    		QueryRunner qr=jdbcUtil.getQueryRunner();
    		try {
    			return (T)qr.query("select * from "+tableName+" where id=?", new BeanHandler(clazz),new Object[]{id});
    		} catch (SQLException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    			throw new RuntimeException(e);
    		}
    	}
    }
    

     简化后的dao类
    public class userDao extends genericDao<user>{
    
    	@Test
    	public void testId()
    	{
    		userDao userDao = new userDao();
    		user byId = userDao.getById(2);
    		System.out.println(byId);
    	}
    	
    }
    public class adminDao extends genericDao<admin>{
    	
    
    	@Test
    	public void testId()
    	{
    		adminDao adminDao = new adminDao();
    		admin byId = adminDao.getById(2);
    		System.out.println(byId);
    	}
    }


    得出结论:子类继承父类,并传一个实际类型给父类,父类可以在类中通过反射技术先获得参数化类型,再获得参数化类型中的实际类型。即xxx.class

         

  • 相关阅读:
    Oracle数据库容灾备份技术探讨
    asp.net 生成、解析条形码和二维码
    推荐一些C#相关的网站、资源和书籍
    内部集群的 DNS server 搭建
    Nginx 负载均衡
    webpack技巧:动态批量加载文件
    Mock.js使用
    @vue/cli 项目编译重复命中缓存问题解析
    用React hooks实现TDD
    从 React 切换到 Vue.js
  • 原文地址:https://www.cnblogs.com/chenny3/p/10226229.html
Copyright © 2020-2023  润新知