作家
登录

JPA的查询语言:JPQL的关联查询

作者: 来源: 2012-06-12 12:33:25 阅读 我要评论

从一关联到多的查询和从多关联到一的查询来简单说说关联查询。

实体Team:球队。

实体Player:球员。

球队和球员是一对多的关系。

Team.java:

  1. package com.cndatacom.jpa.entity;  
  2.    
  3. import java.util.HashSet;  
  4. import java.util.Set;  
  5.    
  6. import javax.persistence.CascadeType;  
  7. import javax.persistence.Column;  
  8. import javax.persistence.Entity;  
  9. import javax.persistence.FetchType;  
  10. import javax.persistence.GeneratedValue;  
  11. import javax.persistence.Id;  
  12. import javax.persistence.OneToMany;  
  13. import javax.persistence.Table;  
  14.    
  15.    
  16. /**  
  17.  * 球队  
  18.  * @author Luxh  
  19.  */ 
  20. @Entity 
  21. @Table(name="team")  
  22. public class Team{  
  23.    
  24.     @Id 
  25.     @GeneratedValue 
  26.     private Long id;  
  27.        
  28.     /**球队名称*/ 
  29.     @Column(name="name",length=32)  
  30.     private String name;  
  31.        
  32.     /**拥有的球员*/ 
  33.     @OneToMany(mappedBy="team",cascade=CascadeType.ALL,fetch=FetchType.LAZY)  
  34.     private Set<Player> players = new HashSet<Player>();  
  35.    
  36.     //以下省略了getter/setter方法   
  37.    
  38.     //......  

Player.java:

  1. package com.cndatacom.jpa.entity;  
  2.    
  3.    
  4. import javax.persistence.CascadeType;  
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.GeneratedValue;  
  8. import javax.persistence.Id;  
  9. import javax.persistence.JoinColumn;  
  10. import javax.persistence.ManyToOne;  
  11. import javax.persistence.Table;  
  12.    
  13.    
  14. /**  
  15.  * 球员  
  16.  * @author Luxh  
  17.  */ 
  18. @Entity 
  19. @Table(name="player")  
  20. public class Player{  
  21.        
  22.     @Id 
  23.     @GeneratedValue 
  24.     private Long id;  
  25.        
  26.     /**球员姓名*/ 
  27.     @Column(name="name")  
  28.     private String name;  
  29.        
  30.     /**所属球队*/ 
  31.     @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH})  
  32.     @JoinColumn(name="team_id")  
  33.     private Team team;  
  34.        
  35.     //以下省略了getter/setter方法  
  36.    
  37.         //......  

1、从One的一方关联到Many的一方:

查找出球员所属的球队,可以使用以下语句:

  1. SELECT DISTINCT t FROM Team t JOIN t.players p where p.name LIKE :name 

或者使用以下语句:

  1. SELECT DISTINCT t FROM Team t,IN(t.players) p WHERE p.name LIKE :name 

上面两条语句是等价的,产生的SQL语句如下:

  1. select 
  2.     distinct team0_.id as id0_,  
  3.     team0_.name as name0_  
  4. from 
  5.     team team0_  
  6. inner join 
  7.     player players1_  
  8.         on team0_.id=players1_.team_id  
  9. where 
  10.     players1_.name like ? 

从SQL语句中可以看到team inner join 到player。inner join要求右边的表达式必须有返回值。

不能使用以下语句:

  1. SELECT DISTINCT t FROM Team t  WHERE t.players.name LIKE :name 

不能使用t.players.name这样的方式从集合中取值,要使用join或者in才行。

2、从Many的一方关联到One的一方:

查找出某个球队下的所有球员,可以使用以下查询语句:

  1. SELECT p FROM Player p JOIN p.team t WHERE t.id = :id 

或者使用以下语句:

  1. SELECT p FROM Player p, IN(p.team) t WHERE t.id = :id 

这两条查询语句是等价的,产生的SQL语句如下:(产生了两条SQL)

  1. Hibernate:  
  2.     select 
  3.         player0_.id as id1_,  
  4.         player0_.name as name1_,  
  5.         player0_.team_id as team3_1_  
  6.     from 
  7.         player player0_  
  8.     inner join 
  9.         team team1_  
  10.             on player0_.team_id=team1_.id  
  11.     where 
  12.         team1_.id=?  
  13. Hibernate:  
  14.     select 
  15.         team0_.id as id2_0_,  
  16.         team0_.name as name2_0_  
  17.     from 
  18.         team team0_  
  19.     where 
  20.         team0_.id=? 

从Many关联到One的查询,还可以使用以下的查询语句:

  1. SELECT p FROM Player p WHERE p.team.id = :id 

这条语句产生的SQL如下:(产生了两条SQL)

  1. Hibernate:  
  2.     select 
  3.         player0_.id as id1_,  
  4.         player0_.name as name1_,  
  5.         player0_.team_id as team3_1_  
  6.     from 
  7.         player player0_  
  8.     where 
  9.         player0_.team_id=?  
  10. Hibernate:  
  11.     select 
  12.         team0_.id as id0_0_,  
  13.         team0_.name as name0_0_  
  14.     from 
  15.         team team0 

以上从Many到One的关联查询都产生了两条SQL,还可以使用join fetch只产生一条SQL语句。查询语句如下:

  1. SELECT p FROM Player p JOIN FETCH p.team t WHERE t.id = :id 

这条查询语句产生的SQL如下:

  1. Hibernate:  
  2.     select 
  3.         player0_.id as id1_0_,  
  4.         team1_.id as id2_1_,  
  5.         player0_.name as name1_0_,  
  6.         player0_.team_id as team3_1_0_,  
  7.         team1_.name as name2_1_  
  8.     from 
  9.         player player0_  
  10.     inner join 
  11.         team team1_  
  12.             on player0_.team_id=team1_.id  
  13.     where 
  14.         team1_.id=? 

原文链接:http://www.cnblogs.com/luxh/archive/2012/06/02/2531750.html

【编辑推荐】

  1. JPA的查询语言:JPQL的简单查询
  2. JPA的查询语言:JPQL的命名查询
  3. Java中finally关键字的使用
  4. Java内存原型分析:基本知识
  5. Java多线程问题之同步器CyclicBarrier

  推荐阅读

  Java多线程问题之同步器CyclicBarrier

还是上次的oracle迁移到mysql的遗留问题,当我在查看数据的时候,发现两个库数据量不一致。最后证实了我的看法,我修改代码时将10个进程简成1个单线程来完成了。所以数据量会少那么多呢。原因很简单当时就是这个函数>>>详细阅读


本文标题:JPA的查询语言:JPQL的关联查询

地址:http://www.17bianji.com/kaifa2/Java/149.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)