(三)利用泛型反射机制实现增加,删除,更新,查询操作(支持继承基类)

/**
 * 基类dao,抽象封装所有的操作
 *
 */
public class BaseDao<T> {
	private DbUtil dbUtil = DbUtil.getInstance();
	//public Connection connection = dbUtil.getConnection();
	private final static int CURD_ADD = 0;
	private final static int CURD_UPDATE = 1;
	private final static int CURD_FIND = 2;
	private final static int CURD_SELECT = 3;
	private final static int CURD_DELETE = 4;
	private final static int CURD_COUNT = 5;
	private Class<T> t; 	 
	
	
	public BaseDao(){
		Type genericSuperclass = this.getClass().getGenericSuperclass();//获得超类
		if(genericSuperclass instanceof ParameterizedType){
			Type[] actualTypeArguments = ((ParameterizedType)genericSuperclass).getActualTypeArguments();
			if(actualTypeArguments != null && actualTypeArguments.length > 0){
				t = (Class<T>) actualTypeArguments[0];
			}
		}
		//System.out.println(t.getSimpleName());
	}
	
	
	/**
	 * 抽象封装数据库添加操作
	 * @param t
	 * @return
	 */
	public boolean add(T t){
		String sql = buildSql(CURD_ADD);
		try {
			PreparedStatement prepareStatement = dbUtil.getConnection().prepareStatement(sql);
			prepareStatement = setPreparedStatement(t,prepareStatement,CURD_ADD);
			int rst = prepareStatement.executeUpdate();
			dbUtil.releaseConnection();
			return rst > 0;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 数据库更新操作抽象封装
	 * @param t
	 * @return
	 */
	public boolean update(T t){
		String sql = buildSql( CURD_UPDATE);
		try {
			PreparedStatement prepareStatement = dbUtil.getConnection().prepareStatement(sql);
			prepareStatement = setPreparedStatement(t,prepareStatement,CURD_UPDATE);
			int rst = prepareStatement.executeUpdate();
			dbUtil.releaseConnection();
			return rst > 0;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	/**
	 * 数据库查询单个实体抽象封装
	 * @param id
	 * @return
	 */
	public T find(int id){
		String sql = buildSql(CURD_FIND);
		T newInstance = null;
		try {
			PreparedStatement prepareStatement = dbUtil.getConnection().prepareStatement(sql);
			prepareStatement.setObject(1, id);
			ResultSet executeQuery = prepareStatement.executeQuery();
			if(executeQuery.next()){
				newInstance = (T) t.newInstance();
				newInstance = setParams(newInstance,executeQuery);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		dbUtil.releaseConnection();
		return newInstance;
	}
	
	
	
	/**
	 * 给从数据库获取的数据赋值并实例化
	 * @param newInstance
	 * @param executeQuery
	 * @return
	 */
	private T setParams(T newInstance, ResultSet executeQuery) {
		// TODO Auto-generated method stub
		//首先获取自身定义的字段
		Field[] declaredFields = newInstance.getClass().getDeclaredFields();
		try {
			for(Field field :declaredFields){
				field.setAccessible(true);
				if(field.isAnnotationPresent(Column.class)){
					Column annotation = field.getAnnotation(Column.class);
					if(!annotation.isForeignEntity()){
						//如果不是自定义对象
						field.set(newInstance, executeQuery.getObject(annotation.name()));
					}else{
						Blob blob = executeQuery.getBlob(annotation.name());
						ObjectInputStream objectInputStream = 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复标识为 “代码味道”,但我们大多数都已经学会忍受它。能不能不写重复的dao 呢 ? 泛型dao,顾名思义就是一个dao可以对多个实体对象进行持久化。当应用中需要使用到上十张表时,DAO的维护变得日益困难,主要表现在这几个方面: 1)dao类的繁多,很多设计都是一个entity对应一个dao (不同的只有类名和方法名) 2)dao接口需要维护的method庞大。 3)业务逻辑改变时,dao需要同时修改两个类文件(接口和实现类) 在本文中,我将为您展示如何避免再地重复 DAO 代码。 在这里我建议项目最好使用一个共通的DAO,因为这样会为你省去非常多的类,而那些类里的逻辑往往差不多。当然是用共通的DAO你需要对结果转型,转成你需要的bean,但这也比写那么多DAO强多了,你可以放下包袱,只关注你的业务逻辑。 如果你真能只用一个dao解决,那么祝贺你,你得到了一个虚拟数据层(高度抽象的数据接口)。这是一个比dao更高级的存在。 欢迎大家指正 -_- 虚心求教 代码层次: bean-->dao-->service-->action 技术概述:1.继承 继承利用现有的类创建新类的过程,现有的类称作基类(或父类),创建的新类称作派生类(子类)。继承其实就是自动地共享基类中成员属性和成员方法的机制。引入继承实现了代码重用; 2.泛型 泛型类型的限定 3.反射 代码概述: bean :Person.java 这个人员类我就不说了 泛型dao接口 :GenericDao 泛型作为DAO的通用接口 CRUD方法 dao接口 : PersonDAO extends GenericDao 可以不写代码,方法已经在父类泛型dao里了,这里为了说明:可扩展添加 findByNameExact()方法 子类的附加方法。 泛型daoimpl :GenericDaoImpl implements GenericDao 必须提供的构造方法,以便创建实例的时候就知道具体实体的类型。 daoimpl :PersonDAOImpl extends GenericDaoImpl implements PersonDAO public PersonDAOImpl() { super(Person.class); } 告诉对哪个类操作,如不需要自定义扩展方法就作有一个构造方法。 泛型Service:GenericService.java 与泛型dao没有区别 Service :PersonService.java 直接继承泛型serviceimpl与serviceimpl实现和dao层实现一样。 Action : SavePersonAction直接调用PersonService。 下面是代码 为了演示减少代码量而且直观去掉些方法方便读者自己扩展写出适合自己的代码,这里我只抛砖引玉了。主要介绍这个技术。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zylyueliang/archive/2010/09/17/5890043.aspx
泛型为Integer的情况下,可以利用反射机制来进行以下操作: 1. 获取泛型的类类型(Type): 可以使用`Class<?> clazz = Integer.class`或者`Class<?> clazz = obj.getClass()`得到泛型的类类型,其中`obj`为已经实例化的泛型对象。 2. 获取泛型类的类型参数(Type Parameter): 可以使用`ParameterizedType parameterizedType = (ParameterizedType) clazz.getGenericSuperclass()`来获取泛型类的类型参数。然后通过`Type[] typeArgs = parameterizedType.getActualTypeArguments()`来获取实际的类型参数数组。 3. 创建泛型对象的实例: 可以使用`Integer integer = (Integer) clazz.newInstance()`来创建泛型对象的实例。 4. 调用泛型对象的方法: 可以使用`Method method = clazz.getMethod("methodName", parameterTypes)`来获取泛型类中的指定方法,其中`methodName`为方法名,`parameterTypes`为方法的参数类型。然后使用`Object result = method.invoke(obj, args)`来调用该方法,其中`obj`为已经实例化的泛型对象,`args`为方法的参数。 5. 使用泛型类中的字段: 可以使用`Field field = clazz.getField("fieldName")`来获取泛型类中的指定字段,其中`fieldName`为字段名。然后使用`Object value = field.get(obj)`来获取该字段的值,`field.set(obj, value)`来设置该字段的值。 通过反射机制,我们可以动态地获取泛型类的信息并实例化对象、调用方法以及访问字段。这种灵活性可以在编写通用代码时更方便地操作泛型类。但需要注意的是,反射的使用会带来额外的性能开销,因此在性能敏感的场景下需要谨慎使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值