hibernate 排序

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

@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 Hibernate注释,因此让我们修改以前的模型以满足我们的新要求。请注意, 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注释上。 在Hibernate状态下,一个排序的集合在Java内存中排序,它负责使用compareTo方法对数据进行排序。
显然,此方法不是对元素集合进行排序的最佳性能方法。 在使用SQL子句和使用注释而不是编写查询之间,我们可能需要一个混合解决方案。

这使我们使用排序方法来解释第三种可能性。 @OrderBy注释(可作为Hibernate注释和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注释( HibernateJPA ),而不是Sort 。 但是有时OrderBy子句是不够的。 在这种情况下,建议您使用具有自定义类型的Sort批注(使用java.util.Comparator类),而不是按自然顺序进行中继以避免触摸模型类。

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

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

保持学习。

参考: Hibernate提示:我们的JCG合作伙伴 Alex Soto在“ 一个罐子统治所有”博客上进行了排序和订购 。

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

hibernate 排序

hibernate 排序_Hibernate提示:排序和排序相关推荐

  1. 输入5个学生的名字(英文),使用冒泡排序按从大到小排序。 提示:涉及到字符串数组,一个字符串是一个一维字符数组;一个 字符串数组就是一个二维字符数组。...

    输入5个学生的名字(英文),使用冒泡排序按从大到小排序. 提示:涉及到字符串数组,一个字符串是一个一维字符数组:一个 字符串数组就是一个二维字符数组. #include <stdio.h> ...

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

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

  3. 排序算法系列:Shell 排序算法

    概述 希尔排序(Shell Sort)是 D.L.Shell 于 1959 年提出来的一种排序算法,在这之前排序算法的时间复杂度基本都是 O(n2n^{2}n2) 的,希尔排序算法是突破这个时间复杂度 ...

  4. 【数据结构】排序相关题目及各种排序方法的总结

    [数据结构之排序] 常用的排序方法有:直接插入排序.希尔排序.冒泡排序.快速排序.简单选择排序.树形选择排序.堆排序.归并排序.基数排序 提示:如有不理解的知识点,请看B站最好的数据结构老师王卓老师的 ...

  5. 计算机编程输入3个数排序,汇编语言 输入10个数排序并输出的实现

    一:题目描述 在键盘输入任意10个数 按从小到大排序后,在计算机屏幕上先输出来.要有结果提示(字符串显示). 将10个数做累加,结果在计算机屏幕显示累加和. 二:伪指令的定义 1.数据段 ATAS S ...

  6. 按复杂度有效性递减排序_十大经典排序算法:python源码实现,通俗深入讲解

    概述 提示:本文上万字,陆陆续续疏理知识点加测试代码,耗时近一个月.阅读时长40分钟左右. 本文将十大经典排序算法进行汇总,从源码实现.复杂度.稳定性进行分析,并对每种排序的特性进行点评.对典型算法, ...

  7. sql服务器修改排序,设置或更改数据库排序规则

    设置或更改数据库排序规则 10/27/2020 本文内容 适用于: SQL Server(所有支持的版本) 本主题说明如何使用 SQL Server Management Studio 或 Trans ...

  8. 程序员内功修炼之学好算法和数据结构(一)排序基础、选择排序、插入排序、希尔排序...

    一.排序基础(重要) 1.1 为什么要学习O(n^2)的排序算法? 编码简单,易于实现,是一些简单情景的首选. 在一些特殊情况下,简单的排序算法更有效. 简单的排序算法思想衍生出复杂的排序算法,在这个 ...

  9. mysqlorderby数字字符串排序_Python中的元组排序和深度比较

    比较Python中的东西.这听起来几乎是不需要教的,但是我发现Python的比较运算符经常被Python新手误解和低估. 我们来回顾一下Python的比较运算符如何处理不同类型的对象,然后看看如何使用 ...

最新文章

  1. Swift - 移除页面视图上的所有元素
  2. eclipse编写wordcount提交spark运行
  3. 【算法】剑指 Offer 40. 最小的k个数 【重刷】
  4. Silverlight中无法设置卫星程序集为中立资源程序集
  5. 学生成绩管理系统——JAVA
  6. 实验项目三 基于A*搜索算法迷宫游戏开发
  7. AI:AI与爱无处不在,大赛与奖金齐飞—【科大讯飞】AI开发者大赛—与你在AI盛会中遨游!
  8. php启动flashpaper,图解FlashPaper的使用方法
  9. 二次函数顶点式计算机,顶点式二次函数表达式
  10. 成长感悟:谁定义了你的大学生活
  11. 《杀出个黎明》(From Dusk Till Dawn)--This is the fucking movie
  12. 2016 最新开发者账号 · 邓白氏申请申请流
  13. VSCode插件之实时字数统计与选中词英汉互译
  14. OpenCV—画出时钟并动态同步系统时间
  15. 比visio简单好用的绘图工具AxGlyph
  16. cuda 安装失败 Nsight Visual Studio Edition 11.1安装失败
  17. 双电阻差分电流采样_不同的泄露电流法特性介绍 多功能电气安规测试仪SECUTEST PRO...
  18. 无法触碰的掌心怎么在电脑上玩 无法触碰的掌心电脑版教程
  19. xposed绕过模拟器检测_利用Xposed躲过Xposed检测
  20. 阿里云轻量应用服务器应用镜像——WordPress 4.8.1

热门文章

  1. Git 12 岁了,送给你 12 个 Git 使用技巧
  2. struts+hibernate+oracle+easyui实现lazyout组件的简单案例——hibernate的config文件(hibernate.cfg.xml)
  3. Ajax响应处理数据的三种格式(主要使用gson包)
  4. 权限管理系统2_权限表,权限模块表
  5. 系统架构设计师考试999999999999
  6. github 公钥 私钥_github快速使用
  7. Linux获取本机hostname函数,Linux下获得主机与域名-gethostbyname和gethostbyaddr
  8. java –cp_Java –缺少字体–崩溃的应用程序!
  9. fork join框架_Java中的Fork / Join框架的简要概述
  10. java streams_使用JShell的Java 9 Streams API