java basedao 泛性反射_泛型的补偿实例--使用泛型反射创建BaseDao

对于Java泛型,我们知道两点:

1.      泛型是JDK1.5以后才有的,可以在编译时期进行类型检查,将类和方法与所使用的类型之间的约束关系进行了解耦,从而可以编写更通用的代码。

2.      泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!如果需要在运行时使用类型信息,需要显式地传递你的类型的Class对象来对泛型进行补偿。

下面的BaseDao就是通过泛型的反射来获得运行时的类型信息,从而编写更为通用的代码。

泛型反射涉及的API

包名:java.lang.reflect

接口 Type

已知子接口:

ParameterizedType

所有已知实现类:

Class

包名java.lang.reflect

接口 ParameterizedType

getActualTypeArguments()

返回表示此类型实际类型参数的 Type 对象的数组。

什么是参数化类型

ArrayList这种形式就是参数化类型

BaseDao代码

其中连接池使用C3P0;

约定:

1. 实体类名  -  表名

2. 实体属性名  -  表中字段名

3. 主键名称必须叫id

import java.lang.reflect.ParameterizedType;

import java.lang.reflect.Type;

import java.sql.SQLException;

import java.util.List;

import org.apache.commons.dbutils.handlers.BeanHandler;

import org.apache.commons.dbutils.handlers.BeanListHandler;

import util.*;

/**

* 所有dao的公用的方法,都在这里实现

*

*/

public class BaseDao {

// 保存当前运行类的参数化类型中的实际的类型

private Class clazz;

// 表名 约定表名就是实体类名 -- 在C#的BaseDAL中,是通过Lamda表达式传入表名的

private String tableName;

// 构造函数: 1. 获取当前运行类的参数化类型;

// 2. 获取参数化类型中实际类型的定义(class)

public BaseDao() {

// this 表示当前运行类 (AccountDao/AdminDao)

// this.getClass() 当前运行类的字节码对象(AccountDao.class/AdminDao.class)

// this.getClass().getGenericSuperclass(); 当前运行类的父类,即为BaseDao

// 其实就是“参数化类型”, ParameterizedType

//返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type

Type type = this.getClass().getGenericSuperclass();

// 强制转换为“参数化类型” 【BaseDao】

ParameterizedType pt = (ParameterizedType) type;

// Class类是Type接口的实现类

// 获取参数化类型中,实际类型的定义 【new Type[]{Account.class}】

Type types[] = pt.getActualTypeArguments();

// 获取数据的第一个元素:Accout.class

clazz = (Class) types[0];

// 表名 (与类名一样,只要获取类名就可以)

tableName = clazz.getSimpleName();

}

/**

* 主键查询

*

* @param id

* 主键值

* @return 返回封装后的对象

*/

@SuppressWarnings({"unchecked"})

public T findById(int id) {

/*

* 1. 知道封装的对象的类型 2. 表名【表名与对象名称一样, 且主键都为id】

*

* 即,得到当前运行类继承的父类 BaseDao ----》 得到Account.class

*/

String sql = "select * from " + tableName + " where id=? ";

try {

return JdbcUtils.getQuerrRunner().query(sql,

new BeanHandler(clazz), id);

} catch (SQLException e) {

throw new RuntimeException(e);

}

}

/**

* 查询全部

*

* @return

*/

public List getAll() {

String sql = "select * from " + tableName;

try {

return JdbcUtils.getQuerrRunner().query(sql,

new BeanListHandler(clazz));

} catch (SQLException e) {

throw new RuntimeException(e);

}

}

}

这样写完之后存在一个明显的问题,那就是前面的约定约束性太强了,如果数据库表和实体类名不是对应关系,该怎么做呢?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值