转载

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

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

实体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=? 

正文到此结束
Loading...