休眠提示:排序和排序

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

@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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372775.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 基本类型 线程安全_java的基本类型和i++线程安全性的深入解析

在java中&#xff0c;除了long和double的8个字节、64位比特的变量外&#xff0c;其他的基本变量都是原子性的。java存储模型要求获取和存储操作都为原子性&#xff0c;但是对于非volatile的long和double变量&#xff0c;jvm允许将64位的读或写划分为两个32位的操作。如果读和写…

MySQL配置文件mysql.ini参数详解

my.ini&#xff08;Linux系统下是my.cnf&#xff09;&#xff0c;当mysql服务器启动时它会读取这个文件&#xff0c;设置相关的运行环境参数。 my.ini分为两块&#xff1a;Client Section和Server Section。 Client Section用来配置MySQL客户端参数。 要查看配置参数可以用下面…

微信公众平台和微信开放平台的区别

自己也刚开始做微信开发&#xff0c;先写写自己的认识&#xff1a; 用微信公众平台可以做手机端H5页面的微信登录&#xff0c;微信支付 用微信开放平台可以做PC端网页的微信登录。 转载于:https://www.cnblogs.com/mafeng/p/5610770.html

java 传递bean_如何将bean作为参数传递给JSP标记?

我ve created a custom JSP tag that is supposed to accept a list of products to render, but I我无法弄清楚如何将列表传递给标签 . 产品列表作为页面范围的bean存在 . Web应用程序使用Struts taglib在Struts 1.2.x中编写 .这是我的代码的简化版本&#xff1a;renderProduc…

Business Component(BC)和Business Object(BO)

Siebel应用架构的一个成功的地方就是在应用里引入了BC&#xff0c;BO的概念&#xff0c;从而使得几千张关系数据表能够按照业务的含义组织成业务对象&#xff0c;对于业务人员而言具有了业务上的含义&#xff0c;而不仅仅是从技术人员的观点来对待数据&#xff08;就是关系表而…

NetBeans可用性提示

的Java IDE都来了&#xff0c;因为在很长的路要走天的JBuilder的 &#xff08;尽管JBuilder中似乎是一个值得欢迎提前在时间&#xff09;。 当今的Java IDE&#xff08;例如NetBeans &#xff0c; Eclipse &#xff0c; IntelliJ IDEA和JDeveloper &#xff09;是非常先进的工具…

一个JVM进程启动后里面有几个线程

在写Java程序时&#xff0c;通常我们管只有一个main函数&#xff08;而没有别的Thread或Runnable的程序&#xff09;叫单线程程序。但是我们写的这个所谓的单线程程序只是JVM这个程序中的一个线程&#xff0c;JVM本身是一个多线程的程序&#xff0c;至少得有一个垃圾收集器线程…

WPF 反编译后错误处理

1. 首先&#xff0c;手动创建一个WPF工程&#xff08;WpfApplicationReflectorDemo&#xff09; 2. 把生成的WpfApplicationReflectorDemo.exe 拖到ILSpy里 3.点击 File -> Save Code...: 相应的代码会生成到指定地方。 4. 打开应用程序&#xff0c;并且编译它&#xff0c;此…

JavaFX 2 GameTutorial第1部分

介绍 我相信大多数软件开发人员可能会在年轻人&#xff08;年轻人&#xff09;一生中的某一时刻被迫创建游戏来帮助他们学习编程语言&#xff08;我知道我确实做到了&#xff09;。 以前&#xff0c;我的第一台计算机实际上是Franklin Ace 1000 &#xff0c;后来是Apple [] 。 …

虚拟现实-VR-UE4-认识UE4

VR的火热&#xff0c;让每个人都想参与一下&#xff0c; 公司在展会上面搞了一个VR的Demo&#xff0c;关注度超出预期&#xff0c;使得公司高层决定来个VR项目 所以 关于UE4 百度百科地址&#xff1a;http://baike.baidu.com/link?urlmEmbwOcqEuqtkfdu9lNdxVtWAkv0Q6UHZ4VgIHr…

java concurrent 例子_[Java Concurrent] 并发访问共享资源的简单案例

EvenGenerator 是一个偶数生成器&#xff0c;每调用一个 next() 就会加 2 并返回叠加后结果。在本案例中&#xff0c;充当被共享的资源。EvenChecker 实现了 Runnable 接口&#xff0c;可以启动新的线程执行 run() 任务&#xff0c;用于检测所指向的偶数生成器是否每次都返回偶…

OSGI实战第一章

第一章 解开OSGI的面纱 OSGI是什么&#xff1f;是Java平台的一个模块化层。模块化&#xff1a;软件应用程序的代码被分割为表示独立内容的逻辑单元&#xff0c;可简化开发&#xff0c;可通过强化逻辑模块的界限来提高可维护性。Java模块化的不足a) Java使用访问…

轻松完成Birt报告

这是使用Birt插件在Eclipse中构建报告的完整指南。 Birt或Business Intelligence and Reporting工具是一种无需编写太多Java代码即可生成报告的工具。 如果您使用的是ireport&#xff0c;那么您知道我在说什么&#xff1a;&#xff09;&#xff08;晶体报告..毫无意义&#xff…

MySQL 的 RowNum 实现

MySQL 下面没有RowNum&#xff0c;排序后序号却无法得到&#xff0c;比较麻烦&#xff01; SELECT rownum:rownum1 rownum, CollectSn From(SELECT rownum:0,bbgmain.* FROM qbdb.bbgmain WHERE collectsn! ORDER BY collectsn limit 10) t转载于:https://www.cnblogs.com/hym-…

java jdbc事务管理_hibernate事务管理 (jdbc jta)

评论# re: hibernate事务管理 (jdbc jta)2007-07-29 10:18pigJTA事务的开始Transaction tx session.beginTransaction();应该不是这样吧&#xff0c;应该是从容器中获得。 回复 更多评论# re: hibernate事务管理 (jdbc jta)2007-07-29 12:35slxpig建议看看hibernate referen…

@Resource VS @Autowired

Resource 和 Autowired 均是用于bean注入的注解&#xff0c;都可以写在字段和setter方法上,如果都写在字段上&#xff0c;就无需写setter方法。 Autowired 由Spring的org.springframework.beans.factory.annotation.Autowired提供 默认byType方式注入&#xff0c;并且对象不能为…

用于Spring应用程序的Gradle原型

我发布了Gradle原型&#xff0c;可用于基于Springframework创建Java / Groovy应用程序。 当然&#xff0c;它不是一个真正的原型&#xff0c;因为这样的创作是不可能的 。不过&#xff0c;你可以创建&#xff0c;编辑和部署应用服务器很少的步骤。 对于可部署的软件项目而言&am…

java tm无响应_Java(TM) Platform SE binary 未响应 是怎么个情况?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼988098 [Thread-10] INFO sound.oo0O - Creating streaming player for music with id [faction_pirate_encounter_02_hostile.ogg]988099 [Thread-10] INFO sound.OooO - Playing music with id [faction_pirate_encounter_02_hos…

ROS and PCL install

ROS hydro安装指南&#xff1a; http://wiki.ros.org/cn/hydro/Installation/Ubuntu &#xff08;加ppa源后直接安装&#xff09; Linux OpenCV安装指南&#xff1a;http://blog.sciencenet.cn/blog-571755-694742.html &#xff08;从源代码编译&#xff09; PCL&#xff1a;…

揭开Python科学计算的面纱

春牛春杖。无限春风来海上。便与春工。染得桃红似肉红。 春幡春胜。一阵春风吹酒醒。不似天涯。卷起杨花似雪花。 标准的Python中用列表保存一组值&#xff0c;可以当做数组使用&#xff0c;但是由于其值类型任意&#xff0c;所以列表中保存的是指针&#xff0c;这样的话保存一…