- 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