Hibernate的单、双向关联(二)
来源:互联网 发布:apache设置虚拟路径 编辑:程序博客网 时间:2024/06/12 19:47
6.3 问题:在Hibernate中配置连接表
6.3.1 提出问题
设计师L在了解了连接表的优点之后,就将数据库中的一些必要的表-表关系设计成了连接表。程序员M使用Hibernate框架来完成开发时提出了问题:在Hibernate框架中如何配置连接表?配置的连接表对于具体持久化方法的调用会有什么影响?
6.3.2 在Hibernate中的连接表配置
首先看一个例子。Room实体与UserInfo实体是一对多关系,room2表与userinfo2表通过一张连接表来表现这层关系,连接表为roomusers。将来在连接表中可以出现room2表与userinfo2表的主键来维护关系。由于Room实体与UserInfo实体是一对多,因此在roomusers连接表中,userinfo2表的主键是惟一的。
针对这个例子,其在Hibernate中的映射文件将会如下配置,见例6.18。
例6.18:一对多连接表映射文件
Room2.hbm.xml(一端的配置)
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java.lang.String"/>
<!-- 通过连接表的一端,因此需要table属性为roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="roomid"></key>
<!-- 配置多对多 -->
<!-- 但是unique属性为true,表示userid字段为不可重复,保证一对多关系 -->
<many-to-many class="UserInfo" unique="true" column="userid"> </many-to-many>
<!-- 在多对多中只要设置unique="true"即可以等同认为是一对多 -->
</set>
</class>
</hibernate-mapping>
UserInfo2.hbm.xml(多端的配置)
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true" />
<property name="sex" column="SEX" type="java.lang.String" />
<!-- 使用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属性所指定的表)。
随后是针对连接表一对多的客户端的实现代码,该段代码与不使用连接表的一对多几乎一致,见例6.19。
例6.19:连接表一对多的操作
public void run() {
//创建Room实体
Room room = new Room();
//设置Room.name
room.setName("rwhome");
//设置Room.roomnumber
room.setRoomnumber("001");
//创建UserInfo实体
UserInfo userInfo = new UserInfo();
//设置UserInfo.name
userInfo.setName("rw");
//设置UserInfo.sex
userInfo.setSex("M");
//保证UserInfo实体得到与Room实体的关系,以帮助由连接表来维护一对多关联
userInfo.setRoom(room);
//创建UserInfo集合userInfoSet
Set userInfoSet = new HashSet();
//添加UserInfo实体到集合userInfoSet
userInfoSet.add(userInfo);
//设置Room.users(这是一个集合类型)
room.setUsers(userInfoSet);
//创建Hibernate Session
Session session = HibernateSessionFactory.currentSession();
//启动事务
Transaction tx = session.beginTransaction();
//持久化Room实体
//此时将更新表room2和userinfo2以及维护关系的roomusers表
①session.save(room);
//提交事务
tx.commit();
//关闭Hibernate Session
HibernateSessionFactory.closeSession();
session = HibernateSessionFactory.currentSession();
tx = session.beginTransaction();
//获取Room实体以成为持久化状态,此时将获取room2表的所有字段信息
//通过外连接roomusers获取userinfo2表的所有字段信息
②Room room1 = (Room)session.get(Room.class, room.getId());
//删除room2表对应的userinfo2表以及连接表roomusers中的相关记录
③session.delete(room1);
tx.commit();
HibernateSessionFactory.closeSession();
}
针对该段代码的SQL语句如下:
Hibernate:
/* ①session.save(room)的动作,插入表room2 */
insert
into
room2
(NAME, roomnumber, id)
values
(?, ?, ?)
Hibernate:
/* ①session.save(room)的动作,插入表userinfo2 */
insert
into
userinfo2
(NAME, SEX, id)
values
(?, ?, ?)
Hibernate:
/* ①session.save(room)的动作,插入表roomusers,维护关系*/
insert
into
roomusers
(roomid, userid)
values
(?, ?)
Hibernate:
/* ②Room room1 = (Room)session.get(Room.class, room.getId())的动作,获取room2表的信息 */
select
room0_.id as id2_0_,
room0_.NAME as NAME2_0_,
room0_.roomnumber as roomnumber2_0_
from
room2 room0_
where
room0_.id=?
Hibernate:
/*②Room room1 = (Room)session.get(Room.class, room.getId())的动作,通过连接表获取userinfo2表的信息*/
select
users0_.roomid as roomid1_,
users0_.userid as userid1_,
userinfo1_.id as id0_0_,
userinfo1_.NAME as NAME0_0_,
userinfo1_.SEX as SEX0_0_,
userinfo1_1_.roomid as roomid1_0_
from
roomusers users0_
left outer join
userinfo2 userinfo1_
on users0_.userid=userinfo1_.id
left outer join
roomusers userinfo1_1_
on userinfo1_.id=userinfo1_1_.userid
where
users0_.roomid=?
Hibernate:
/* ③session.delete(room1)的动作,删除roomusers连接表记录 */
delete
from
roomusers
where
roomid=?
Hibernate:
/* ③session.delete(room1)的动作,删除userinfo2表记录 */
delete
from
userinfo2
where
id=?
Hibernate:
/* ③session.delete(room1)的动作,删除room2表记录 */
delete
from
room2
where
id=?
可以看到,针对连接表的一对多关联,其操作在Hibernate中是连动3张表的。而且在获取实体时,将通过映射配置的optional属性来保证外连接的关系获取。
6.3.3 多对多连接表配置和实现
连接表的配置最常见的使用是维护多对多关系,假设Room实体和UserInfo实体是一个多对多关系,那么其映射配置见例6.20。
例6.20:维护Room实体和UserInfo实体多对多关系
Room2.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">
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java. lang.String"/>
<!-- 通过连接表的多端,因此需要table属性为roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="roomid"></key>
<!-- 连接表中配置多对多 -->
<many-to-many class="UserInfo" column="userid"></many-to-many>
</set>
</class>
</hibernate-mapping>
UserInfo2.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">
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true" />
<property name="sex" column="SEX" type="java.lang.String" />
<!-- 通过连接表的多端,因此需要table属性为roomusers -->
<set name="rooms" cascade="all" table="roomusers">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="userid"></key>
<!-- 连接表中配置多对多 -->
<many-to-many class="Room" column="roomid"></many-to-many>
</set>
</class>
</hibernate-mapping>
可以看到,在两个实体映射文件中都配置了many-to-many关系,这样的配置已经可以通过任意一个多端来维护另一端。实现持久化的代码见例6.21。
例6.21:实现持久化
public void run() {
//创建Room实体
Room room = new Room();
//设置Room.name
room.setName("rwhome");
//设置Room.roomnumber
room.setRoomnumber("001");
//创建第二个Room实体
Room room2 = new Room();
//设置Room.name
room2.setName("rwhome2");
//设置Room.roomnumber
room2.setRoomnumber("002");
//创建UserInfo实体
UserInfo userInfo = new UserInfo();
//设置UserInfo.name
userInfo.setName("rw");
//设置UserInfo.sex
userInfo.setSex("M");
//创建第二个UserInfo实体
UserInfo userInfo2 = new UserInfo();
//设置UserInfo.name
userInfo2.setName("rw2");
//设置UserInfo.sex
userInfo2.setSex("M2");
//创建第二个UserInfo实体与第二个Room实体的关系,通过连接表维护关系
①Set roomSet = new HashSet();
roomSet.add(room2);
userInfo2.setRooms(roomSet);
//创建第一个Room实体与第一、第二个UserInfo实体的关系,通过连接表维护关系
//添加UserInfo实体到集合userInfoSet
②Set userInfoSet = new HashSet();
userInfoSet.add(userInfo);
userInfoSet.add(userInfo2);
room.setUsers(userInfoSet);
//创建Hibernate Session
Session session = HibernateSessionFactory.currentSession();
//启动事务
Transaction tx = session.beginTransaction();
//持久化Room实体
//此时将更新表room2和userinfo2以及维护关系的roomuser表
③session.save(room);
//提交事务
tx.commit();
//关闭Hibernate Session
HibernateSessionFactory.closeSession();
session = HibernateSessionFactory.currentSession();
tx = session.beginTransaction();
//获取Room实体以成为持久化状态,此时将获取room2表的所有字段信息
④Room roomF1 = (Room)session.get(Room.class, room.getId());
//通过外连接roomusers获取userinfo2表的对应字段信息
⑤Iterator iF1 = roomF1.getUsers().iterator();
while(iF1.hasNext()) {
UserInfo userInfoF = (UserInfo)iF1.next();
System.out.println(userInfoF.getId());
System.out.println(userInfoF.getName());
System.out.println(userInfoF.getSex());
}
//获取Room实体以成为持久化状态,此时将获取room2表的所有字段信息
⑥Room roomF2 = (Room)session.get(Room.class, room2.getId());
//通过外连接roomusers获取userinfo2表的对应字段信息
⑦Iterator iF2 = roomF2.getUsers().iterator();
while(iF2.hasNext()) {
UserInfo userInfoF = (UserInfo)iF2.next();
System.out.println(userInfoF.getId());
System.out.println(userInfoF.getName());
System.out.println(userInfoF.getSex());
}
tx.commit();
HibernateSessionFactory.closeSession();
}
针对该段代码的SQL语句如下:
Hibernate:
/* ③session.save(room)的动作,插入第一个Room实体 */
insert
into
room2
(NAME, roomnumber, id)
values
(?, ?, ?)
Hibernate:
/* ③session.save(room)的动作,通过②的动作,插入第二个UserInfo实体*/
insert
into
userinfo2
(NAME, SEX, id)
values
(?, ?, ?)
Hibernate:
/* ③session.save(room)的动作,通过①的动作,插入第二个Room实体*/
insert
into
room2
(NAME, roomnumber, id)
values
(?, ?, ?)
Hibernate:
/* ③session.save(room)的动作,通过②的动作,插入第一个UserInfo实体*/
insert
into
userinfo2
(NAME, SEX, id)
values
(?, ?, ?)
Hibernate:
/* ③session.save(room)的动作,通过②的动作,维护第一个Room实体和第一个UserInfo实体关系*/
insert
into
roomusers
(roomid, userid)
values
(?, ?)
Hibernate:
/* ③session.save(room)的动作,通过②的动作,维护第一个Room实体和第二个UserInfo实体关系*/
insert
into
roomusers
(roomid, userid)
values
(?, ?)
Hibernate:
/* ③session.save(room)的动作,通过②的动作,维护第二个UserInfo实体和第一个Room实体关系*/
insert
into
roomusers
(userid, roomid)
values
(?, ?)
Hibernate:
/* ④Room roomF1 = (Room)session.get(Room.class, room.getId())的动作,获取第一个Room实体 */
select
room0_.id as id2_0_,
room0_.NAME as NAME2_0_,
room0_.roomnumber as roomnumber2_0_
from
room2 room0_
where
room0_.id=?
Hibernate:
/* ⑤Iterator iF1 = roomF1.getUsers().iterator()的动作,通过连接表获取多个UserInfo实体,在本实现中对应将获取两条UserInfo实体记录 */
select
users0_.roomid as roomid1_,
users0_.userid as userid1_,
userinfo1_.id as id0_0_,
userinfo1_.NAME as NAME0_0_,
userinfo1_.SEX as SEX0_0_
from
roomusers users0_
left outer join
userinfo2 userinfo1_
on users0_.userid=userinfo1_.id
where
users0_.roomid=?
Hibernate:
/* ⑥Room roomF2 = (Room)session.get(Room.class, room2.getId())的动作,获取第二个Room实体 */
select
room0_.id as id2_0_,
room0_.NAME as NAME2_0_,
room0_.roomnumber as roomnumber2_0_
from
room2 room0_
where
room0_.id=?
Hibernate:
/* ⑦Iterator iF2 = roomF2.getUsers().iterator()的动作,通过连接表获取多个UserInfo实体,在本实现中对应只会获取一条UserInfo实体记录 */
select
users0_.roomid as roomid1_,
users0_.userid as userid1_,
userinfo1_.id as id0_0_,
userinfo1_.NAME as NAME0_0_,
userinfo1_.SEX as SEX0_0_
from
roomusers users0_
left outer join
userinfo2 userinfo1_
on users0_.userid=userinfo1_.id
where
users0_.roomid=?
通过本实现可以看到,对于多对多关系的维护在任意一个多端都可以进行。对于持久化方式的实现,不用考虑连接表,只对实体进行关系的维护可以直接影响连接表。
6.3.4 其他通过连接表的映射配置
在之前的小节中已经给出了一对多/多对一、多对多的两种映射配置和持久化实现。其实在Hibernate中,还支持更多的连接表关系映射。这里作一个总结并给出映射配置。
(1)一对多单向映射配置:与一对多/多对一双向关系配置类似,只是在多端不需要使用join元素来配置与一端的关联,见例6.22。
例6.22:连接表单向一对多的映射文件
Room2.hbm.xml(一端的配置)
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java. lang.String"/>
<!-- 通过连接表的一端,因此需要table属性为roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="roomid"></key>
<!-- 配置多对多 -->
<!-- 但是unique属性为true,表示userid字段为不可重复,保证一对多关系 -->
<many-to-many class="UserInfo" unique="true" column="userid"> </many-to-many>
<!-- 在多对多中只要设置unique="true"即可以等同认为是一对多 -->
</set>
</class>
</hibernate-mapping>
UserInfo2.hbm.xml(多端的配置)
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true" />
<property name="sex" column="SEX" type="java.lang.String" />
</class>
</hibernate-mapping>
连接表的单向一对多关系只能通过一端来维护关系,而在抓取信息时,通过多端是无法抓取到一端信息的。在通过一端抓取多端记录时,将会执行外连接语句的SQL。连接表的单向一对多比非连接表的单向一对多建模语义要清晰得多,在效率上也不低,因此非常常见。
(2)多对一单向映射配置。与一对多/多对一双向关系配置类似,只是在一端不需要使用set元素来配置与多端的关联,见例6.23。
例6.23:连接表单向多对一的映射文件
Room2.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">
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java. lang.String"/>
</class>
</hibernate-mapping>
UserInfo2.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">
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true" />
<property name="sex" column="SEX" type="java.lang.String" />
<!-- 使用join来配置多对一的连接,以table属性来表示连接表的多对一,连接表为roomusers -->
<!-- optional属性表示这是一个外连接 -->
<join table="roomusers" optional="true">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="userid" />
<!-- 连接表中配置多对一,对应的字段为roomid -->
<many-to-one name="room" class="Room" column="roomid" not-null="true"/>
</join>
</class>
</hibernate-mapping>
使用连接表的单向多对一关系是非常常见的,在通过多端抓取一端记录时,仅通过外连接连接表获取一端的主键或实体。
(3)连接表的单向一对一关系并不常见,只需在单向一对多的一端映射配置中设置属性unique即可,这里不做具体介绍。
(4)连接表的单向多对多关系也并不常见,这里仅给出其映射配置,见例6.24。
例6.24:连接表的单向多对多映射
Room2.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">
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java. lang.String"/>
<!-- 通过连接表的多端,因此需要table属性为roomusers -->
<set name="users" cascade="all" table="roomusers">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="roomid"></key>
<!-- 连接表中配置多对多 -->
<many-to-many class="UserInfo" column="userid"></many-to-many>
</set>
</class>
</hibernate-mapping>
UserInfo2.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">
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null="true" />
<property name="sex" column="SEX" type="java.lang.String" />
</class>
</hibernate-mapping>
(5)连接表的双向一对一关系并不常见,其配置映射需要在两端都配置<join>元素,见例6.25。
例6.25:连接表的双向一对一映射配置
Room2.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">
<hibernate-mapping package="testhibernate">
<class name="Room" table="room2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="roomnumber" column="roomnumber" type="java. lang.String"/>
<!-- 使用join来配置一对一的连接,以table属性来表示连接表的一对一,连接表为roomusers -->
<!-- optional属性表示这是一个外连接 -->
<join table="roomusers" optional="true">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="roomid" unique="true"/>
<!-- 连接表中配置一对一,对应的字段为roomid -->
<many-to-one name="user" class="UserInfo" column="userid" not-null=" true" unique="true"/>
</join>
</class>
</hibernate-mapping>
UserInfo2.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">
<hibernate-mapping package="testhibernate">
<class name="UserInfo" table="userinfo2">
<id name="id" column="id" type="java.lang.Long">
<generator class="increment" />
</id>
<property name="name" column="NAME" type="java.lang.String" not-null=" true" />
<property name="sex" column="SEX" type="java.lang.String" />
<!-- 使用join来配置一对一的连接,以table属性来表示连接表的一对一,连接表为roomusers -->
<!-- optional属性表示这是一个外连接 -->
<join table="roomusers" optional="true">
<!-- 该key的字段为连接表中的字段,作为外键 -->
<key column="userid" unique="true"/>
<!-- 连接表中配置一对一,对应的字段为roomid -->
<many-to-one name="room" class="Room" column="roomid" not-null="true" unique="true"/>
</join>
</class>
</hibernate-mapping>
通过连接表来实现双向一对一关联并不是一个好办法,虽然Hibernate提供了这种方式,但是并不推荐使用。
6.3.5 结语
在Hibernate中提供了多种连接表关系映射的配置方案。其持久化实现并不用关心连接表,而是直接关注当前的实体,而框架在后台会根据配置自行对连接表进行维护来保证关系。因此在一定的条件下使用连接表的关系映射是非常有帮助的。下面是各种关系的一种比较。
1.实体一对多关系
(1)更新(获取)一端时同时更新(获取)多端,业务要求只通过一端来维护关系,使用双向一对多、单向一对多、连接表双向一对多、连接表单向一对多都可以,推荐使用双向一对多、连接表单向一对多。
(2)更新(获取)一端时同时更新(获取)多端,业务要求通过一端和多端都可维护关系,使用双向一对多、连接表双向一对多都可以,确定业务推荐双向一对多;扩展业务推荐连接表双向一对多。
2.实体多对多关系
(1)更新(获取)多端时同时更新(获取)另一多端,业务要求只通过一个多端来维护关系,使用连接表双向多对多、连接表单向多对多都可以,推荐使用连接表单向多对多。
(2)更新(获取)多端时同时更新(获取)另一多端,业务要求两个多端都可以维护关系,只能使用连接表双向多对多。
3.实体一对一关系
(1)更新(获取)一端时同时更新(获取)另一端,业务要求只通过一个一端来维护关系,使用双向一对一、单向一对一、连接表双向一对一、连接表单向一对一都可以,推荐使用单向一对一。
(2)更新(获取)一端时同时更新(获取)另一一端,业务要求两个一端都可维护关系,使用双向一对一、连接表双向一对一都可以,推荐使用双向一对一。
此书名:《揭密J2EE项目开发的70个问题》
以上内容摘自http://book.csdn.net/bookfiles/563/10056318683.shtml
- Hibernate的单、双向关联(二)
- 6.2.1 Hibernate的单、双向关联
- Hibernate的单、双向关联(一)
- Hibernate中的单,双向关联
- Hibernate单、双向关联与inverse属性
- Hibernate一对一单双向外键关联
- hibernate多对多关联--单双向
- Hibernate关联映射之多对多单/双向关联映射
- Hibernate的单向关联和双向关联
- hibernate 单向外键关联,一对一双向外间关联凡是双向关联必设mappedBy!!!
- 【Hibernate框架】使用链接表的关联映射(一对多/多对一、单/双向映射)
- 在Hibernate中,@OneToMany单/双向外键关联
- 在Hibernate中@ManyTOMany 单/双向外键关联
- Hibernate初学者---多对多单/双向关联
- Hibernate -- 一对多的双向关联关系
- 【Hibernate】双向关联的oneTomany练习
- Hibernate的双向1-N关联(五)
- Hibernate的双向N-N关联(六)
- scanf,sscanf高级用法
- ubuntu 3D桌面演示!
- windows 消息大全 与 虚拟键列表 HOOK专题
- 怎样缩小SQL Server数据库日志文件
- [多图] Ubuntu 8.04 中开启3D桌面特效与设置方法
- Hibernate的单、双向关联(二)
- 获取网页中的验证码图片
- MyPanel
- 一些学习java的网站
- MyTabPage
- 删除sql server2005 的日志文件
- SOAP协议
- java里面打印2个日期之间的所有日期
- isnull()函数的使用