• 领域模型:

  • 关系数据模型

  • 双向 n-n 关联须要两端都使用集合属性
  • 双向n-n关联必须使用连接表
  • 集合属性应添加 key 子元素用以映射外键列, 集合元素里还应添加many-to-many子元素关联实体类
  • 在双向 n-n 关联的两边都需指定连接表的表名及外键列的列名. 两个集合元素 set 的table 元素的值必须指定,并且必须同样。set元素的两个子元素:key 和 many-to-many
    都必须指定 column 属性。当中,key 和 many-to-many 分别指定本持久化类和关联类在连接表中的外键列名,因此两边的 key 与 many-to-many 的column属性交叉同样。也就是说,一边的set元素的key的 cloumn值为a,many-to-many 的 column 为b。则还有一边的 set 元素的 key 的 column
    值 b,many-to-many的 column 值为 a.
  • 对于双向 n-n 关联, 必须把当中一端的 inverse 设置为 true, 否则两端都维护关联关系可能会造成主键冲突.


代码具体解释:
Category.java
package com.atguigu.hibernate.n2n;

import java.util.HashSet;
import java.util.Set; public class Category { private Integer id;
private String name; private Set<Item> items = new HashSet<>(); public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Set<Item> getItems() {
return items;
} public void setItems(Set<Item> items) {
this.items = items;
} }

Item.java

package com.atguigu.hibernate.n2n;

import java.util.HashSet;
import java.util.Set; public class Item { private Integer id;
private String name; private Set<Category> categories = new HashSet<>(); public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
} }

Category.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.atguigu.hibernate.n2n"> <class name="Category" table="CATEGORIES"> <id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property> <!-- table: 指定中间表 -->
<set name="items" table="CATEGORIES_ITEMS">
<key>
<column name="C_ID" />
</key>
<!-- 使用 many-to-many 指定多对多的关联关系. column 运行 Set 集合中的持久化类在中间表的外键列的名称 -->
<many-to-many class="Item" column="I_ID"></many-to-many>
</set> </class>
</hibernate-mapping>

Item.hbm.xml

<?

xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.atguigu.hibernate.n2n.Item" table="ITEMS"> <id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id> <property name="name" type="java.lang.String">
<column name="NAME" />
</property> <set name="categories" table="CATEGORIES_ITEMS" inverse="true">
<key column="I_ID"></key>
<many-to-many class="com.atguigu.hibernate.n2n.Category" column="C_ID"></many-to-many>
</set> </class>
</hibernate-mapping>

package com.atguigu.hibernate.n2n;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.Set; import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.jdbc.Work;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest { private SessionFactory sessionFactory;
private Session session;
private Transaction transaction; @Before
public void init(){
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry =
new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry); session = sessionFactory.openSession();
transaction = session.beginTransaction();
} @After
public void destroy(){
transaction.commit();
session.close();
sessionFactory.close();
} @Test
public void testGet(){
Category category = (Category) session.get(Category.class, 1);
System.out.println(category.getName()); //须要连接中间表
Set<Item> items = category.getItems();
System.out.println(items.size());
} @Test
public void testSave(){
Category category1 = new Category();
category1.setName("C-AA"); Category category2 = new Category();
category2.setName("C-BB"); Item item1 = new Item();
item1.setName("I-AA"); Item item2 = new Item();
item2.setName("I-BB"); //设定关联关系
category1.getItems().add(item1);
category1.getItems().add(item2); category2.getItems().add(item1);
category2.getItems().add(item2); item1.getCategories().add(category1);
item1.getCategories().add(category2); item2.getCategories().add(category1);
item2.getCategories().add(category2); //运行保存操作
session.save(category1);
session.save(category2); session.save(item1);
session.save(item2);
} }

版权声明:本文博主原创文章。博客,未经同意不得转载。

hibernate 双向n-n的更多相关文章

  1. Hibernate双向多对多关联

    一.配置双向多对多关联 以Project类(项目)和Emp类(员工)为例: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 priva ...

  2. 注解:【无连接表的】Hibernate双向1->N关联

    Person与Address关联:双向1->N,[无连接表的],推荐使用 #由N端控制关联关系 #对于指定了mappedBy属性的@OneToMany,@ManyToMany,@OneToOne ...

  3. Hibernate双向多对多对象关系模型映射

    1 双向many-to-many 业务模型: 描述员工和项目 一个员工同时可以参与多个项目 一个项目中可以包含多个员工 分析:数据库的数据模型,通过中间关系表,建立两个one-to-many构成man ...

  4. hibernate 双向 1-n(具体分析)

    双向 1-n 与 双向 n-1 是全然同样的两种情形 双向 1-n 须要在 1 的一端能够訪问 n 的一端, 反之依旧. 域模型:从 Order 到 Customer 的多对一双向关联须要在Order ...

  5. hibernate双向一对多映射

    双向多对一 :Customer类------------>一的一端   Order类----------->多的一端 Customer类:(省略set().get()和构造方法) priv ...

  6. hibernate双向关联

    双向关联中最好的设置是一端为inverse=true,一端为inverse=false. falses维护,true不维护,设置多的一方维护(false) inverse属性就是用来规定是由谁来维护这 ...

  7. hibernate 双向1对多

    1: 还是用客户Customer和订单Order来解释: “一对多”的物理意义:一个客户可以有多个订单,某个订单只能归宿于一个客户. “双向”的物理意义:客户知道自己有哪些订单,订单也知道自己归宿于哪 ...

  8. 注解:【基于外键的】Hibernate双向1->1关联

    Person与Address关联:双向1->1,[基于外键的]. #主表不应该控制关联关系.(否则会导致生成额外的update语句,从而导致性能下降), #因此主表对应的实体中使用@OneToO ...

  9. 注解:Hibernate双向N->N关联(两端都控制关联关系)

    Person与Address关联:双向N->N,[连接表必须有],两端都控制关联关系 #需要说明的是:如果程序希望某一端放弃控制关联关系,则可以在这一段的@ManyToMany注解中指定mapp ...

随机推荐

  1. java它们的定义ArrayList序列, 大神跳跃

    一个list有两种类型的对象,今天有需求必须责令不同的约会对象,这里是代码 /** *@author xh1991101@163.com */ List<Message> messages ...

  2. iOS Dev (55) 获得本年度、月、日本和其他信息

    iOS Dev (55) 获得本年度.月.日本和其他信息 作者:大锐哥 博客:http://prevention.iteye.com - NSDate *now = [NSDate date]; NS ...

  3. android CountDownTimer

    最近进行的项目使用的定时功能,我发现了一个非常容易使用内置类CountDownTimer.当然,可以使用这种效果TimerTask + Timer为了实现.只是我个人的意见CountDownTimer ...

  4. Quick StateMachine状态机

    状态机quick中是一个亮点,假设我们做一款RPG游戏,一个角色通常会拥有idle,attack,walk.run,death这些状态,假设游戏角色的状态採用分支条件推断的话.会造成很庞大而难以维护. ...

  5. Oracle安装过程物理内存检查及临时temp空间不足解决办法

    物理内存 – 此先决条件将测试系统物理内存总量是否至少为 922MB (944128.0KB). 预期值 : N/A 实际值 : N/A 错误列表: – 可用物理内存 PRVF-7531 : 无法在节 ...

  6. Gradle第二步骤来创建学习Task

    请下载本系列中的以下文章Github演示示例代码: git clone https://github.com/davenkin/gradle-learning.git     Gradle的Proje ...

  7. Dubbo-Admin管理平台和Zookeeper注册中心的搭建(转)

    林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubb ...

  8. Byte[]和BASE64之间的转换

    一. BASE64编码 把byte[]中的元素当做无符号八位整数转换成只含有64个基本字符的字符串,这些基本字符是: l 大写的A-Z l 小写的a-z l 数字0-9 l '+' 和 '/' l 空 ...

  9. Swing中弹出对话框的几种方式(转)

    http://www.cnblogs.com/mailingfeng/archive/2011/12/28/2304289.html 在swing中,基于业务的考量,会有对话框来限制用户的行为及对用户 ...

  10. Codeforces 385B Bear and Strings

    题目链接:Codeforces 385B Bear and Strings 记录下每一个bear的起始位置和终止位置,然后扫一遍记录下来的结构体数组,过程中用一个变量记录上一个扫过的位置,用来去重. ...