若多個使用者可共住一個房間,則使用者與房間的關係就是多對一的關係。
您可以使用@ManyToOne於User類別的Room屬性上標示多對一關係,例如:
- User.java
package onlyfun.caterpillar;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name="T_USER")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="USER_ID")
private Long id;
private String name;
private Long age;
@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name="ROOM_ID_FK")
private Room room;
// 以下為 Getter、Setter
....
}
而Room類別可以撰寫如下:
- Room.java
package onlyfun.caterpillar;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="T_ROOM")
public class Room implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="ROOM_ID")
private Long id;
private String address;
// 以下為 Getter、Setter
....
}
在這樣的設定下,是由User維持對Room的參考來維持多對一的關係,Room並沒有意識到User的存在,而您在儲存時,由於設定了CascadeType.ALL,所以直接儲存User實例時,所參考的Room實例也會一併被儲存,例如一個範例如下所示:
Room room = new Room();
room.setAddress("NTU-M8-419");
User user1 = new User();
user1.setName("caterpillar");
user1.setAge(new Long(30));
user1.setRoom(room);
User user2 = new User();
user2.setName("Justin");
user2.setAge(new Long(35));
user2.setRoom(room);
EntityManager entityManager =
JPAUtil.getEntityManagerFactory().createEntityManager();
EntityTransaction etx = entityManager.getTransaction();
etx.begin();
entityManager.persist(user1);
entityManager.persist(user2);
etx.commit();
entityManager.close();
此時會先儲存Room實例,取得ROOM_ID之後,再儲存User實例,並將ROOM_ID_FK設為與ROOM_ID相同,此時表格內容如下所示:
而如果您使用以下的方式查詢:
User user = entityManager.find(User.class, new Long(1));
在使用Hibernate作為JPA的實作時,會產生以下的SQL語句:
Hibernate:
select
user0_.USER_ID as USER1_0_1_,
user0_.age as age0_1_,
user0_.name as name0_1_,
user0_.ROOM_ID_FK as ROOM4_0_1_,
room1_.ROOM_ID as ROOM1_1_0_,
room1_.address as address1_0_
from
T_USER user0_
left outer join
T_ROOM room1_
on user0_.ROOM_ID_FK=room1_.ROOM_ID
where
user0_.USER_ID=?
select
user0_.USER_ID as USER1_0_1_,
user0_.age as age0_1_,
user0_.name as name0_1_,
user0_.ROOM_ID_FK as ROOM4_0_1_,
room1_.ROOM_ID as ROOM1_1_0_,
room1_.address as address1_0_
from
T_USER user0_
left outer join
T_ROOM room1_
on user0_.ROOM_ID_FK=room1_.ROOM_ID
where
user0_.USER_ID=?