Java SSH Hibernate中查询的方法小结

  1. 具有一个直观的、可扩展的条件查询API是Hibernate的特色。
  2. 15.1.创建一个Criteria实例
  3. org.hibernate.Criteria接口表示特定持久类的一个查询。Session是Criteria实例的工厂。
  4. Criteriacrit=sess.createCriteria(Cat.class);
  5. crit.setMaxResults(50);
  6. Listcats=crit.list();
  7. 15.2.限制结果集内容
  8. 一个单独的查询条件是org.hibernate.criterion.Criterion接口的一个实例。org.hibernate.criterion.Restrictions类定义了获得某些内置Criterion类型的工厂方法。
  9. Listcats=sess.createCriteria(Cat.class)
  10. .add(Restrictions.like("name","Fritz%"))
  11. .add(Restrictions.between("weight",minWeight,maxWeight))
  12. .list();
  13. 约束可以按逻辑分组。
  14. Listcats=sess.createCriteria(Cat.class)
  15. .add(Restrictions.like("name","Fritz%"))
  16. .add(Restrictions.or(
  17. Restrictions.eq("age",newInteger(0)),
  18. Restrictions.isNull("age")
  19. ))
  20. .list();
  21. Listcats=sess.createCriteria(Cat.class)
  22. .add(Restrictions.in("name",newString[]{"Fritz","Izi","Pk"}))
  23. .add(Restrictions.disjunction()
  24. .add(Restrictions.isNull("age"))
  25. .add(Restrictions.eq("age",newInteger(0)))
  26. .add(Restrictions.eq("age",newInteger(1)))
  27. .add(Restrictions.eq("age",newInteger(2)))
  28. ))
  29. .list();
  30. Hibernate提供了相当多的内置criterion类型(Restrictions子类),但是尤其有用的是可以允许你直接使用SQL。
  31. Listcats=sess.createCriteria(Cat.class)
  32. .add(Restrictions.sql("lower({alias}.name)likelower(?)","Fritz%",Hibernate.STRING))
  33. .list();
  34. {alias}占位符应当被替换为被查询实体的列别名。
  35. Property实例是获得一个条件的另外一种途径。你可以通过调用Property.forName()创建一个Property。
  36. Propertyage=Property.forName("age");
  37. Listcats=sess.createCriteria(Cat.class)
  38. .add(Restrictions.disjunction()
  39. .add(age.isNull())
  40. .add(age.eq(newInteger(0)))
  41. .add(age.eq(newInteger(1)))
  42. .add(age.eq(newInteger(2)))
  43. ))
  44. .add(Property.forName("name").in(newString[]{"Fritz","Izi","Pk"}))
  45. .list();
  46. 15.3.结果集排序
  47. 你可以使用org.hibernate.criterion.Order来为查询结果排序。
  48. Listcats=sess.createCriteria(Cat.class)
  49. .add(Restrictions.like("name","F%")
  50. .addOrder(Order.asc("name"))
  51. .addOrder(Order.desc("age"))
  52. .setMaxResults(50)
  53. .list();
  54. Listcats=sess.createCriteria(Cat.class)
  55. .add(Property.forName("name").like("F%"))
  56. .addOrder(Property.forName("name").asc())
  57. .addOrder(Property.forName("age").desc())
  58. .setMaxResults(50)
  59. .list();
  60. 15.4.关联
  61. 你可以使用createCriteria()非常容易的在互相关联的实体间建立约束。
  62. Listcats=sess.createCriteria(Cat.class)
  63. .add(Restrictions.like("name","F%")
  64. .createCriteria("kittens")
  65. .add(Restrictions.like("name","F%")
  66. .list();
  67. 注意第二个createCriteria()返回一个新的Criteria实例,该实例引用kittens集合中的元素。
  68. 接下来,替换形态在某些情况下也是很有用的。
  69. Listcats=sess.createCriteria(Cat.class)
  70. .createAlias("kittens","kt")
  71. .createAlias("mate","mt")
  72. .add(Restrictions.eqProperty("kt.name","mt.name"))
  73. .list();
  74. (createAlias()并不创建一个新的Criteria实例。)
  75. Cat实例所保存的之前两次查询所返回的kittens集合是没有被条件预过滤的。如果你希望只获得符合条件的kittens,你必须使用returnMaps()。
  76. Listcats=sess.createCriteria(Cat.class)
  77. .createCriteria("kittens","kt")
  78. .add(Restrictions.eq("name","F%"))
  79. .returnMaps()
  80. .list();
  81. Iteratoriter=cats.iterator();
  82. while(iter.hasNext()){
  83. Mapmap=(Map)iter.next();
  84. Catcat=(Cat)map.get(Criteria.ROOT_ALIAS);
  85. Catkitten=(Cat)map.get("kt");
  86. }
  87. 15.5.动态关联抓取
  88. 你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
  89. Listcats=sess.createCriteria(Cat.class)
  90. .add(Restrictions.like("name","Fritz%"))
  91. .setFetchMode("mate",FetchMode.EAGER)
  92. .setFetchMode("kittens",FetchMode.EAGER)
  93. .list();
  94. 这个查询可以通过外连接抓取mate和kittens。查看第19.1节“抓取策略(Fetchingstrategies)”可以获得更多信息。
  95. 15.6.查询示例
  96. org.hibernate.criterion.Example类允许你通过一个给定实例构建一个条件查询。
  97. Catcat=newCat();
  98. cat.setSex('F');
  99. cat.setColor(Color.BLACK);
  100. Listresults=session.createCriteria(Cat.class)
  101. .add(Example.create(cat))
  102. .list();
  103. 版本属性、标识符和关联被忽略。默认情况下值为null的属性将被排除。
  104. 你可以自行调整Example使之更实用。
  105. Exampleexample=Example.create(cat)
  106. .excludeZeroes()//excludezerovaluedproperties
  107. .excludeProperty("color")//excludethepropertynamed"color"
  108. .ignoreCase()//performcaseinsensitivestringcomparisons
  109. .enableLike();//uselikeforstringcomparisons
  110. Listresults=session.createCriteria(Cat.class)
  111. .add(example)
  112. .list();
  113. 你甚至可以使用examples在关联对象上放置条件。
  114. Listresults=session.createCriteria(Cat.class)
  115. .add(Example.create(cat))
  116. .createCriteria("mate")
  117. .add(Example.create(cat.getMate()))
  118. .list();
  119. 15.7.投影(Projections)、聚合(aggregation)和分组(grouping)
  120. org.hibernate.criterion.Projections是Projection的实例工厂。我们通过调用setProjection()应用投影到一个查询。
  121. Listresults=session.createCriteria(Cat.class)
  122. .setProjection(Projections.rowCount())
  123. .add(Restrictions.eq("color",Color.BLACK))
  124. .list();
  125. Listresults=session.createCriteria(Cat.class)
  126. .setProjection(Projections.projectionList()
  127. .add(Projections.rowCount())
  128. .add(Projections.avg("weight"))
  129. .add(Projections.max("weight"))
  130. .add(Projections.groupProperty("color"))
  131. )
  132. .list();
  133. 在一个条件查询中没有必要显式的使用"groupby"。某些投影类型就是被定义为分组投影,他们也出现在SQL的groupby子句中。
  134. 你可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式:
  135. Listresults=session.createCriteria(Cat.class)
  136. .setProjection(Projections.alias(Projections.groupProperty("color"),"colr"))
  137. .addOrder(Order.asc("colr"))
  138. .list();
  139. Listresults=session.createCriteria(Cat.class)
  140. .setProjection(Projections.groupProperty("color").as("colr"))
  141. .addOrder(Order.asc("colr"))
  142. .list();
  143. alias()和as()方法简便的将一个投影实例包装到另外一个别名的Projection实例中。简而言之,当你添加一个投影到一个投影列表中时你可以为它指定一个别名:
  144. Listresults=session.createCriteria(Cat.class)
  145. .setProjection(Projections.projectionList()
  146. .add(Projections.rowCount(),"catCountByColor")
  147. .add(Projections.avg("weight"),"avgWeight")
  148. .add(Projections.max("weight"),"maxWeight")
  149. .add(Projections.groupProperty("color"),"color")
  150. )
  151. .addOrder(Order.desc("catCountByColor"))
  152. .addOrder(Order.desc("avgWeight"))
  153. .list();
  154. Listresults=session.createCriteria(Domestic.class,"cat")
  155. .createAlias("kittens","kit")
  156. .setProjection(Projections.projectionList()
  157. .add(Projections.property("cat.name"),"catName")
  158. .add(Projections.property("kit.name"),"kitName")
  159. )
  160. .addOrder(Order.asc("catName"))
  161. .addOrder(Order.asc("kitName"))
  162. .list();
  163. 你也可以使用Property.forName()来表示投影:
  164. Listresults=session.createCriteria(Cat.class)
  165. .setProjection(Property.forName("name"))
  166. .add(Property.forName("color").eq(Color.BLACK))
  167. .list();
  168. Listresults=session.createCriteria(Cat.class)
  169. .setProjection(Projections.projectionList()
  170. .add(Projections.rowCount().as("catCountByColor"))
  171. .add(Property.forName("weight").avg().as("avgWeight"))
  172. .add(Property.forName("weight").max().as("maxWeight"))
  173. .add(Property.forName("color").group().as("color")
  174. )
  175. .addOrder(Order.desc("catCountByColor"))
  176. .addOrder(Order.desc("avgWeight"))
  177. .list();
  178. 15.8.离线(detached)查询和子查询
  179. DetachedCriteria类使你在一个session范围之外创建一个查询,并且可以使用任意的Session来执行它。
  180. DetachedCriteriaquery=DetachedCriteria.forClass(Cat.class)
  181. .add(Property.forName("sex").eq('F'));
  182. Sessionsession=....;
  183. Transactiontxn=session.beginTransaction();
  184. Listresults=query.getExecutableCriteria(session).setMaxResults(100).list();
  185. txn.commit();
  186. session.close();
  187. DetachedCriteria也可以用以表示子查询。条件实例包含子查询可以通过Subqueries或者Property获得。
  188. DetachedCriteriaavgWeight=DetachedCriteria.forClass(Cat.class)
  189. .setProjection(Property.forName("weight").avg());
  190. session.createCriteria(Cat.class)
  191. .add(Property.forName("weight).gt(avgWeight))
  192. .list();
  193. DetachedCriteriaweights=DetachedCriteria.forClass(Cat.class)
  194. .setProjection(Property.forName("weight"));
  195. session.createCriteria(Cat.class)
  196. .add(Subqueries.geAll("weight",weights))
  197. .list();
  198. 甚至相互关联的子查询也是有可能的:
  199. DetachedCriteriaavgWeightForSex=DetachedCriteria.forClass(Cat.class,"cat2")
  200. .setProjection(Property.forName("weight").avg())
  201. .add(Property.forName("cat2.sex").eqProperty("cat.sex"));
  202. session.createCriteria(Cat.class,"cat")
  203. .add(Property.forName("weight).gt(avgWeightForSex))
  204. .list();
  205. //具体应用
  206. 把HSQL语句用Criteria代替,感觉更加美观一点,而且还支持中文,要是HSQL想支持中文,你得使用占位符来设置,具体可参照:http://.blogdriver.com//983190.html
  207. 那么Criteria的用法是这样的:
  208. publicCollectionfindCriteria(finalDetachedCriteriadc,finalIPagepage){
  209. return(List)getHibernateTemplate().execute(newHibernateCallback(){
  210. publicObjectdoInHibernate(Sessionsession)throwsHibernateException,SQLException{
  211. Criteriac=dc.getExecutableCriteria(session);
  212. page.setTotalCount(((Integer)c.setProjection(Projections.rowCount()).uniqueResult()).intValue());
  213. c.setProjection(null);
  214. c.setResultTransformer(Criteria.ROOT_ENTITY);
  215. c.setFirstResult(page.getBeginIndex());
  216. c.setMaxResults(page.getPageSize());
  217. returnc.list();
  218. }
  219. },true);
  220. }
  221. 其中的参数true表示要Spring强制传入SessionImpl,而不是传入Proxy代理类,page.setTotalCount(((Integer)c.setProjection(Projections.rowCount()).uniqueResult()).intValue());
  222. c.setProjection(null);目的是为了获得行数,并设置投影为空,为的是返回List出来,如果不设置setProjection(null)的话,c.list将返回的是行数(int型),而不是所要查询的数据库信息。但是Criteria的ResultTransformer会变成PassThroughResultTransformer,criteria.list的时候可能结果会跟理想的不一样。所以我们还要再c.setResultTransformer(Criteria.ROOT_ENTITY);把结果以Entity的形式返回,而不是Object[]的形式返回。具体的ResultTransformer可以google一下。
  223. 测试代码如下:
  224. publicvoidtestCriteria(){
  225. DetachedCriteriadc=DetachedCriteria.forClass(User.class);
  226. dc.add(Restrictions.eq("name","user")).add(Restrictions.like("description","%主管人员%"));
  227. IPagepage=newPage();
  228. page.setCurrentPage(1);
  229. page.setPageSize(10);
  230. Collectionlist=_userDAO.findCriteria(dc,page);
  231. assertNotNull(list);
  232. assertEquals(1,list.size());
  233. }

你可能感兴趣的:(Hibernate)