Hibernate的CRUD重用性
1、在研究了hibernate框架之后,准备完成一套Hibernate的CRUD操作,并且让其具有高度的重用性。在复杂查询方面,hibernate可谓是各种不方便,因此查询方面,利用java反射做出一套根据对象属性来动态查询数据的小框架。
2、先做出可行的设计图
3、具体的实现过程
1 package com.framework.common.dao; 2 3 import test.framework.common.PageEntity; 4 5 import java.util.List; 6 import java.util.Map; 7 8 /** 9 * @AUTHOR fuguangli 10 * @DESCRIPTION hibernate的查询类,利用反射检测对象的不为空条件 11 * @DATE 2017/4/8 0008 12 */ 13 public interface HibernateQueryReflect<T> { 14 /** 15 * 按条件分页查询所有 16 * @param t 17 * @param pageEntity 18 * @return 19 */ 20 List<T> listAllWithPage(T t, PageEntity pageEntity); 21 22 /** 23 * 按条件查询所有 24 * @param t 25 * @return 26 */ 27 List<T> listAll(T t); 28 29 /** 30 * 按hql语句查询所有,针对复杂查询 31 * @param hql 32 * @return 33 */ 34 List<T> listByHql(String hql); 35 }
1 package com.framework.common.dao; 2 3 import org.hibernate.Criteria; 4 import org.hibernate.Query; 5 import org.hibernate.criterion.Projections; 6 import org.hibernate.criterion.Restrictions; 7 import org.springframework.orm.hibernate3.support.HibernateDaoSupport; 8 import org.springframework.util.CollectionUtils; 9 import test.framework.common.PageEntity; 10 import test.framework.common.dao.*; 11 12 import java.lang.reflect.Field; 13 import java.lang.reflect.Method; 14 import java.util.Arrays; 15 import java.util.HashMap; 16 import java.util.List; 17 import java.util.Map; 18 19 /** 20 * @AUTHOR fuguangli 21 * @DESCRIPTION 类 22 * @DATE 2017/4/8 0008 23 * @warning 并没有获取实体的父类属性当作条件 24 * @extend 应该使条件可自定义,应该使父类的属性也能参与条件 25 * @explain 原理就是利用java的反射调用属性相应的get方法,如果值不为null,则添加条件 26 */ 27 public abstract class HibernateQueryReflectImpl<T> extends HibernateDaoSupport implements test.framework.common.dao.HibernateQueryReflect<T> { 28 29 30 /** 31 * 根据条件查询所有的数据 32 * 33 * @param t 34 * @return 35 */ 36 public List<T> listAll(T t) { 37 try { 38 //创建查询对象,根据对象值添加条件 39 Criteria criteria = this.getSession().createCriteria(t.getClass()); 40 41 //反射添加条件 42 Class clazz = t.getClass(); 43 Field[] fields = clazz.getDeclaredFields(); 44 if (!CollectionUtils.isEmpty(Arrays.asList(fields))) { 45 for (Field f : fields) { 46 f.setAccessible(true); 47 String fieldSimpleName = f.getName(); 48 String getMethodName = "get" + fieldSimpleName.substring(0, 1).toUpperCase() + fieldSimpleName.substring(1); 49 Method method = clazz.getDeclaredMethod(getMethodName, null); 50 Object value = method.invoke(t, null); 51 if (value != null) { 52 criteria.add(Restrictions.eq(fieldSimpleName, value)); 53 } 54 } 55 } 56 57 //执行查询 58 return criteria.list(); 59 } catch (Exception e) { 60 e.printStackTrace(); 61 } 62 return null; 63 } 64 65 /** 66 * 根据条件f分页查询所有的数据 67 * 68 * @param t 69 * @param pageEntity 70 * @return 71 */ 72 public List<T> listAllWithPage(T t, PageEntity pageEntity) { 73 74 try { 75 //创建查询对象,根据对象值添加条件 76 Criteria criteria = this.getSession().createCriteria(t.getClass()); 77 78 //反射添加条件 79 Class clazz = t.getClass(); 80 Field[] fields = clazz.getDeclaredFields(); 81 if (!CollectionUtils.isEmpty(Arrays.asList(fields))) { 82 for (Field f : fields) { 83 f.setAccessible(true); 84 String fieldSimpleName = f.getName(); 85 String getMethodName = "get" + fieldSimpleName.substring(0, 1).toUpperCase() + fieldSimpleName.substring(1); 86 Method method = clazz.getDeclaredMethod(getMethodName, null); 87 Object value = method.invoke(t, null); 88 if (value != null) { 89 criteria.add(Restrictions.eq(fieldSimpleName, value)); 90 } 91 } 92 } 93 //查询总记录数 94 criteria.setProjection(Projections.rowCount()); 95 long allCount = (Long) criteria.uniqueResult(); 96 97 //分页条件 98 if (pageEntity != null) { 99 criteria.setFirstResult(pageEntity.getStartRow()); 100 criteria.setMaxResults(pageEntity.getPageSize()); 101 } 102 103 //恢复查询 104 criteria.setProjection(null); 105 //执行查询 106 List<T> resultData = criteria.list(); 107 108 //扩展分页实体 109 pageEntity.setTotalResultSize((int)allCount); 110 pageEntity.setTotalPageSize((int)allCount / pageEntity.getPageSize() + (allCount % pageEntity.getPageSize() > 0 ? 1 : 0)); 111 112 113 114 return resultData; 115 } catch (Exception e) { 116 e.printStackTrace(); 117 } 118 return null; 119 } 120 121 /** 122 * 按hql语句查询所有,针对复杂查询 123 * 124 * @param hql 125 * @return 126 */ 127 @Override 128 public List<T> listByHql(String hql) { 129 Query query = this.getSession().createQuery(hql); 130 List<T> data = query.list(); 131 return data; 132 } 133 134 /*排序 分组 查询*/ 135 136 /*模糊查询*/ 137 }
1 package com.framework.dao; 2 3 import org.springframework.transaction.annotation.Transactional; 4 import test.framework.common.dao.HibernateQueryReflect; 5 6 import java.io.Serializable; 7 8 /** 9 * @AUTHOR fuguangli 10 * @DESCRIPTION 基础CRUD类 11 * @DATE 2017/4/7 0007 12 */ 13 @Transactional 14 public interface BaseDao<T> extends HibernateQueryReflect<T> { 15 /** 16 * 插入数据 17 * @param t 18 * @return 19 */ 20 T insert(T t); 21 22 /** 23 * 删除数据 24 * @param t 25 */ 26 void delete(T t); 27 28 /** 29 * 更新数据 30 * @param t 31 * @return 32 */ 33 T update(T t); 34 35 /** 36 * 按ID查询数据 37 * @param t 38 * @param id 39 * @return 40 */ 41 @Transactional(readOnly = true) 42 T getById(T t, Serializable id); 43 }
1 package com.framework.daoImpl; 2 3 import org.apache.log4j.Logger; 4 import org.hibernate.HibernateException; 5 import org.springframework.dao.DataAccessResourceFailureException; 6 import org.springframework.stereotype.Repository; 7 import test.framework.common.dao.HibernateQueryReflectImpl; 8 import test.framework.dao.BaseDao; 9 10 import java.io.Serializable; 11 12 /** 13 * @AUTHOR fuguangli 14 * @DESCRIPTION 基础CRUD类 15 * @DATE 2017/4/7 0007 16 */ 17 @Repository 18 public abstract class BaseDaoImpl<T> extends HibernateQueryReflectImpl<T> implements BaseDao<T> { 19 20 @Override 21 public T insert(T t) { 22 this.getSession().save(t); 23 return t; 24 } 25 26 @Override 27 public void delete(T t) { 28 this.getSession().delete(t); 29 } 30 31 @Override 32 public T update(T t) { 33 this.getSession().update(t); 34 return t; 35 } 36 37 38 @Override 39 public T getById(T t, Serializable id) { 40 return (T) this.getSession().get(t.getClass(), id); 41 } 42 43 /** 44 * 根据对象动态获取hql语句 45 * 46 * @param o 47 * @return 48 */ 49 private String packageQueryObject(Object o) { 50 return null; 51 } 52 }
1 package com.framework.service; 2 3 import org.springframework.transaction.annotation.Transactional; 4 import test.framework.common.PageEntity; 5 import test.framework.dao.BaseDao; 6 7 import java.io.Serializable; 8 import java.util.List; 9 10 /** 11 * @AUTHOR fuguangli 12 * @DESCRIPTION 基础业务类 13 * @DATE 2017/4/8 0008 14 */ 15 public interface BaseService<T> { 16 /** 17 * 插入数据 18 * @param t 19 * @return 20 */ 21 T insert(T t); 22 23 /** 24 * 删除数据 25 * @param t 26 */ 27 void delete(T t); 28 29 /** 30 * 更新数据 31 * @param t 32 * @return 33 */ 34 T update(T t); 35 36 /** 37 * 按ID查询数据 38 * @param t 39 * @param id 40 * @return 41 */ 42 T getById(T t, Serializable id); 43 44 /** 45 * 按条件分页查询所有 46 * @param t 47 * @param pageEntity 48 * @return 49 */ 50 List<T> listAllWithPage(T t, PageEntity pageEntity); 51 52 /** 53 * 按条件查询所有 54 * @param t 55 * @return 56 */ 57 List<T> listAll(T t); 58 59 /** 60 * 按hql语句查询所有,针对复杂查询 61 * @param hql 62 * @return 63 */ 64 List<T> listByHql(String hql); 65 }
1 package com.framework.serviceimpl; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import test.framework.common.PageEntity; 5 import test.framework.dao.BaseDao; 6 import test.framework.service.BaseService; 7 8 import java.io.Serializable; 9 import java.util.List; 10 11 /** 12 * @AUTHOR fuguangli 13 * @DESCRIPTION 基础业务类 14 * @DATE 2017/4/8 0008 15 */ 16 public abstract class BaseServiceImpl<T> implements BaseService<T> { 17 /** 18 * 插入数据 19 * 20 * @param t 21 * @return 22 */ 23 @Autowired 24 private BaseDao<T> baseDao; 25 26 @Override 27 public T insert(T t) { 28 return baseDao.insert(t); 29 } 30 31 /** 32 * 删除数据 33 * 34 * @param t 35 */ 36 @Override 37 public void delete(T t) { 38 baseDao.delete(t); 39 } 40 41 /** 42 * 更新数据 43 * 44 * @param t 45 * @return 46 */ 47 @Override 48 public T update(T t) { 49 return baseDao.update(t); 50 } 51 52 /** 53 * 按ID查询数据 54 * 55 * @param t 56 * @param id 57 * @return 58 */ 59 @Override 60 public T getById(T t, Serializable id) { 61 return baseDao.getById(t,id); 62 } 63 64 /** 65 * 按条件分页查询所有 66 * 67 * @param t 68 * @param pageEntity 69 * @return 70 */ 71 @Override 72 public List<T> listAllWithPage(T t, PageEntity pageEntity) { 73 return baseDao.listAllWithPage(t,pageEntity); 74 } 75 76 /** 77 * 按条件查询所有 78 * 79 * @param t 80 * @return 81 */ 82 @Override 83 public List<T> listAll(T t) { 84 return baseDao.listAll(t); 85 } 86 87 /** 88 * 按hql语句查询所有,针对复杂查询 89 * 90 * @param hql 91 * @return 92 */ 93 @Override 94 public List<T> listByHql(String hql) { 95 return baseDao.listByHql(hql); 96 } 97 }
4、到此,新建dao直接继承BaseDao或者service直接继承BaseService,就可以进行增删改查操作了