zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    mssql分页原理及效率分析
    [ActiveX]使用VS2010创建MFC ActiveX工程项目
    Study notes for Discrete Probability Distribution
    oracle存储过程异常捕获
    (Python学习9)Python虚拟机中的一般表达式
    用Arduino做一个可视化网络威胁级别指示器!
    iOS上线项目源码分享
    android实习程序6——拨号通话
    评价等级使用的五星选择,包含半星的选择
    AJAX实现无刷新验证用户名
  • 原文地址:https://www.cnblogs.com/wangdaxianer/p/9728284.html
Copyright © 2011-2022 走看看