JPA封装baseDao

  1 /**
  2  * 
  3  */
  4 package pw.lizi.base;
  5 
  6 import java.io.Serializable;
  7 import java.lang.reflect.ParameterizedType;
  8 import java.lang.reflect.Type;
  9 import java.util.ArrayList;
 10 import java.util.Collection;
 11 import java.util.LinkedHashMap;
 12 import java.util.List;
 13 import java.util.Map;
 14 
 15 import javax.annotation.Resource;
 16 import javax.persistence.EntityManager;
 17 import javax.persistence.Query;
 18 
 19 import org.slf4j.Logger;
 20 import org.slf4j.LoggerFactory;
 21 import org.springframework.transaction.annotation.Propagation;
 22 import org.springframework.transaction.annotation.Transactional;
 23 
 24 import pw.lizi.util.AssertUtil;
 25 import pw.lizi.util.CollectionUtil;
 26 import pw.lizi.util.StringUtil;
 27 
 28 /**
 29  * 说明:
 30  *  34  * 2018年9月29日 下午2:03:17
 35  */
 36 @SuppressWarnings("unchecked")
 37 @Transactional
 38 public abstract class BaseServiceImpl<T, ID> implements BaseService<T, ID> {  
 39 
 40     static Logger log = LoggerFactory.getLogger(BaseServiceImpl.class);
 41     
 42     //实体类class
 43     private Class<T> entityClass = null;
 44     
 45     //ID字段的class
 46     private Class<ID> idClass = null;
 47 
 48     {
 49         
 50         //getSuperclass   返回直接继承的父类(由于编译擦除,没有显示泛型参数)
 51         //getGenericSuperclass  返回直接继承的父类(包含泛型参数)
 52         Type type = getClass().getGenericSuperclass();
 53 
 54         //解决多层继承拿泛型类型   //BaseServiceImpl<User> <- UserService <- PassportService 
 55         while(!(type instanceof ParameterizedType)){ 
 56             type = ((Class<?>)type).getGenericSuperclass();
 57             //为了避免写错代码出现死循环,加上这个保险。
 58             if(type == null || "java.lang.Object".equals(type.getClass())){
 59                 break;
 60             }
 61         }
 62 
 63         if(type instanceof ParameterizedType){
 64             ParameterizedType parameterizedType = (ParameterizedType)type;
 65             Type[] genericTypies = parameterizedType.getActualTypeArguments();
 66             entityClass = (Class<T>)genericTypies[0];
 67             idClass     = (Class<ID>)genericTypies[1];
 68         }
 69     }
 70 
 71     /**
 72      * 从strter-jpa里面取出entityManager
 73      */
 74     @Resource
 75     protected EntityManager entityManager;
 76 
 77     /* (non-Javadoc)
 78      * @see pw.lizi.base.BaseService#save(T)
 79      */
 80     @Override
 81     public void save(T entity){
 82         entityManager.persist(entity);
 83     }
 84 
 85     /* (non-Javadoc)
 86      * @see pw.lizi.base.BaseService#delete(T)
 87      */
 88     @Override
 89     public void delete(T entity){
 90         entityManager.remove(entity);
 91     }
 92 
 93     /* (non-Javadoc)
 94      * @see pw.lizi.base.BaseService#delete(java.io.Serializable)
 95      */
 96     @Override
 97     public int delete(Serializable id){
 98         Query query = entityManager.createQuery("DELETE FROM " + entityClass.getName() + " WHERE " + getIdField() + "=?");
 99         query.setParameter(0, id);
100         return query.executeUpdate();
101     }
102     
103     
104     /* (non-Javadoc)
105      * @see pw.lizi.base.BaseService#update(java.io.Serializable, java.util.LinkedHashMap)
106      */
107     @Override
108     public int update(Serializable id, LinkedHashMap<String, Object> values){
109         LinkedHashMap<String, Object> conditions = new LinkedHashMap<>();
110         conditions.put(getIdField(), id); //where uid=?
111         return updates(conditions, values);
112     }
113     
114     
115     /* (non-Javadoc)
116      * @see pw.lizi.base.BaseService#updates(java.util.LinkedHashMap, java.util.LinkedHashMap)
117      */
118     @Override
119     public int updates(LinkedHashMap<String, Object> conditions, LinkedHashMap<String, Object> values){
120         AssertUtil.notEmpty(values, "要更新的值不能空");
121         //update entityClass set field1=?,field2=?, where field1=? AND field2=? AND
122         StringBuilder jpql = new StringBuilder("UPDATE ").append(entityClass.getName()).append(" SET ");
123         for(Map.Entry<String, Object> v : values.entrySet()){
124             jpql.append(v.getKey()).append("=?,");
125         }
126         jpql.deleteCharAt(jpql.length() - 1);
127         
128         Collection<Object> params = new ArrayList<Object>();
129         params.addAll(values.values());
130         
131         if(conditions != null && conditions.size() > 0){
132             jpql.append(" WHERE ");
133             for(Map.Entry<String, Object> condition : conditions.entrySet()){
134                 jpql.append(condition.getKey()).append("=? AND ");
135             }
136             jpql.delete(jpql.length() - 5, jpql.length());
137             
138             params.addAll(conditions.values());
139         }
140         
141         log.debug("更新语句:" + jpql.toString());
142         
143         Query query = entityManager.createQuery(jpql.toString());
144         
145         int i = 0;
146         for (Object value : params) {
147             query.setParameter(++i, value);
148         }
149         
150         return query.executeUpdate();
151     }
152 
153     /* (non-Javadoc)
154      * @see pw.lizi.base.BaseService#findOne(java.io.Serializable)
155      */
156     @Override
157     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
158     public T findOne(Serializable id){
159         return entityManager.find(entityClass, id);
160     }
161     
162     
163     /* (non-Javadoc)
164      * @see pw.lizi.base.BaseService#finds()
165      */
166     @Override
167     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
168     public List<T> finds(){
169         return entityManager.createQuery("from " + entityClass.getName()).getResultList();
170     }
171     
172     /* (non-Javadoc)
173      * @see pw.lizi.base.BaseService#finds(java.util.LinkedHashMap)
174      */
175     @Override
176     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
177     public List<T> finds(Sort sort){
178         return finds(null, null, null, sort);
179     }
180     
181     /* (non-Javadoc)
182      * @see pw.lizi.base.BaseService#finds(pw.lizi.base.Page)
183      */
184     @Override
185     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
186     public List<T> finds(Page page){
187         return finds(null, null, page, null);
188     }
189     
190     /* (non-Javadoc)
191      * @see pw.lizi.base.BaseService#finds(pw.lizi.base.Page, java.util.LinkedHashMap)
192      */
193     @Override
194     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
195     public List<T> finds(Page page, Sort sort){
196         return finds(null, null, page, sort);
197     }
198     
199     /* (non-Javadoc)
200      * @see pw.lizi.base.BaseService#finds(java.util.LinkedHashMap, pw.lizi.base.Page, java.util.LinkedHashMap)
201      */
202     @Override
203     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
204     public List<T> finds(LinkedHashMap<String, Object> conditions, Page page, Sort sort){
205         return finds(null, conditions, page, sort);
206     }
207     
208     /* (non-Javadoc)
209      * @see pw.lizi.base.BaseService#finds(java.lang.String, java.util.LinkedHashMap, pw.lizi.base.Page, java.util.LinkedHashMap)
210      */
211     @Override
212     @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
213     public List<T> finds(String fields, LinkedHashMap<String, Object> conditions, Page page, Sort sort){
214         
215         //准备返回字段,如果没自定义就返回*
216         fields = StringUtil.hasLength(fields) ? "new " + entityClass.getName() + "(" + fields + ") " : "o ";
217         
218         //拼查询语句:select o.* from entityClass as o where f=v order by xxx
219         StringBuilder JPQL = new StringBuilder("SELECT ").append(fields).append(" FROM ").append(entityClass.getName()).append(" as o");
220         
221         //拼统计语句:select count(getIdField()) from entityClass where f=v 
222         StringBuilder countJPQL = new StringBuilder("SELECT count(o.").append(getIdField()).append(')')
223                 .append(" FROM ").append(entityClass.getName()).append(" as o");
224         
225         //拼条件
226         if(CollectionUtil.notEmpty(conditions)){
227             JPQL.append(" WHERE ");
228             countJPQL.append(" WHERE ");
229             
230             for(Map.Entry<String, Object> condition : conditions.entrySet()){
231                 JPQL.append("o.").append(condition.getKey()).append("=? AND ");
232                 countJPQL.append("o.").append(condition.getKey()).append("=? AND ");
233             }
234             JPQL.delete(JPQL.length() - 5, JPQL.length());
235             countJPQL.delete(JPQL.length() - 5, JPQL.length());
236         }
237         
238         /* 分页:只分第1页,后面的记录总页数就可以算出总记录数,从而不需要再统计
239          * (98条|100条)=总页面相等
240          * http://localhsot/news/list?pageIndex=2&pageCount=10
241          */
242         if(page != null && page.getTotalCount() == 0){
243             log.debug("统计语句:" + countJPQL.toString());
244             Query query = entityManager.createQuery(countJPQL.toString());
245             if(conditions != null){
246                 setParameter(query, conditions.values());
247             }
248             long count = (Long) query.getSingleResult();
249             page.setTotalCount((int)count);
250         }
251         
252         //排序
253         if(CollectionUtil.notEmpty(sort)){
254             JPQL.append(" ORDER BY ");
255             for(Map.Entry<String, Boolean> order : sort.entrySet()){
256                 JPQL.append("o.").append(order.getKey()).append(' ').append(order.getValue() ? "ASC" : "DESC").append(',');
257             }
258             JPQL.deleteCharAt(JPQL.length() - 1);
259         }
260         
261         log.debug("查询语句:" + JPQL.toString());
262         
263         //生成查询对象,绑定参数
264         Query query = entityManager.createQuery(JPQL.toString());
265         if(conditions != null){
266             setParameter(query, conditions.values());
267         }
268         
269         //设置分页 limit 50,10
270         query.setFirstResult(page.getOffset()).setMaxResults(page.getPageSize());
271         
272         //返回查询结果
273         List<T> result = query.getResultList();
274         
275         return result;
276     }
277     
278     //--------------------------------------------private-----------------------------------------
279 
280     private void setParameter(Query query, Collection<Object> params){
281         int i = 0;
282         for (Object object : params) {
283             query.setParameter(++i, object);//JPA是从1开始
284         }
285     }
286     
287     private String getIdField(){
288         
289         /*
290         //第1个bug:拿不到父类的field,除非父类的属性设为public
291         //第2个bug:如果注解是放在get方法上的,那还得要遍历方法
292         //第3个问题:性能较关
293         Field[] fields = entityClass.getDeclaredFields();
294         for (Field field : fields) {
295             Id id = field.getAnnotation(Id.class);
296             if(id != null){
297                 return field.getName();
298             }
299         }
300         */
301         
302         String idField = entityManager.getMetamodel().entity(entityClass).getId(idClass).getName();
303         
304         return idField;
305     }
306 }
  1 package pw.lizi.base;
  2 
  3 import java.io.Serializable;
  4 import java.util.LinkedHashMap;
  5 import java.util.List;
  6 
  7 
  8 /**
  9  * 说明:
 10  * 
 11  *
 12  * 2018年9月30日 上午9:07:42
 13  */
 14 public interface BaseService<T, ID> {
 15 
 16     /**
 17      * 功能说明:保存<br>
 18      * @param entity
 19      * void
 20      */
 21     public abstract void save(T entity);
 22 
 23     /**
 24      * 功能说明:删除实体<br>
 25      * @param entity
 26      * void
 27      */
 28     public abstract void delete(T entity);
 29 
 30     /**
 31      * 功能说明:根据ID删除<br>
 32      * @param id
 33      * void
 34      */
 35     public abstract int delete(Serializable id);
 36 
 37     /**
 38      * 功能说明:根据ID更新单条记录<br>
 39      * @param id
 40      * @param values
 41      * void
 42      */
 43     public abstract int update(Serializable id,
 44             LinkedHashMap<String, Object> values);
 45 
 46     /**
 47      * 功能说明:批量更新<br>
 48      * @param conditions
 49      * @param values
 50      * @return
 51      * int
 52      */
 53     public abstract int updates(LinkedHashMap<String, Object> conditions,
 54             LinkedHashMap<String, Object> values);
 55 
 56     public abstract T findOne(Serializable id);
 57 
 58     public abstract List<T> finds();
 59 
 60     /**
 61      * 功能说明:排序查询<br>
 62      * @param orders
 63      * @return
 64      * List<T>
 65      */
 66     public abstract List<T> finds(Sort sort);
 67 
 68     /**
 69      * 功能说明:分页查询<br>
 70      * @param page
 71      * @return
 72      * List<T>
 73      */
 74     public abstract List<T> finds(Page page);
 75 
 76     /**
 77      * 功能说明:分页排序查询<br>
 78      * @param page
 79      * @param orders
 80      * @return
 81      * List<T>
 82      */
 83     public abstract List<T> finds(Page page, Sort sort);
 84 
 85     /**
 86      * 功能说明:分页排序多条件查询<br>
 87      * @param conditions
 88      * @param page
 89      * @param orders
 90      * @return
 91      * List<T>
 92      */
 93     public abstract List<T> finds(LinkedHashMap<String, Object> conditions,     Page page, Sort sort);
 94 
 95     /**
 96      * 功能说明:分页排序多条件,且可自定义字段查询<br>
 97      * @param fields
 98      * @param conditions
 99      * @param page
100      * @param orders
101      * @return
102      * List<T>
103      */
104     public abstract List<T> finds(String fields, LinkedHashMap<String, Object> conditions, Page page, Sort sort);
105 
106 }
 1 /**
 2  * 
 3  */
 4 package pw.lizi.base;
 5 
 6 import java.io.Serializable;
 7 
 8 /**
 9  * 说明:
10  * 
11  *
12  * 2018年9月30日 上午8:15:31
13  */
14 public class Page implements Serializable {
15 
16     private static final long serialVersionUID = 1L;
17 
18     private int pageIndex = 1;
19     
20     private int pageSize;
21     
22     private int totalCount;
23 
24     
25     public Page(int pageIndex, int pageSize) {
26         super();
27         this.pageIndex = pageIndex;
28         this.pageSize = pageSize;
29     }
30 
31     public int getOffset(){
32         return (this.getPageIndex() - 1 ) * this.getPageSize();
33     }
34     
35     public int getPageIndex() {
36         return pageIndex;
37     }
38 
39     public void setPageIndex(int pageIndex) {
40         this.pageIndex = pageIndex;
41     }
42 
43     public int getPageSize() {
44         return pageSize;
45     }
46 
47     public void setPageSize(int pageSize) {
48         this.pageSize = pageSize;
49     }
50 
51     public int getTotalCount() {
52         return totalCount;
53     }
54 
55     public void setTotalCount(int totalCount) {
56         this.totalCount = totalCount;
57     }
58     
59     
60 }
 1 /**
 2  * 
 3  */
 4 package pw.lizi.base;
 5 
 6 import java.util.LinkedHashMap;
 7 
 8 /**
 9  * 说明:
10  * 
11  *
12  * 2018年9月30日 上午9:38:02
13  */
14 public class Sort extends LinkedHashMap<String, Boolean> {
15 
16     private static final long serialVersionUID = 1L;
17 
18     public Sort(String field, boolean asc){
19         put(field, asc);
20     }
21     
22     public Sort add(String field, boolean asc){
23         put(field, asc);
24         return this;
25     }
26     public static Sort newInstance(String field, boolean asc){
27         Sort sort = new Sort(field, asc);
28         return sort;
29     }
30 }
sort
原文地址:https://www.cnblogs.com/wangdaxianer/p/9728284.html