JPA的查詢語言:JPQL的關(guān)聯(lián)查詢
從一關(guān)聯(lián)到多的查詢和從多關(guān)聯(lián)到一的查詢來簡單說說關(guān)聯(lián)查詢。
實體Team:球隊。
實體Player:球員。
球隊和球員是一對多的關(guān)系。
Team.java:
- package com.cndatacom.jpa.entity;
- import java.util.HashSet;
- import java.util.Set;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.FetchType;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.OneToMany;
- import javax.persistence.Table;
- /**
- * 球隊
- * @author Luxh
- */
- @Entity
- @Table(name="team")
- public class Team{
- @Id
- @GeneratedValue
- private Long id;
- /**球隊名稱*/
- @Column(name="name",length=32)
- private String name;
- /**擁有的球員*/
- @OneToMany(mappedBy="team",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
- private Set<Player> players = new HashSet<Player>();
- //以下省略了getter/setter方法
- //......
- }
Player.java:
- package com.cndatacom.jpa.entity;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.ManyToOne;
- import javax.persistence.Table;
- /**
- * 球員
- * @author Luxh
- */
- @Entity
- @Table(name="player")
- public class Player{
- @Id
- @GeneratedValue
- private Long id;
- /**球員姓名*/
- @Column(name="name")
- private String name;
- /**所屬球隊*/
- @ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH})
- @JoinColumn(name="team_id")
- private Team team;
- //以下省略了getter/setter方法
- //......
- }
1、從One的一方關(guān)聯(lián)到Many的一方:
查找出球員所屬的球隊,可以使用以下語句:
- SELECT DISTINCT t FROM Team t JOIN t.players p where p.name LIKE :name
或者使用以下語句:
- SELECT DISTINCT t FROM Team t,IN(t.players) p WHERE p.name LIKE :name
上面兩條語句是等價的,產(chǎn)生的SQL語句如下:
- select
- distinct team0_.id as id0_,
- team0_.name as name0_
- from
- team team0_
- inner join
- player players1_
- on team0_.id=players1_.team_id
- where
- players1_.name like ?
從SQL語句中可以看到team inner join 到player。inner join要求右邊的表達(dá)式必須有返回值。
不能使用以下語句:
- SELECT DISTINCT t FROM Team t WHERE t.players.name LIKE :name
不能使用t.players.name這樣的方式從集合中取值,要使用join或者in才行。
2、從Many的一方關(guān)聯(lián)到One的一方:
查找出某個球隊下的所有球員,可以使用以下查詢語句:
- SELECT p FROM Player p JOIN p.team t WHERE t.id = :id
或者使用以下語句:
- SELECT p FROM Player p, IN(p.team) t WHERE t.id = :id
這兩條查詢語句是等價的,產(chǎn)生的SQL語句如下:(產(chǎn)生了兩條SQL)
- Hibernate:
- select
- player0_.id as id1_,
- player0_.name as name1_,
- player0_.team_id as team3_1_
- from
- player player0_
- inner join
- team team1_
- on player0_.team_id=team1_.id
- where
- team1_.id=?
- Hibernate:
- select
- team0_.id as id2_0_,
- team0_.name as name2_0_
- from
- team team0_
- where
- team0_.id=?
從Many關(guān)聯(lián)到One的查詢,還可以使用以下的查詢語句:
- SELECT p FROM Player p WHERE p.team.id = :id
這條語句產(chǎn)生的SQL如下:(產(chǎn)生了兩條SQL)
- Hibernate:
- select
- player0_.id as id1_,
- player0_.name as name1_,
- player0_.team_id as team3_1_
- from
- player player0_
- where
- player0_.team_id=?
- Hibernate:
- select
- team0_.id as id0_0_,
- team0_.name as name0_0_
- from
- team team0
以上從Many到One的關(guān)聯(lián)查詢都產(chǎn)生了兩條SQL,還可以使用join fetch只產(chǎn)生一條SQL語句。查詢語句如下:
- SELECT p FROM Player p JOIN FETCH p.team t WHERE t.id = :id
這條查詢語句產(chǎn)生的SQL如下:
- Hibernate:
- select
- player0_.id as id1_0_,
- team1_.id as id2_1_,
- player0_.name as name1_0_,
- player0_.team_id as team3_1_0_,
- team1_.name as name2_1_
- from
- player player0_
- inner join
- team team1_
- on player0_.team_id=team1_.id
- where
- team1_.id=?
原文鏈接:http://www.cnblogs.com/luxh/archive/2012/06/02/2531750.html