1.集合的映射配置
<span style="font-size:14px;"><!--
1. set集合映射
name 要映射的set集合属性
table 集合属性对应的表(集合从哪个表获取); 集合表
key 集合表的外键 (只要通过key指定外键,会自动关联当前表的主键!)
element 集合表的存储数据的字段!
-->
<set name="addressSet" table="t_addressSet">
<key column="user_id"></key>
<element column="address" type="string"></element>
</set>
<!--
2. list集合映射
index 指定集合表(t_addressList)中的排序字段!
-->
<list name="addressList" table="t_addressList">
<key column="user_id"></key>
<index column="idx" type="int"></index>
<element column="address" type="string"></element>
</list>
<!--
3. map集合映射
map-key 集合的key对应的字段
element 集合的value对应的字段
-->
<map name="addressMap" table="t_addressMap">
<key column="user_id"></key>
<map-key column="shortName" type="string"></map-key>
<span style="white-space:pre"> </span><element column="address" type="string"></element>
</map></span>
2.多对一映射
<span style="font-size:14px;"><!--
多的一方含有一的一方的对象.(其普通余部分略)
多对一映射:
(映射地址中用户对象:多个地址对应一个用户)
name 映射的对象属性
column 对象属性,对应的数据库中外键字段
class 对象的类型
找到映射文件,外键应用的就是这个映射文件中主键!
-->
<many-to-one name="user" class="User" column="user_id"></many-to-one></span>
<span style="font-size:14px;"> //测试
public void testSave(){
Session session = sf.openSession();
session.beginTransaction();
//user对象
User user = new User();
user.setAge(25);
user.setName("班长");
user.setSex('男');
// 地址
Address address = new Address();
address.setProvince("广东");
address.setCity("广州");
address.setCode("51000");
// 设置表的关系
address.setUser(user);
/*
* 保存
*/
// 生成2条insert + update
//session.save(address); // 先插入地址,但这个时候用户为null
//session.save(user); // 再插入用户; 最后再通过update语句维护关系
// 生成2条insert
session.save(user);
session.save(address);
//所以数据的保存与顺序无关,但第二种可以提高效率
session.getTransaction().commit();
session.close();
}</span>
<span style="font-size:14px;"> public void testGet(){
Session session = sf.openSession();
session.beginTransaction();
// 获取地址
Address address = (Address) session.get(Address.class, 1);
System.out.println(address.getProvince());
System.out.println(address.getCity());
System.out.println(address.getAddress());
// -- user --
System.out.println(address.getUser().getName());
System.out.println(address.getUser().getSex());
session.getTransaction().commit();
session.close();
}</span></span>
3.一对多映射
<span style="font-size:14px;"><!--
一的一方含有多的一方的对象集合.
一对多的映射
name 指定映射的集合属性
table 集合属性对应的表(集合表)
可选; 如果不写,会找类型对应的映射文件中的表!
key 集合表的外键字段
class 集合元素的类型!
-->
<set name="addresses" table="t_address">
<key column="user_id"></key>
<one-to-many class="Address"/>
</set></span>
4.多对多映射
双方都是一对多的关系,即双方都含有另一方的对象集合.
a.在维护(设置)表的关系时,不能重复重复维护关系.
5.inverse控制权设置
用于配置中<set inverse="false">节点中,即一对多/多对多的情况下.
inverse代表控制权,若为false,表示当前表有控制权,可以更方便的维护表的关系.
若为true,即解除关系,当前表没有控制权,无法删除被另一张表引用的数据.当然程序不会报错.只是无法删除数据.
如:当前表的字段被另一个表引用,当前表不需顾虑引用,可以直接删除当前表数据,而外键表的引用会被更新为null.
后台自动维护表的关系.但也造成了数据不安全因素.
注意:
一对多的情况:
Hibernate: select dept0_.id as id0_0_, dept0_.deptName as deptName0_0_ from t_dept dept0_ where dept0_.id=?
Hibernate: update t_employee set dept_id=null where dept_id=?
Hibernate: delete from t_dept where id=?
即,一对多时,当删除主键表的数据之前,会先将外键表的外键引用情况,设为null,再删除数据.
多对多的情况:
Hibernate: select project0_.id as id0_0_, project0_.pName as pName0_0_ from t_project project0_ where project0_.id=?
Hibernate: delete from t_relation where pid=?
Hibernate: delete from t_project where id=?
-----------------------------------------------
Hibernate: select se0_.id as id2_0_, se0_.sName as sName2_0_ from t_se se0_ where se0_.id=?
Hibernate: delete from t_relation where sid=?
Hibernate: delete from t_se where id=?
即,多对多时,当删除一张表的数据前,先删除关系表的对应数据,然后再删除要删除的数据.
只有要用数据时才会查询数据库.
默认支持懒加载.
可以在映射配置文件的<set>/<many-to-many>/<many-to-one>节点上设置.表示当用到数据时才会查询数据库.
Lazy 值:
true 支持懒加载(默认值)
false 关闭懒加载
extra 支持懒加载; 在真正使用数据的时候才向数据库发送查询的sql;
如果只是调用size()/isEmpty()方法,只会统计.