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

 

  1. 1 package pw.lizi.base;
  2. 2
  3. 3 import java.io.Serializable;
  4. 4 import java.util.LinkedHashMap;
  5. 5 import java.util.List;
  6. 6
  7. 7
  8. 8 /**
  9. 9 * 说明:
  10. 10 *
  11. 11 *
  12. 12 * 2018年9月30日 上午9:07:42
  13. 13 */
  14. 14 public interface BaseService<T, ID> {
  15. 15
  16. 16 /**
  17. 17 * 功能说明:保存<br>
  18. 18 * @param entity
  19. 19 * void
  20. 20 */
  21. 21 public abstract void save(T entity);
  22. 22
  23. 23 /**
  24. 24 * 功能说明:删除实体<br>
  25. 25 * @param entity
  26. 26 * void
  27. 27 */
  28. 28 public abstract void delete(T entity);
  29. 29
  30. 30 /**
  31. 31 * 功能说明:根据ID删除<br>
  32. 32 * @param id
  33. 33 * void
  34. 34 */
  35. 35 public abstract int delete(Serializable id);
  36. 36
  37. 37 /**
  38. 38 * 功能说明:根据ID更新单条记录<br>
  39. 39 * @param id
  40. 40 * @param values
  41. 41 * void
  42. 42 */
  43. 43 public abstract int update(Serializable id,
  44. 44 LinkedHashMap<String, Object> values);
  45. 45
  46. 46 /**
  47. 47 * 功能说明:批量更新<br>
  48. 48 * @param conditions
  49. 49 * @param values
  50. 50 * @return
  51. 51 * int
  52. 52 */
  53. 53 public abstract int updates(LinkedHashMap<String, Object> conditions,
  54. 54 LinkedHashMap<String, Object> values);
  55. 55
  56. 56 public abstract T findOne(Serializable id);
  57. 57
  58. 58 public abstract List<T> finds();
  59. 59
  60. 60 /**
  61. 61 * 功能说明:排序查询<br>
  62. 62 * @param orders
  63. 63 * @return
  64. 64 * List<T>
  65. 65 */
  66. 66 public abstract List<T> finds(Sort sort);
  67. 67
  68. 68 /**
  69. 69 * 功能说明:分页查询<br>
  70. 70 * @param page
  71. 71 * @return
  72. 72 * List<T>
  73. 73 */
  74. 74 public abstract List<T> finds(Page page);
  75. 75
  76. 76 /**
  77. 77 * 功能说明:分页排序查询<br>
  78. 78 * @param page
  79. 79 * @param orders
  80. 80 * @return
  81. 81 * List<T>
  82. 82 */
  83. 83 public abstract List<T> finds(Page page, Sort sort);
  84. 84
  85. 85 /**
  86. 86 * 功能说明:分页排序多条件查询<br>
  87. 87 * @param conditions
  88. 88 * @param page
  89. 89 * @param orders
  90. 90 * @return
  91. 91 * List<T>
  92. 92 */
  93. 93 public abstract List<T> finds(LinkedHashMap<String, Object> conditions, Page page, Sort sort);
  94. 94
  95. 95 /**
  96. 96 * 功能说明:分页排序多条件,且可自定义字段查询<br>
  97. 97 * @param fields
  98. 98 * @param conditions
  99. 99 * @param page
  100. 100 * @param orders
  101. 101 * @return
  102. 102 * List<T>
  103. 103 */
  104. 104 public abstract List<T> finds(String fields, LinkedHashMap<String, Object> conditions, Page page, Sort sort);
  105. 105
  106. 106 }
  1. 1 /**
  2. 2 *
  3. 3 */
  4. 4 package pw.lizi.base;
  5. 5
  6. 6 import java.io.Serializable;
  7. 7
  8. 8 /**
  9. 9 * 说明:
  10. 10 *
  11. 11 *
  12. 12 * 2018年9月30日 上午8:15:31
  13. 13 */
  14. 14 public class Page implements Serializable {
  15. 15
  16. 16 private static final long serialVersionUID = 1L;
  17. 17
  18. 18 private int pageIndex = 1;
  19. 19
  20. 20 private int pageSize;
  21. 21
  22. 22 private int totalCount;
  23. 23
  24. 24
  25. 25 public Page(int pageIndex, int pageSize) {
  26. 26 super();
  27. 27 this.pageIndex = pageIndex;
  28. 28 this.pageSize = pageSize;
  29. 29 }
  30. 30
  31. 31 public int getOffset(){
  32. 32 return (this.getPageIndex() - 1 ) * this.getPageSize();
  33. 33 }
  34. 34
  35. 35 public int getPageIndex() {
  36. 36 return pageIndex;
  37. 37 }
  38. 38
  39. 39 public void setPageIndex(int pageIndex) {
  40. 40 this.pageIndex = pageIndex;
  41. 41 }
  42. 42
  43. 43 public int getPageSize() {
  44. 44 return pageSize;
  45. 45 }
  46. 46
  47. 47 public void setPageSize(int pageSize) {
  48. 48 this.pageSize = pageSize;
  49. 49 }
  50. 50
  51. 51 public int getTotalCount() {
  52. 52 return totalCount;
  53. 53 }
  54. 54
  55. 55 public void setTotalCount(int totalCount) {
  56. 56 this.totalCount = totalCount;
  57. 57 }
  58. 58
  59. 59
  60. 60 }

 

  1. 1 /**
  2. 2 *
  3. 3 */
  4. 4 package pw.lizi.base;
  5. 5
  6. 6 import java.util.LinkedHashMap;
  7. 7
  8. 8 /**
  9. 9 * 说明:
  10. 10 *
  11. 11 *
  12. 12 * 2018年9月30日 上午9:38:02
  13. 13 */
  14. 14 public class Sort extends LinkedHashMap<String, Boolean> {
  15. 15
  16. 16 private static final long serialVersionUID = 1L;
  17. 17
  18. 18 public Sort(String field, boolean asc){
  19. 19 put(field, asc);
  20. 20 }
  21. 21
  22. 22 public Sort add(String field, boolean asc){
  23. 23 put(field, asc);
  24. 24 return this;
  25. 25 }
  26. 26 public static Sort newInstance(String field, boolean asc){
  27. 27 Sort sort = new Sort(field, asc);
  28. 28 return sort;
  29. 29 }
  30. 30 }
sort

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号