我们学习了hibernate的一对一和一对多,下面就剩下一个多对多啦,这次我们就来学习一下它的多对多关联映射。
废话不多说,直接上代码:
这次我们举的例子是Group和Role,一般情况下,我们一个组可以对应多个角色,同时一个角色也可以对应多个组。
先看一下实体类代码:
public class TGroup implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String name;
private Set<TRole> roles = new HashSet<TRole>();
//省略Get/Set方法
}
public class TRole implements Serializable{
private static final long serialVersionUID = 1L;
private int id;
private String name;
private Set<TGroup> groups = new HashSet<TGroup>();
//省略Get/Set方法
}
简单的实体类,在看映射文件之前我们需要说明一下多对多映射与之前讲的映射不同的地方。
多对多映射需要用到另外一张关联表,用以关联两个表的ID。
我们看一下映射文件:
<hibernate-mapping package="org.hibernate.tutorial.domain7">
<class name="TGroup" table="t_group" dynamic-insert="true" dynamic-update="true">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String" column="name"/>
<set name="roles" table="t_group_role" lazy="false" cascade="save-update">
<key column="group_id"/>
<many-to-many class="TRole" column="role_id" />
</set>
</class>
</hibernate-mapping>
这里我们用到了一个中间表,t_group_role,在该表中指定了此表对应的列group_id,另外一个不同的地方就是我们设置了lazy="false",这个属于懒惰加载机制的内容,我们以后会讲到。这里先大概了解一下,把它设为false(也是默认值),它表明这个实体会在hibernate加载的时候全部加载进来。如果设为true,则表明当我们需要访问到此属性时才进行取出(这里的访问是指调用get方法等)。
我们再看一下另外一个映射文件:
<hibernate-mapping package="org.hibernate.tutorial.domain7">
<class name="TRole" table="t_role" dynamic-insert="true" dynamic-update="true">
<id name="id" column="id">
<generator class="native" />
</id>
<property name="name" type="java.lang.String" column="name"/>
<set name="groups" table="t_group_role" lazy="false" inverse="true" cascade="save-update">
<key column="role_id"/>
<many-to-many class="TGroup" column="group_id" />
</set>
</class>
</hibernate-mapping>
两个表的映射文件变化不大,主要是这里有inverse="true"表明把插入权交给TGroup,即当TGroup进行保存的时候,会把user_id和group_id同时进行插入。
下面我们看一下测试类,由于是多对多关联,类会比较长:
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
TRole role1 = new TRole();
role1.setName("role1");
TRole role2 = new TRole();
role2.setName("role2");
TRole role3 = new TRole();
role3.setName("role3");
TGroup group1 = new TGroup();
group1.setName("group1");
TGroup group2 = new TGroup();
group2.setName("group2");
TGroup group3 = new TGroup();
group3.setName("group3");
role1.getGroups().add(group1);
role1.getGroups().add(group2);
role2.getGroups().add(group2);
role2.getGroups().add(group3);
role3.getGroups().add(group1);
role3.getGroups().add(group2);
group1.getRoles().add(role1);
group1.getRoles().add(role2);
group2.getRoles().add(role2);
group2.getRoles().add(role3);
group3.getRoles().add(role2);
group3.getRoles().add(role3);
session.save(role1);
session.save(role2);
session.save(role3);
session.save(group1);
session.save(group2);
session.save(group3);
session.getTransaction().commit();
session.close();
}
运行此测试类,我们可以看到输出的语句为:
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
插入的语句与我们前面通过add有关联,这个可以自己仔细看一下,只是数数的问题而已。
也许,某些童鞋看到这里,又会想想说如果去掉inverse="true"会是什么情况呢?
那么我们来试一下:
把inverse="true"去掉,然后再运行测试类:我们同样看到插入语句,但紧跟着的是异常,看看是什么异常:
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_role (name) values (?)
Hibernate: insert into t_group (name) values (?)
Hibernate: insert into t_group_role (role_id, group_id) values (?, ?)
Hibernate: insert into t_group_role (role_id, group_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (group_id, role_id) values (?, ?)
Hibernate: insert into t_group_role (role_id, group_id) values (?, ?)
Hibernate: insert into t_group_role (role_id, group_id) values (?, ?)
22:23:46,062 ERROR JDBCExceptionReporter:101 - Duplicate entry '13-14' for key 'PRIMARY'
22:23:46,064 ERROR AbstractFlushingEventListener:324 - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
重复的记录,这个错误看来是插入了两条重复的记录,肯定两个字段都相同,而后一个异常是因为找不到需要更新的记录。这个的原因是因为我们没有指定inverse="true",那么两个表都对t_gropu_role有责任,就因为这样,它们都会进行插入,这也就超成了前面的错误,而后面的错误更多的是由前面的错误所引起的。
分享到:
相关推荐
hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,包含4个说明文档,分别详细解说了hibernate关联映射的...
总之,Hibernate的多对多关联映射是解决复杂关系数据库设计的关键技术之一。通过合理的配置和使用,开发者可以轻松管理实体之间的多对多关系,提高开发效率。理解并熟练掌握这部分知识对于提升Java企业级应用开发...
本文将深入探讨“hibernate关联映射实例”中的关键知识点,包括一对多、多对多和继承映射,这些都是Hibernate中至关重要的概念。 1. **一对多关联映射**: 在现实世界中,一个实体可能会与多个其他实体相关联,...
### Hibernate关联映射总结 #### 一、基础知识 在探讨Hibernate中的关联映射之前,我们需要先理解几个基本概念,这将有助于我们更好地理解和应用这些关联映射。 - **主键**(Primary Key):主键是用来唯一标识一...
### Hibernate关联映射的作用与常用属性详解 #### 关联映射概述 在对象关系映射(Object Relational Mapping,简称ORM)技术中,Hibernate作为Java领域内非常成熟且功能强大的框架之一,它允许开发者将Java类映射...
9. Hibernate 一对一外键双向关联、主键双向关联、连接表双向关联、一对多外键双向关联、一对多连接表双向关联、多对多双向关联: 这些关联方式与单向关联类似,区别在于两个实体类都知道彼此的关联。在双向关联中...
总之,Hibernate的关联映射是其强大之处,能够帮助开发者轻松处理复杂的数据库关系。SSH框架结合了MVC设计模式、依赖注入和持久化管理,为Java Web开发提供了一套完整的解决方案。通过深入学习和实践,我们可以更好...
在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系模型,它用于处理两个实体类之间存在多个对应关系的情况。这篇博客"hibernate多对多关联映射(单项关联)"深入探讨了如何在Hibernate中实现这种映射...
在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是一种常见的关系数据库模型映射方式。这种关联通常发生在两个实体之间,且每个实体都只有一个对应的实例。本篇文章将详细探讨双向一对一主键关联映射...
本教程“Hibernate关联映射.rar”聚焦于Hibernate中的关联映射,特别是多对一和一对多的关系映射,非常适合初学者了解和实践。 首先,我们要理解什么是关联映射。在数据库中,表与表之间存在各种关系,如一对一、一...
本主题将深入探讨Hibernate集合映射与关联关系,包括"student与Score的Map集合关系"、"student与class的多对一"以及"一对多映射"的概念。 首先,让我们理解一下Hibernate中的集合映射。在关系型数据库中,一个实体...
本练习主要关注的是Hibernate中的单向多对多关联映射,这是一种常见的关系数据库设计模式,用于表示两个实体间复杂的关系。 在多对多关联中,两个实体类可以相互拥有多个实例,但只在一个方向上建立关联。例如,...
在深入探讨Hibernate关联关系映射分类之前,我们首先简要回顾一下Hibernate框架的基本概念。Hibernate是一种持久层框架,主要用于Java应用程序中的对象关系映射(ORM),它能够将面向对象的数据模型转换为数据库中的...
在Java的持久化框架Hibernate中,双向多对多关联映射是一种常见的数据关系模型,它允许两个实体类之间存在多个实例互相引用的情况。本练习旨在帮助开发者深入理解并熟练运用这种映射方式。通过以下详细讲解,我们将...
总的来说,这个压缩包提供了丰富的Hibernate关联映射的学习资源,涵盖了从基础到进阶的各种关联类型。通过学习这些示例,你将能够熟练掌握如何在Java项目中使用Hibernate进行数据持久化,并灵活地处理各种数据库关系...
在这个“hibernate双向多对多关联映射(注解版)”的主题中,我们将深入探讨如何使用Hibernate的注解配置来处理数据库中的双向多对多关联关系。 首先,多对多关联在数据库设计中是指两个实体之间存在多个对应关系,...
本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...
### Hibernate映射一对多关联关系 #### 知识点概览 - **概念解析**:一对多(One-to-Many)关联关系的概念及其在Hibernate中的实现方式。 - **域模型设计**:创建具有一个实体与多个实体关联的域模型。 - **关系...