連接表
連接表就是保存多個關係在一張表中,而實體表中將不會出現與關係有關的任何信息。
1.表結構如下:
create table ROOM (
ID NUMBER(4) not null,
ROOMNUMBER VARCHAR2(11) not null,
NAME VARCHAR2(32) not null,
constraint ROOM_PK primary key (ID)
);
ID NUMBER(4) not null,
ROOMNUMBER VARCHAR2(11) not null,
NAME VARCHAR2(32) not null,
constraint ROOM_PK primary key (ID)
);
USERINFO(用戶表)
create table USERINFO(
ID NUMBER(4) not null,
NAME VARCHAR2(32) not null,
SEX VARCHAR2(2),
constraint USERINFO_PK primary key (ID)
);
ID NUMBER(4) not null,
NAME VARCHAR2(32) not null,
SEX VARCHAR2(2),
constraint USERINFO_PK primary key (ID)
);
連接表
create table ROOMUSERS(
USERID NUMBER(4) not null,
ROOMID NUMBER(4) not null,
constraint ROOMUSERS_PK primary key (USERID)
);
USERID NUMBER(4) not null,
ROOMID NUMBER(4) not null,
constraint ROOMUSERS_PK primary key (USERID)
);
一對多連接表映射文件
Room.hbm.xml(一端的配置)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.cosmow.hibernatedemo2.entity">
<class name="Room" table="ROOM" schema="STORE">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<!-- Oracle數據庫增長方式序列 -->
<generator class="sequence">
<param name="sequence">ROOM_SEQ</param>
</generator>
</id>
<!-- 映射roomnumber屬性 -->
<property name="roomnumber" type="java.lang.String">
<column name="ROOMNUMBER" length="11" not-null="true" />
</property>
<!-- 映射name屬性 -->
<property name="name" type="java.lang.String">
<column name="NAME" length="32" not-null="true" />
</property>
<!-- 通過連接表的一端,因此血藥table屬性爲roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 該key的字段爲連接表中的字段,作爲外鍵 -->
<key column="roomid" />
<!-- 配置多對多 -->
<!-- 但是unique屬性爲true,表示userid字段爲不可重複,保證一對多關係 -->
<many-to-many class="Userinfo" column="userid"
unique="true" />
</set>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.cosmow.hibernatedemo2.entity">
<class name="Room" table="ROOM" schema="STORE">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<!-- Oracle數據庫增長方式序列 -->
<generator class="sequence">
<param name="sequence">ROOM_SEQ</param>
</generator>
</id>
<!-- 映射roomnumber屬性 -->
<property name="roomnumber" type="java.lang.String">
<column name="ROOMNUMBER" length="11" not-null="true" />
</property>
<!-- 映射name屬性 -->
<property name="name" type="java.lang.String">
<column name="NAME" length="32" not-null="true" />
</property>
<!-- 通過連接表的一端,因此血藥table屬性爲roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 該key的字段爲連接表中的字段,作爲外鍵 -->
<key column="roomid" />
<!-- 配置多對多 -->
<!-- 但是unique屬性爲true,表示userid字段爲不可重複,保證一對多關係 -->
<many-to-many class="Userinfo" column="userid"
unique="true" />
</set>
</class>
</hibernate-mapping>
Userinfo.hbm.xml(多端的配置)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.cosmow.hibernatedemo2.entity">
<class name="Userinfo" table="USERINFO" schema="STORE">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<!-- Oracle數據庫增長方式序列 -->
<generator class="sequence">
<param name="sequence">USERINFO_SEQ</param>
</generator>
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="32" not-null="true" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="2" />
</property>
<!-- 使用join來配置多對一的連接,以table屬性來表示連接表的多對一,連接表爲roomusers -->
<!-- optional屬性表示這是一個外連接,inverse屬性可以出現在一端和多端,這裏選擇出現在多端,效果相同 -->
<join table="roomusers" optional="true" inverse="true">
<!-- 該key的字段爲連接表中的字段,作爲外鍵 -->
<key column="userid" />
<!-- 連接表中配置多對一,對應的字段爲roomid -->
<many-to-one name="room" column="roomid" not-null="true" />
</join>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping package="com.cosmow.hibernatedemo2.entity">
<class name="Userinfo" table="USERINFO" schema="STORE">
<id name="id" type="java.lang.Long">
<column name="ID" precision="4" scale="0" />
<!-- Oracle數據庫增長方式序列 -->
<generator class="sequence">
<param name="sequence">USERINFO_SEQ</param>
</generator>
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="32" not-null="true" />
</property>
<property name="sex" type="java.lang.String">
<column name="SEX" length="2" />
</property>
<!-- 使用join來配置多對一的連接,以table屬性來表示連接表的多對一,連接表爲roomusers -->
<!-- optional屬性表示這是一個外連接,inverse屬性可以出現在一端和多端,這裏選擇出現在多端,效果相同 -->
<join table="roomusers" optional="true" inverse="true">
<!-- 該key的字段爲連接表中的字段,作爲外鍵 -->
<key column="userid" />
<!-- 連接表中配置多對一,對應的字段爲roomid -->
<many-to-one name="room" column="roomid" not-null="true" />
</join>
</class>
</hibernate-mapping>
使用連接表最大的不同如下:
一端:
1.在<set>元素中需要增加table屬性,以表示這是一個連接表的關係。
2.將不使用連接表一對多的<one-to-many>,改爲<many-to-many>,並增加unique屬性
3.在<set>元素中的所有字段都將針對連接表(table屬性所指定的表)
多端:
1.使用<join>元素來配置多端的連接。
2.在<join>元素中,所有字段都針對連接表(table屬性所指定的表)
測試代碼如下:
實體類Room
package com.cosmow.hibernatedemo2.entity;
import java.util.Set;
/** *//**
* Room generated by MyEclipse Persistence Tools
*/
public class Room implements java.io.Serializable {
// Fields
private static final long serialVersionUID = 1L;
private Long id;
private String roomnumber;
private String name;
private Set<Userinfo> users;
// Constructors
/** *//** default constructor */
public Room2() {
}
// Property accessors
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoomnumber() {
return this.roomnumber;
}
public void setRoomnumber(String roomnumber) {
this.roomnumber = roomnumber;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set<Userinfo> getUsers() {
return users;
}
public void setUsers(Set<Userinfo> users) {
this.users = users;
}
}
import java.util.Set;
/** *//**
* Room generated by MyEclipse Persistence Tools
*/
public class Room implements java.io.Serializable {
// Fields
private static final long serialVersionUID = 1L;
private Long id;
private String roomnumber;
private String name;
private Set<Userinfo> users;
// Constructors
/** *//** default constructor */
public Room2() {
}
// Property accessors
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoomnumber() {
return this.roomnumber;
}
public void setRoomnumber(String roomnumber) {
this.roomnumber = roomnumber;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set<Userinfo> getUsers() {
return users;
}
public void setUsers(Set<Userinfo> users) {
this.users = users;
}
}
實體類Userinfo
package com.cosmow.hibernatedemo2.entity;
/** *//**
* Userinfo generated by MyEclipse Persistence Tools
*/
public class Userinfo implements java.io.Serializable {
// Fields
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private String sex;
private Room2 room;
// Constructors
/** *//** default constructor */
public Userinfo() {
}
// Property accessors
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Room2 getRoom() {
return room;
}
public void setRoom(Room2 room) {
this.room = room;
}
}
/** *//**
* Userinfo generated by MyEclipse Persistence Tools
*/
public class Userinfo implements java.io.Serializable {
// Fields
private static final long serialVersionUID = 1L;
private Long id;
private String name;
private String sex;
private Room2 room;
// Constructors
/** *//** default constructor */
public Userinfo() {
}
// Property accessors
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Room2 getRoom() {
return room;
}
public void setRoom(Room2 room) {
this.room = room;
}
}
test
public void test() {
Room room = new Room();
room.setName("cosmoHome");
room.setRoomnumber("001");
Userinfo user = new Userinfo();
user.setName("cosmo");
user.setSex("M");
user.setRoom(room);
Set<Userinfo> userSet = new HashSet<Userinfo>();
userSet.add(user);
room.setUsers(userSet);
// 啓動Session
Session session = HibernateSessionFactory.getSession();
// 啓動事務
Transaction tx = session.beginTransaction();
// 持久化room實體
session.save(room);
tx.commit();
HibernateSessionFactory.closeSession();
// 啓動Session
session = HibernateSessionFactory.getSession();
// 啓動事務
tx = session.beginTransaction();
Room room1 = (Room)session.get(Room.class, room.getId());
session.delete(room1);
tx.commit();
HibernateSessionFactory.closeSession();
}
Room room = new Room();
room.setName("cosmoHome");
room.setRoomnumber("001");
Userinfo user = new Userinfo();
user.setName("cosmo");
user.setSex("M");
user.setRoom(room);
Set<Userinfo> userSet = new HashSet<Userinfo>();
userSet.add(user);
room.setUsers(userSet);
// 啓動Session
Session session = HibernateSessionFactory.getSession();
// 啓動事務
Transaction tx = session.beginTransaction();
// 持久化room實體
session.save(room);
tx.commit();
HibernateSessionFactory.closeSession();
// 啓動Session
session = HibernateSessionFactory.getSession();
// 啓動事務
tx = session.beginTransaction();
Room room1 = (Room)session.get(Room.class, room.getId());
session.delete(room1);
tx.commit();
HibernateSessionFactory.closeSession();
}