让我们介绍另一个休眠性能提示。 你还记得以前的休眠的模式后 ? 我们有一个与一对多协会有关的星际飞船和军官。

@Entity
public class Starship {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@OneToMany(mappedBy="starship", cascade={CascadeType.ALL}) private List<Officer> officers = new ArrayList<Officer>();public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}//more code
}@Entity
public class Officer {@Id @GeneratedValue(strategy=GenerationType.SEQUENCE) private Long id;public Long getId() {return id;}protected void setId(Long id) {this.id = id;}@ManyToOne private Starship starship; public Starship getStarship() {return starship;}protected void setStarship(Starship starship) {this.starship = starship;}//more code
}

现在我们有下一个要求:
我们将按字母顺序将所有军官分配给星际飞船。
为了解决这个要求,我们可以:

  1. 使用order by子句实现HQL查询。
  2. 使用排序方法。
  3. 使用订单方法。

第一个解决方案在性能方面不错,但是作为开发人员意味着更多的工作,因为我们应该编写一个查询来查找按名称排序的给定飞船的所有人员,然后在DAO层中创建finder方法(如果您使用的是DAO模式 ) 。
让我们探索第二个解决方案,我们可以使用SortedSet类作为关联,并使Officer实现Comparable ,因此Officer具有 自然秩序。 该解决方案的工作量少于第一个,但需要在关联定义上使用@Sort 休眠注释,因此让我们修改以前的模型以满足我们的新要求。请注意, JPA规范中没有等效的注释。 首先我们要实施

@Entity
public class Officer implements Comparable<Officer>{//getters, setters, equals, ... codepublic int compareTo(Officer officer) {return this.name.compareTo(officer.getName());}}

官员类中的可比接口。

我们通过简单地比较名称字段来按名称订购人员。 下一步是使用@Sort注释关联。

@Entity
public class Starship {//more code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL})@Sort(type=SortType.NATURAL)private SortedSet>Officer< officers = new TreeSet>Officer<();public SortedSet>Officer< getOfficers() {return Collections.unmodifiableSortedSet(officers);}protected void setOfficers(SortedSet>Officer< officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}
}

注意,现在使用SortedSet而不是List来实现人员关联。 此外,我们在关系中添加了@Sort批注,表明官员应自然而有序。 在完成本文之前,我们将在@Sort主题中坚持使用更多内容,但到目前为止已经足够。

最后是一种方法,该方法可以按名称对给定星际飞船的所有人员进行排序,并将其打印在日志文件中。

EntityManager entityManager = this.entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();transaction.begin();
log.info("Before Find Starship By Id");Starship newStarship = entityManager.find(Starship.class, starshipId);
SortedSet<Officer> officers = newStarship.getOfficers();for (Officer officer : officers) {log.info("Officer name {} with rank {}", officer.getName(), officer.getRank());
}log.info("After Find Starship By Id and Before Commit");transaction.commit();
entityManager.close();

所有人员均按其姓名排序,但让我们检查将哪些查询发送到RDBMS

Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_
from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_
from Officer officers0_ where officers0_.starship_id=?

第一个查询是在EntityManager实例查找星舰上调用find方法导致的。

因为默认情况下,当我们调用getOfficers方法并且第一次访问SortedSet时 ,一对多关系是惰性的,所以执行第二个查询来检索所有人员。 看到查询中不存在order by子句,但仔细查看输出,会按字母顺序检索人员。

<Officer name Beverly Crusher with rank COMMANDER>
<Officer name Data with rank LIEUTENANT_COMMANDER>
<Officer name Deanna Troi with rank COMMANDER>
<Officer name Geordi La Forge with rank LIEUTENANT>
<Officer name Jean-Luc Picard with rank CAPTAIN>
<Officer name William Riker with rank COMMANDER>
<Officer name Worf with rank LIEUTENANT>

那么谁是整理人员实体? 说明在@Sort注释上。 在休眠状态下,一个排序的集合在Java内存中排序,它负责使用compareTo方法对数据进行排序。
显然,此方法不是对元素集合进行排序的最佳性能方法。 在使用SQL子句和使用注释而不是编写查询之间,我们可能需要一种混合解决方案。

这使我们使用排序方法来解释第三种可能性。 @OrderBy注释(可以用作休眠注释和JPA注释),让我们指定如何通过在生成的SQL中添加“ order by ”子句来对集合进行排序

请记住,使用javax.persistence.OrderBy允许我们通过对象属性指定集合的​​顺序,同时org.hibernate.annotations.OrderBy对集合进行排序,将SQL的片段(不是HQL )直接附加到order by子句中。
现在不应该触动Officer类,我们不需要实现compareTo方法或java.util.Comparator 。 我们只需要使用@OrderBy注释来注释人员字段。 由于在这种情况下,我们通过简单的属性进行排序,因此使用JPA注释来保持与其他“支持JPA的ORM引擎的完全兼容性。 默认情况下,假定升序。

@Entity
public class Starship {//code@OneToMany(mappedBy="starship", cascade={CascadeType.ALL})@OrderBy("name")private List<Officer> officers = new ArrayList<Officer>();public List<Officer> getOfficers() {return Collections.unmodifiableList(officers);}protected void setOfficers(List<Officer> officers) {this.officers = officers;}public void addOfficer(Officer officer) {officer.setStarship(this);this.officers.add(officer);}
}

如果我们重新运行所有人员的方法,则会发送下一个查询:

Hibernate: select starship0_.id as id1_0_, starship0_.affiliationEnum as affiliat2_1_0_, starship0_.launched as launched1_0_, starship0_.height as height1_0_, starship0_.length as length1_0_, starship0_.power as power1_0_, starship0_.width as width1_0_, starship0_.registry as registry1_0_, starship0_.starshipClassEnum as starship9_1_0_
from Starship starship0_ where starship0_.id=?Hibernate: select officers0_.starship_id as starship7_1_1_, officers0_.id as id1_, officers0_.id as id0_0_, officers0_.affiliationEnum as affiliat2_0_0_, officers0_.homePlanet as homePlanet0_0_, officers0_.name as name0_0_, officers0_.rank as rank0_0_, officers0_.speciesEnum as speciesE6_0_0_, officers0_.starship_id as starship7_0_0_
from Officer officers0_ where officers0_.starship_id=? order by officers0_.name asc

这两个查询仍然执行,但请注意,现在select查询也包含order by子句。

使用此解决方案,您可以节省处理时间,从而允许RDBMS快速对数据进行排序,而不是一旦接收到Java中的数据就对其进行排序。
此外, OrderBy批注不会强制您使用SortedSetSortedMap集合。 您可以使用HashMapHashSet甚至Bag之类的任何集合,因为hibernate将在内部分别使用LinkedHashMapLinkedHashSetArrayList

在这个例子中,我们已经看到了正确选择订购策略的重要性。 只要有可能,您都应该尝试利用RDBMS的功能,因此您的第一个选择应该是使用OrderBy注释( 休眠JPA ),而不是Sort 。 但是有时OrderBy子句是不够的。 在这种情况下,我建议您使用具有自定义类型的Sort注释(使用java.util.Comparator类),而不是按自然顺序进行中继以避免触摸模型类。

@Sort(type=SortType.COMPARATOR, comparator=TimeComparator.class)

我希望这篇文章可以帮助您了解休眠状态下 “排序”“顺序”之间的区别。

保持学习。

参考: Hibernate提示:我们的JCG合作伙伴 Alex Soto的“ 排序和排序”在One Jar To Rule All All博客中。

翻译自: https://www.javacodegeeks.com/2012/04/hibernate-tip-sort-and-order.html

休眠提示:排序和排序相关推荐

  1. 扩展GridView控件(2) - 复合排序和排序状态提示

    GridView既强大又好用.为了让它更强大.更好用,我们来写一个继承自GridView的控件. [索引页] [源码下载] 扩展GridView控件(2) - 复合排序和排序状态提示 作者:webab ...

  2. java排序——桶排序

    2019独角兽企业重金招聘Python工程师标准>>> package jxau.blueDot.lyx;import java.util.ArrayList; import jav ...

  3. 【数据结构-排序】1. 图解插入排序三种实现(插入排序/折半排序/希尔排序)

    直接插入排序(插入排序) 排序思想 对于一个数组 A[0,n] 的排序问题,假设认为数组在 A[0,n-1] 排序的问题已经解决了. 考虑 A[n] 的值,从右向左扫描有序数组 A[0,n-1] ,直 ...

  4. python 排序_Python 排序了解一下?

    脚本之家 你与百万开发者在一起 文 | 潮汐 来源:Python 技术「ID: pythonall」 排序是每个开发人员都需要掌握的技能.排序是对程序本身有一个全面的理解.不同的排序算法很好地展示了算 ...

  5. boost::sort模块实现使用最坏情况分布进行扩展排序的排序示例

    boost::sort模块实现使用最坏情况分布进行扩展排序的排序示例 实现功能 C++实现代码 实现功能 boost::sort模块实现使用最坏情况分布进行扩展排序的排序示例 C++实现代码 #inc ...

  6. 堆排序算法c语言筛选法,【排序】排序算法之选择排序

    排序算法之选择排序 罗朝辉(http://www.cppblog.com/kesalin) 转载请注明出处 排序是数据处理中经常使用的一种重要运算,在计算机及其应用系统中,花费在排序上的时间在系统运行 ...

  7. 算法-排序-k排序(算法导论第三版第八章思考题8-5)

    算法-排序-k排序 算法导论第三版第八章思考题8-5 时间复杂度Θ(nlg(n/k)). 利用最小堆完成,把元素分成k个堆,每个堆大小⌈n/k⌉. 利用堆作为子排序稳定,也可以采用其他排序作为子排序, ...

  8. 合并排序算法排序过程_合并排序| 用于大型输入的最佳排序算法之一

    合并排序算法排序过程 What is sorting? 什么是分类? Sorting allows us to process our data in a more organized and eff ...

  9. 排序上---(排序概念,常见排序算法,直接插入,希尔排序,直接选择排序,堆排序)

    排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作. 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对 ...

最新文章

  1. mysql 时差查了13小时_Mysql 时间差了 14 或 13 小时 com.mysql.cj.jdbc.Driver
  2. linux嵌套字幕工具,Linux(NAS通用)下自动匹配射手字幕脚本
  3. [git]通过commit_id找回文件
  4. 改进同步等待的网络服务端应用 (转)
  5. errorattributes 过时_苹果官方确认:iPhone 5c 已被列为过时产品
  6. [Buzz Today]2012.09.01
  7. 第十八章 35用重载比较运算符实现字符串的比较
  8. linux shell ls -1 列显示文件
  9. word文本框中插入文本框_在Word 2007中快速将文本翻译成另一种语言
  10. FFmpeg给mp4视频加上旋转90度的代码
  11. 《鱿鱼游戏》开场了|谁才是影评人的御用写作工具
  12. 自动化设备远程监控系统软件
  13. 对持久层、持久性、持久化的讨论
  14. 用Python帮你选注双色球号码
  15. 自我介绍思维导图简单又漂亮
  16. Struts Hibernate整合配置准备
  17. K_A07_001 基于 STM32等单片机驱动A4988模块按键控制步进电机正反转
  18. webmatrix安装_上下文中的Microsoft WebMatrix和部署您的第一个站点
  19. 如何利用织梦的内链功能,自动给文章加内链。
  20. 极简主义的思想内核-奥卡姆剃刀原则

热门文章

  1. 对Servlet容器的补充
  2. java集合——具体的集合
  3. 存储过程内基础语法---补充while循环
  4. 手游建筑美术资源_建筑商和机械手
  5. jpa避免n+1_JPA技巧:避免N + 1选择问题
  6. jooq_jOOQ API设计缺陷的怪异事件
  7. restful xml_使用入站适配器公开HTTP Restful API。 第1部分(XML)
  8. 图片大小 媒体大小自适应_自适应堆大小
  9. html嵌入war_WAR文件与具有嵌入式服务器的Java应用程序
  10. springmvc jpa_使用JavaConfig的SpringMVC4 + Spring Data JPA + SpringSecurity配置