本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用

内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。

本人互联网技术爱好者,互联网技术发烧友

微博:伊直都在0221

QQ:951226918

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.单向 n-n

  域模型:

      

  

  关系数据模型

      

2.解决方法

  1)n-n 的关联必须使用连接表

  

  2)与 1-n 映射类似,必须为 set 集合元素添加 key 子元素,指定 CATEGORIES_ITEMS 表中参照 CATEGORIES 表的外键为 CATEGORIY_ID.  

3)与 1-n 关联映射不同的是,建立 n-n 关联时, 集合中的元素使用 many-to-many. many-to-many 子元素的 class 属性指定 items 集合中存放的是 Item 对象 , column 属性指定 CATEGORIES_ITEMS 表中参照 ITEMS 表的外键为 ITEM_ID

  

  <!--  table:指定中间表 -->
<set name="items" table="CATEGORYS_ITEMS" >
<key>
<column name="C_ID" />
</key>
<!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 -->
<many-to-many class="Item">
<column name="I_ID"></column>
</many-to-many>
</set>

3.代码

  Category

 package com.jason.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<>();
12

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

 package com.jason.hibernate.n2n;

 public class Item {

     private Integer id;
private String name; 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;
} }

  

  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.jason.hibernate.n2n"> <class name="Category" table="CATEGORYS"> <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:指定中间表 -->
20 <set name="items" table="CATEGORYS_ITEMS" >
21 <key>
22 <column name="C_ID" />
23 </key>
24 <!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 -->
25 <many-to-many class="Item">
26 <column name="I_ID"></column>
27 </many-to-many>
28 </set>
29

</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.jason.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> </class> </hibernate-mapping>

  HibernateTest

 package com.jason.hibernate.n2n;

 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.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 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); session.save(category1);
session.save(category2); session.save(item1);
session.save(item2); } @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()); } }

hibernate.cfg.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 连接数据库的基本信息 -->
<property name="connection.username">root</property>
<property name="connection.password">zhangzhen</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql:///hibernate</property> <!-- 配置hibernate 的节本信息 -->
<!-- hibernate 所使用的数据库方言 -->
<!--<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 执行操作时是否在控制台打印SQL -->
<property name="show_sql">true</property> <!-- 是否都SQL 进行格式化 -->
<property name="format_sql">true</property> <!-- 指定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">update</property> <!-- 设置hibernate 的事务隔离级别 -->
<property name="connection.isolation">2</property> <!-- 配置c3p0 -->
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.min_size">5</property>
<property name="c3p0.acquire_increment">2</property>
<property name="c3p0.idle_test_period">2000</property>
<property name="c3p0.timeout">2000</property>
<property name="c3p0.max_statements">10</property> <!-- 对于mysql 无效,对于oracle 有效 -->
<!-- 设定JDBC 的Statement 读取数据的时候每次从数据库中取出的记录的条数 -->
<property name="hibernate.jdbc.fetch_size">100</property> <!-- 设置数据库进行批量删除,批量更新和批量插入的时候的大小 -->
<property name="hibernate.jdbc.batch_size">30</property>
<mapping resource="com/jason/hibernate/n2n/Category.hbm.xml"/>
<mapping resource="com/jason/hibernate/n2n/Item.hbm.xml"/> </session-factory> </hibernate-configuration>

4.双向n-n

  域模型:

    

  关系数据模型

    

  1)核心点

    ① 双向 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, 否则两端都维护关联关系可能会造成主键冲突.

Catogery

 package com.jason.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<>();
12

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

 package com.jason.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 Set<Category> getCategories() {
return categories;
} public void setCategories(Set<Category> categories) {
this.categories = categories;
} 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;
} }

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.jason.hibernate.n2n"> <class name="Category" table="CATEGORYS"> <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="CATEGORYS_ITEMS" >
<key>
<column name="C_ID" />
</key>
<!-- 使用 many-to-many 指定多对多的关联关系,column 指定 set集合中的 持久化类 在中间表的外键列的名称 -->
<many-to-many class="Item">
<column name="I_ID"></column>
</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.jason.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="CATEGORYS_ITEMS">
<key column="I_ID"></key>
<many-to-many class="com.jason.hibernate.n2n.Category">
<column name="C_ID"></column>
</many-to-many>
</set> </class> </hibernate-mapping>

hibernate.cfg.xml

hibernateTest

[原创]java WEB学习笔记86:Hibernate学习之路-- -映射 n-n 关系,单向n-n,双向n-n的更多相关文章

  1. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  2. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用

    目录 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用 21.1 read命令键盘读取变量的值 21.1.1 read常用见用法及参数 21.2 流程控制语句if 21.2 ...

  5. 学习笔记:CentOS7学习之二十:shell脚本的基础

    目录 学习笔记:CentOS7学习之二十:shell脚本的基础 20.1 shell 基本语法 20.1.1 什么是shell? 20.1.2 编程语言分类 20.1.3 什么是shell脚本 20. ...

  6. 学习笔记:CentOS7学习之十九:Linux网络管理技术

    目录 学习笔记:CentOS7学习之十九:Linux网络管理技术 本文用于记录学习体会.心得,兼做笔记使用,方便以后复习总结.内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK ...

  7. 学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用

    目录 学习笔记:CentOS7学习之十六:LVM管理和ssm存储管理器使用 16.1 LVM的工作原理 16.1.1 LVM常用术语 16.1.2 LVM优点 16.2 创建LVM的基本步骤 16.2 ...

  8. HTML+CSS学习笔记 (6) - 开始学习CSS

    HTML+CSS学习笔记 (6) - 开始学习CSS 认识CSS样式 CSS全称为"层叠样式表 (Cascading Style Sheets)",它主要是用于定义HTML内容在浏 ...

  9. 在Java Web程序中使用Hibernate

    在Java Web程序中使用Hibernate与普通Java程序一样.本文中将使用Servlet和JSP结合Hibernate实现数据库表的增删改查操作. Web程序中,hibernate.cfg.x ...

  10. 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧

    目录 学习笔记:CentOS7学习之二十五:shell中色彩处理和awk使用技巧 25.1 Shell中的色彩处理 25.2 awk基本应用 25.2.1 概念 25.2.2实例演示 25.3 awk ...

随机推荐

  1. jsonObject jsonarray

    1.JAR包简介 要使程序可以运行必须引入JSON-lib包,JSON-lib包同时依赖于以下的JAR包: commons-lang.jar commons-beanutils.jar commons ...

  2. 更新Delphi中SVN客户端版本的方法

    Delphi从XE以后集成里SVN客户端, 安装完Delphi以后, 在bin\subversion下, 存放的就是SVN客户端文件, 可惜版本有点低(好像是1.7的) 如果想更新成高版本的客户端文件 ...

  3. 利用ArcMap对tiff或jpg格式地图图片的配准步骤

    原文:利用ArcMap对tiff或jpg格式地图图片的配准步骤 在实际应用中,经常会遇到提供一张高精度的地图图片文件,如何对将该图片进行配准(使图片具有经纬度坐标). 当然我们得有一些大概的参考图层, ...

  4. -tableView: cellForRowAtIndexPath:方法不执行问题

    今天在学习UItableView 的时候,定义了一个属性 @property (weak, nonatomic) NSMutableArray *dataList: 在ViewDidLoad方法方法中 ...

  5. How to pass selected records from form to dilog in AX 2012

    static void main(Args args) { FormDataSource formDataSource; ; if(args.record().TableId == tablenum( ...

  6. js数组判断是否含有某一个元素

    arr.indexOf('a')如果有则返回的a的下标位置,否则返回false.

  7. 微信JS SDK使用权限签名算法

    jsapi_ticket 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据.正常情况下,jsapi_ticket的有效期为7200秒, ...

  8. 改变DataGrid某一行和单元格的颜色

    前段时间做WPF项目,需要改变DataGrid某一行的颜色.高度,以及某个单元格的颜色.单元格字体的颜色,自然就必需取到datagrid的一行和一行的单元格,网上也是搜索了好久才找到,记录下来便于使用 ...

  9. 通过 ec2-api / boto 调用 OpenStack 功能

    通过 ec2-api / boto 调用 OpenStack 功能 OpenStack 支持 amazon ec2 的 api,并能通过 python 库 boto 来进行调用.目前,社区在把 ec2 ...

  10. ssh secure shell client

    登陆方式和putty一样