首页 > 技术文章 > Hibernate的CRUD重用性

yuan951 2017-04-08 18:52 原文

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,就可以进行增删改查操作了

推荐阅读