HibernateDao.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. /**
  2. * Copyright (c) 2005-2011 springside.org.cn
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. *
  6. * $Id: HibernateDao.java 1547 2011-05-05 14:43:07Z calvinxiu $
  7. */
  8. package com.key.common.dao;
  9. import java.io.Serializable;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.regex.Matcher;
  14. import java.util.regex.Pattern;
  15. import com.key.common.plugs.page.PageRequest;
  16. import org.hibernate.Criteria;
  17. import org.hibernate.Query;
  18. import org.hibernate.criterion.CriteriaSpecification;
  19. import org.hibernate.criterion.Criterion;
  20. import org.hibernate.criterion.Disjunction;
  21. import org.hibernate.criterion.MatchMode;
  22. import org.hibernate.criterion.Order;
  23. import org.hibernate.criterion.Projection;
  24. import org.hibernate.criterion.Projections;
  25. import org.hibernate.criterion.Restrictions;
  26. import org.hibernate.impl.CriteriaImpl;
  27. import org.hibernate.transform.ResultTransformer;
  28. import com.key.common.plugs.page.Page;
  29. import com.key.common.plugs.page.PropertyFilter;
  30. import com.key.common.plugs.page.PropertyFilter.MatchType;
  31. import com.key.common.utils.AssertUtils;
  32. import com.key.common.utils.ReflectionUtils;
  33. /**
  34. * 封装SpringSide扩展功能的Hibernat DAO泛型基类.
  35. *
  36. * 扩展功能包括分页查询,按属性过滤条件列表查询.
  37. *
  38. * @param <T> DAO操作的对象类型
  39. * @param <ID> 主键类型
  40. *
  41. */
  42. public class HibernateDao<T, ID extends Serializable> extends SimpleHibernateDao<T, ID> implements IHibernateDao<T, ID> {
  43. /**
  44. * 通过子类的泛型定义取得对象类型Class.
  45. * eg.
  46. * public class UserDao extends HibernateDao<User, Long>{
  47. * }
  48. */
  49. public HibernateDao() {
  50. super();
  51. }
  52. public HibernateDao(Class<T> entityClass) {
  53. super(entityClass);
  54. }
  55. //-- 分页查询函数 --//
  56. /* (non-Javadoc)
  57. * @see com.key.common.orm.hibernate.IHibernateDao#getAll(com.key.common.orm.PageRequest)
  58. */
  59. @Override
  60. public Page<T> getAll(final PageRequest pageRequest) {
  61. return findPage(pageRequest);
  62. }
  63. /* (non-Javadoc)
  64. * @see com.key.common.orm.hibernate.IHibernateDao#findPage(com.key.common.orm.PageRequest, java.lang.String, java.lang.Object)
  65. */
  66. @Override
  67. public Page<T> findPage(final PageRequest pageRequest, String hql, final Object... values) {
  68. AssertUtils.notNull(pageRequest, "pageRequest不能为空");
  69. Page<T> page = new Page<T>(pageRequest);
  70. if (pageRequest.isCountTotal()) {
  71. long totalCount = countHqlResult(hql, values);
  72. page.setTotalItems(totalCount);
  73. }
  74. if (pageRequest.isOrderBySetted()) {
  75. hql = setOrderParameterToHql(hql, pageRequest);
  76. }
  77. Query q = createQuery(hql, values);
  78. setPageParameterToQuery(q, pageRequest);
  79. List result = q.list();
  80. page.setResult(result);
  81. return page;
  82. }
  83. /* (non-Javadoc)
  84. * @see com.key.common.orm.hibernate.IHibernateDao#findPage(com.key.common.orm.PageRequest, java.lang.String)
  85. */
  86. @Override
  87. public Page<T> findPage(final PageRequest pageRequest, String hql) {
  88. AssertUtils.notNull(pageRequest, "pageRequest不能为空");
  89. Page<T> page = new Page<T>(pageRequest);
  90. if (pageRequest.isCountTotal()) {
  91. long totalCount = countHqlResult(hql);
  92. page.setTotalItems(totalCount);
  93. }
  94. if (pageRequest.isOrderBySetted()) {
  95. hql = setOrderParameterToHql(hql, pageRequest);
  96. }
  97. Query q = createQuery(hql);
  98. setPageParameterToQuery(q, pageRequest);
  99. List result = q.list();
  100. page.setResult(result);
  101. return page;
  102. }
  103. /* (non-Javadoc)
  104. * @see com.key.common.orm.hibernate.IHibernateDao#findPage(com.key.common.orm.PageRequest, java.lang.String, java.util.Map)
  105. */
  106. @Override
  107. public Page<T> findPage(final PageRequest pageRequest, String hql, final Map<String, ?> values) {
  108. AssertUtils.notNull(pageRequest, "page不能为空");
  109. Page<T> page = new Page<T>(pageRequest);
  110. if (pageRequest.isCountTotal()) {
  111. long totalCount = countHqlResult(hql, values);
  112. page.setTotalItems(totalCount);
  113. }
  114. if (pageRequest.isOrderBySetted()) {
  115. hql = setOrderParameterToHql(hql, pageRequest);
  116. }
  117. Query q = createQuery(hql, values);
  118. setPageParameterToQuery(q, pageRequest);
  119. List result = q.list();
  120. page.setResult(result);
  121. return page;
  122. }
  123. /* (non-Javadoc)
  124. * @see com.key.common.orm.hibernate.IHibernateDao#findPage(com.key.common.orm.PageRequest, org.hibernate.criterion.Criterion)
  125. */
  126. @Override
  127. public Page<T> findPage(final PageRequest pageRequest, final Criterion... criterions) {
  128. AssertUtils.notNull(pageRequest, "page不能为空");
  129. Page<T> page = new Page<T>(pageRequest);
  130. Criteria c = createCriteria(criterions);
  131. if (pageRequest.isCountTotal()) {
  132. long totalCount = countCriteriaResult(c);
  133. page.setTotalItems(totalCount);
  134. pageRequest.setTotalPage(page.getTotalPage());
  135. }
  136. if(pageRequest.isIslastpage()){
  137. pageRequest.setPageNo(pageRequest.getTotalPage());
  138. page.setPageNo(pageRequest.getPageNo());
  139. }
  140. setPageRequestToCriteria(c, pageRequest);
  141. List result = c.list();
  142. page.setResult(result);
  143. return page;
  144. }
  145. /**
  146. * 在HQL的后面添加分页参数定义的orderBy, 辅助函数.
  147. */
  148. protected String setOrderParameterToHql(final String hql, final PageRequest pageRequest) {
  149. StringBuilder builder = new StringBuilder(hql);
  150. builder.append(" order by");
  151. for (PageRequest.Sort orderBy : pageRequest.getSort()) {
  152. builder.append(String.format(" %s.%s %s,", DEFAULT_ALIAS, orderBy.getProperty(), orderBy.getDir()));
  153. }
  154. builder.deleteCharAt(builder.length() - 1);
  155. return builder.toString();
  156. }
  157. /**
  158. * 设置分页参数到Query对象,辅助函数.
  159. */
  160. protected Query setPageParameterToQuery(final Query q, final PageRequest pageRequest) {
  161. q.setFirstResult(pageRequest.getOffset());
  162. q.setMaxResults(pageRequest.getPageSize());
  163. return q;
  164. }
  165. /**
  166. * 设置分页参数到Criteria对象,辅助函数.
  167. */
  168. protected Criteria setPageRequestToCriteria(final Criteria c, final PageRequest pageRequest) {
  169. AssertUtils.isTrue(pageRequest.getPageSize() > 0, "Page Size must larger than zero");
  170. c.setFirstResult(pageRequest.getOffset());
  171. c.setMaxResults(pageRequest.getPageSize());
  172. if (pageRequest.isOrderBySetted()) {
  173. for (PageRequest.Sort sort : pageRequest.getSort()) {
  174. if (PageRequest.Sort.ASC.equals(sort.getDir())) {
  175. c.addOrder(Order.asc(sort.getProperty()));
  176. } else {
  177. c.addOrder(Order.desc(sort.getProperty()));
  178. }
  179. }
  180. }
  181. return c;
  182. }
  183. /**
  184. * 执行count查询获得本次Hql查询所能获得的对象总数.
  185. *
  186. * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
  187. */
  188. protected long countHqlResult(final String hql, final Object... values) {
  189. String countHql = prepareCountHql(hql);
  190. try {
  191. Long count = findUnique(countHql, values);
  192. return count;
  193. } catch (Exception e) {
  194. throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e);
  195. }
  196. }
  197. /**
  198. * 执行count查询获得本次Hql查询所能获得的对象总数.
  199. *
  200. * 本函数只能自动处理简单的hql语句,复杂的hql查询请另行编写count语句查询.
  201. */
  202. protected long countHqlResult(final String hql, final Map<String, ?> values) {
  203. String countHql = prepareCountHql(hql);
  204. try {
  205. Long count = findUnique(countHql, values);
  206. return count;
  207. } catch (Exception e) {
  208. throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e);
  209. }
  210. }
  211. private String prepareCountHql(String orgHql) {
  212. String countHql = "select count (*) " + removeSelect(removeOrders(orgHql));
  213. return countHql;
  214. }
  215. private static String removeSelect(String hql) {
  216. int beginPos = hql.toLowerCase().indexOf("from");
  217. return hql.substring(beginPos);
  218. }
  219. private static String removeOrders(String hql) {
  220. Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
  221. Matcher m = p.matcher(hql);
  222. StringBuffer sb = new StringBuffer();
  223. while (m.find()) {
  224. m.appendReplacement(sb, "");
  225. }
  226. m.appendTail(sb);
  227. return sb.toString();
  228. }
  229. /**
  230. * 执行count查询获得本次Criteria查询所能获得的对象总数.
  231. */
  232. protected long countCriteriaResult(final Criteria c) {
  233. CriteriaImpl impl = (CriteriaImpl) c;
  234. // 先把Projection、ResultTransformer、OrderBy取出来,清空三者后再执行Count操作
  235. Projection projection = impl.getProjection();
  236. ResultTransformer transformer = impl.getResultTransformer();
  237. List<CriteriaImpl.OrderEntry> orderEntries = null;
  238. try {
  239. orderEntries = (List) ReflectionUtils.getFieldValue(impl, "orderEntries");
  240. ReflectionUtils.setFieldValue(impl, "orderEntries", new ArrayList());
  241. } catch (Exception e) {
  242. logger.error("不可能抛出的异常:{}", e.getMessage());
  243. }
  244. // 执行Count查询
  245. Long totalCountObject = (Long) c.setProjection(Projections.rowCount()).uniqueResult();
  246. long totalCount = (totalCountObject != null) ? totalCountObject : 0;
  247. // 将之前的Projection,ResultTransformer和OrderBy条件重新设回去
  248. c.setProjection(projection);
  249. if (projection == null) {
  250. c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
  251. }
  252. if (transformer != null) {
  253. c.setResultTransformer(transformer);
  254. }
  255. try {
  256. ReflectionUtils.setFieldValue(impl, "orderEntries", orderEntries);
  257. } catch (Exception e) {
  258. logger.error("不可能抛出的异常:{}", e.getMessage());
  259. }
  260. return totalCount;
  261. }
  262. //-- 属性过滤条件(PropertyFilter)查询函数 --//
  263. /* (non-Javadoc)
  264. * @see com.key.common.orm.hibernate.IHibernateDao#findBy(java.lang.String, java.lang.Object, com.key.common.orm.PropertyFilter.MatchType)
  265. */
  266. @Override
  267. public List<T> findBy(final String propertyName, final Object value, final MatchType matchType) {
  268. Criterion criterion = buildCriterion(propertyName, value, matchType);
  269. return find(criterion);
  270. }
  271. /* (non-Javadoc)
  272. * @see com.key.common.orm.hibernate.IHibernateDao#find(java.util.List)
  273. */
  274. @Override
  275. public List<T> find(List<PropertyFilter> filters) {
  276. Criterion[] criterions = buildCriterionByPropertyFilter(filters);
  277. return find(criterions);
  278. }
  279. /* (non-Javadoc)
  280. * @see com.key.common.orm.hibernate.IHibernateDao#findPage(com.key.common.orm.PageRequest, java.util.List)
  281. */
  282. @Override
  283. public Page<T> findPage(final PageRequest pageRequest, final List<PropertyFilter> filters) {
  284. Criterion[] criterions = buildCriterionByPropertyFilter(filters);
  285. return findPage(pageRequest, criterions);
  286. }
  287. /**
  288. * 按属性条件参数创建Criterion,辅助函数.
  289. */
  290. protected Criterion buildCriterion(final String propertyName, final Object propertyValue, final MatchType matchType) {
  291. AssertUtils.hasText(propertyName, "propertyName不能为空");
  292. Criterion criterion = null;
  293. //根据MatchType构造criterion
  294. switch (matchType) {
  295. case EQ:
  296. criterion = Restrictions.eq(propertyName, propertyValue);
  297. break;
  298. case LIKE:
  299. criterion = Restrictions.like(propertyName, (String) propertyValue, MatchMode.ANYWHERE);
  300. break;
  301. case LE:
  302. criterion = Restrictions.le(propertyName, propertyValue);
  303. break;
  304. case LT:
  305. criterion = Restrictions.lt(propertyName, propertyValue);
  306. break;
  307. case GE:
  308. criterion = Restrictions.ge(propertyName, propertyValue);
  309. break;
  310. case GT:
  311. criterion = Restrictions.gt(propertyName, propertyValue);
  312. break;
  313. case NE:
  314. criterion = Restrictions.ne(propertyName, propertyValue);
  315. }
  316. return criterion;
  317. }
  318. /**
  319. * 按属性条件列表创建Criterion数组,辅助函数.
  320. */
  321. protected Criterion[] buildCriterionByPropertyFilter(final List<PropertyFilter> filters) {
  322. List<Criterion> criterionList = new ArrayList<Criterion>();
  323. for (PropertyFilter filter : filters) {
  324. if (!filter.hasMultiProperties()) { //只有一个属性需要比较的情况.
  325. Criterion criterion = buildCriterion(filter.getPropertyName(), filter.getMatchValue(),
  326. filter.getMatchType());
  327. criterionList.add(criterion);
  328. } else {//包含多个属性需要比较的情况,进行or处理.
  329. Disjunction disjunction = Restrictions.disjunction();
  330. for (String param : filter.getPropertyNames()) {
  331. Criterion criterion = buildCriterion(param, filter.getMatchValue(), filter.getMatchType());
  332. disjunction.add(criterion);
  333. }
  334. criterionList.add(disjunction);
  335. }
  336. }
  337. return criterionList.toArray(new Criterion[criterionList.size()]);
  338. }
  339. /* (non-Javadoc)
  340. * @see com.key.common.orm.hibernate.IHibernateDao#findAll(com.key.common.orm.PageRequest, java.util.List)
  341. */
  342. @Override
  343. public List<T> findAll(final PageRequest pageRequest, final List<PropertyFilter> filters) {
  344. Criterion[] criterions = buildCriterionByPropertyFilter(filters);
  345. Criteria c = createCriteria(criterions);
  346. if (pageRequest.isOrderBySetted()) {
  347. for (PageRequest.Sort sort : pageRequest.getSort()) {
  348. if (PageRequest.Sort.ASC.equals(sort.getDir())) {
  349. c.addOrder(Order.asc(sort.getProperty()));
  350. } else {
  351. c.addOrder(Order.desc(sort.getProperty()));
  352. }
  353. }
  354. }
  355. return c.list();
  356. }
  357. @Override
  358. public T getModel(ID id) {
  359. T t = null;
  360. try {
  361. if (id != null && !"".equals(id)) {
  362. t = get(id);
  363. }
  364. if (t == null) {
  365. t = entityClass.newInstance();
  366. }
  367. } catch (InstantiationException e) {
  368. // TODO Auto-generated catch block
  369. e.printStackTrace();
  370. } catch (IllegalAccessException e) {
  371. // TODO Auto-generated catch block
  372. e.printStackTrace();
  373. }
  374. return t;
  375. }
  376. @Override
  377. public List<T> find(String orderByProperty, boolean isAsc,
  378. Criterion... criterions) {
  379. Criteria c = createCriteria(criterions);
  380. if (isAsc) {
  381. c.addOrder(Order.asc(orderByProperty));
  382. } else {
  383. c.addOrder(Order.desc(orderByProperty));
  384. }
  385. return c.list();
  386. }
  387. @Override
  388. public T findFirst(String orderByProperty, boolean isAsc,
  389. Criterion... criterions) {
  390. Criteria c = createCriteria(criterions);
  391. if (isAsc) {
  392. c.addOrder(Order.asc(orderByProperty));
  393. } else {
  394. c.addOrder(Order.desc(orderByProperty));
  395. }
  396. c.setMaxResults(1);
  397. return (T) c.uniqueResult();
  398. }
  399. @Override
  400. public T findFirst(String orderByProperty, boolean isAsc,
  401. List<Criterion> criterions) {
  402. Criteria c = createCriteria(criterions);
  403. if (isAsc) {
  404. c.addOrder(Order.asc(orderByProperty));
  405. } else {
  406. c.addOrder(Order.desc(orderByProperty));
  407. }
  408. c.setMaxResults(1);
  409. return (T) c.uniqueResult();
  410. }
  411. @Override
  412. public Object findUniObjs(String hql,Object... values ) {
  413. Query q = createQuery(hql, values);
  414. return q.uniqueResult();
  415. }
  416. @Override
  417. public List<Object[]> findList(String hql, Object... values) {
  418. Query q = createQuery(hql, values);
  419. return q.list();
  420. }
  421. @Override
  422. public T findFirst(Criterion... criterions) {
  423. Criteria c = createCriteria(criterions);
  424. c.setMaxResults(1);
  425. return (T) c.uniqueResult();
  426. }
  427. public T findFirst(List<Criterion> criterions) {
  428. Criteria c = createCriteria(criterions);
  429. c.setMaxResults(1);
  430. return (T) c.uniqueResult();
  431. }
  432. @Override
  433. public Page<T> findPageList(PageRequest pageRequest,
  434. List<Criterion> criterions) {
  435. if(criterions!=null && criterions.size()>0){
  436. Criteria c = createCriteria(criterions);
  437. return findPageCriteria(pageRequest, c);
  438. }
  439. return findPage(pageRequest);
  440. }
  441. public Page<T> findPageCriteria(PageRequest pageRequest,Criteria c){
  442. Page<T> page = new Page<T>(pageRequest);
  443. if (pageRequest.isCountTotal()) {
  444. long totalCount = countCriteriaResult(c);
  445. page.setTotalItems(totalCount);
  446. pageRequest.setTotalPage(page.getTotalPage());
  447. }
  448. if(pageRequest.isIslastpage()){
  449. pageRequest.setPageNo(pageRequest.getTotalPage());
  450. page.setPageNo(pageRequest.getPageNo());
  451. }
  452. setPageRequestToCriteria(c, pageRequest);
  453. List result = c.list();
  454. page.setResult(result);
  455. return page;
  456. }
  457. public Page<T> findPageByCri(Page<T> pageRequest, List<Criterion> criterions){
  458. Criteria c = createCriteria(criterions);
  459. Page<T> page = new Page<T>(pageRequest);
  460. if (pageRequest.isCountTotal()) {
  461. long totalCount = countCriteriaResult(c);
  462. page.setTotalItems(totalCount);
  463. pageRequest.setTotalPage(page.getTotalPage());
  464. }
  465. if(pageRequest.isIslastpage()){
  466. pageRequest.setPageNo(pageRequest.getTotalPage());
  467. page.setPageNo(pageRequest.getPageNo());
  468. }
  469. setPageRequestToCriteria(c, pageRequest);
  470. List result = c.list();
  471. page.setResult(result);
  472. return page;
  473. }
  474. }