映射文件也相同,只需要去掉unique="true"即可。
[html]
7.5、双向1-N关联
双向的1-N关联的持久化类,N的一端增加引用到关联实体的属性,1的一端增加集合属性,集合元素为关联实体。
1、基于无连接表的双向1-N关联
对于基于无连接表的双向1-N关联的映射文件,需要在N的一端增加
1的一端的映射文件
[html]
N的一端的映射文件
[html]
2、基于连接表的双向1-N关联
1的一端使用集合元素映射,然后在集合元素里增加
1的一端映射文件
[html]
N的一端映射文件
[html]
这里必须要保证以下三队相等:两个table的值要相等、
7.6、双向N-N关联
双向N-N关联需要两端都使用Set集合属性,两端都增加对集合属性的访问。
[html]
[html]
7.7、双向1-1关联
双向的1-1关联同样有这样三种映射方式:基于外键、基于连接表、基于主键
1、基于外键的双向1-1关联
基于外键的1-1关联,外键可以存放在任意一边。需要存放外键的一端,需要增加
另一端需要使用
[html]
[html]
2、基于连接表的双向关联
双向1-1关联两端都需要使用
[html]
[html]
3、基于主键的双向关联
在任意一端采用foreign主键生成器策略。两端同时使用
[html]
person
[html] view plaincopyprint
这里关于关联映射要注意以下几点:
1、对于所有的基于外键约束的关联关系中,要么选择先持久化主表记录对应的实体,要么是有级联操作
2、对于1-N关联关系而言,我们一般都采用N的一端控制关联关系
3、N-N的关联关系都需要使用连接表策略来进行映射
4、单向关联更加难于查询。在大型应用中,几乎所有的关联必须在查询中可以双向导航。
7.8、组件属性包含的关联实体
对于组件属性的关联实体的映射文件使用
[html]
八、Hibernate的批量处理
Hibernate在对大数据进行更新的时候,会抛出OutOfMemoryException(内存溢出)异常。有如下方案解决这个问题:定时将Session缓存的数据刷入数据库。设计一个累加器,每次更新一次数据,累加器就加1更加累加器的值决定是否需要将Session缓存中的数据刷入数据库。
[html]
static void addUser() throws Exception{
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//循环1000次,插入1000条记录
for(int i = 0;i < 100000;i++){
//创建User对象
User user = new User();
user.setName("userName"+i);
user.setAge(i);
//在session级别缓存User实例
session.save(user);
//每当累加器是20的倍数的时候,将session中数据刷入数据库,并且情况session缓存
if(i%20==0){
session.flush();
session.clear();
}
}
同时也可以使用DML风格进行批量处理。
[java]
//使用DML风格的批量删除
static void deleteUser() throws Exception{
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//定义批量更新的HQL语句
String hql = "delete User";
//执行删除
session.createQuery(hql).executeUpdate();
tx.commit();
session.close();
}
九、Hibernate的继承映射策略
对于面向对象的程序设计的语言,继承、多态是两个最基本的概念。Hibernate的继承映射可以理解两个持久化类之间的继承关系。Hibernate采用如下三种策略来完成继承映射:subclass、joined-subclass、union-subclass。
subclass:采用这种映射策略