一、多对多映射有单向多对多和双向多对多
二、实现
商品有很多种,每个商品拿来分类,一个商品可以属于多个类别,一种分类下有多重商品
三、代码
共用的类
public class Category {
private Integer id;
private String name;
private Set<Item> items = new HashSet<>();
//set/get...
}
配置文件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>
<!-- 配置链接数据库的基本信息 -->
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate01</property>
<!-- hibernate的基本信息 -->
<!-- hibernate使用的数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<!-- 执行操作时是否在控制台打印sql语句 -->
<property name="show_sql">true</property>
<!-- 是否对sql进行格式化 -->
<property name="format_sql">true</property>
<!-- 指定自动生成数据表的策略 -->
<property name="hbm2ddl.auto">create</property>
<!-- 设置hibernate的隔离级别 -->
<property name="connection.isolation">2</property>
<!-- 删除对象后,设置其OID为null -->
<property name="use_identifier_rollback">true</property>
<!-- 配置C3P0数据源 -->
<property name="c3p0.max_size">100</property>
<property name="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>
<!-- 设置JDBC的statement读取数据库的时候每次从数据库中读取记录条数,这个值100合适,太大会损耗内存,小了速度慢 -->
<property name="jdbc.fetch_size">100</property>
<!-- 设置数据库进行批量删除,更新,插入的时候批次的大小,30比较合适 -->
<property name="jdbc.batch_size">30</property>
<!-- 指定关联的hbm.xml文件 -->
<!-- 单向多对多 -->
<!--
<mapping resource="com/hibernate/n2n/single/Category.hbm.xml"/>
<mapping resource="com/hibernate/n2n/single/Item.hbm.xml"/>
-->
<!-- 双向多对多 -->
<mapping resource="com/hibernate/n2n/doubles/Category.hbm.xml"/>
<mapping resource="com/hibernate/n2n/doubles/Item.hbm.xml"/>
</session-factory>
</hibernate-configuration>
1、双向多对多
public class Item {
private Integer id;
private String name;
private Set<Category> categories = new HashSet<>();
//get/set...
}
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">
<!-- Generated 2017-3-27 21:23:17 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.hibernate.n2n.doubles">
<class name="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.hibernate.n2n.doubles.Category" column="C_ID"></many-to-many>
</set>
</class>
</hibernate-mapping>
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">
<!-- Generated 2017-3-27 21:23:17 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.hibernate.n2n.doubles">
<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" inverse="true">
<key>
<column name="C_ID" />
</key>
<!-- column-Set集合中的持久类在中间表的外键列的名称 -->
<many-to-many class="Item" column="I_ID" />
</set>
</class>
</hibernate-mapping>
Test
import static org.junit.Assert.*;
import java.util.Set;
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;
@Test
public void testN2NSave() {
Category category1 = new Category();
category1.setName("AA1");
Category category2 = new Category();
category2.setName("AA2");
Item item1 = new Item();
item1.setName("BB1");
Item item2 = new Item();
item2.setName("BB12");
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);
}
@Test
public void testGet(){
Category category1 = (Category) session.get(Category.class, 3);
System.out.println(category1.getName());
Set<Item> items = category1.getItems();
System.out.println(items.size());
// session.delete(category1);
}
@Before
public void init() {
System.out.println("HibernateTest.init()");
// 1.创建一个sessionFactory对象
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2.创建一个session对象
session = sessionFactory.openSession();
// 3.开启事务
transaction = session.beginTransaction();
}
@After
public void destroy() {
System.out.println("HibernateTest.destroy()");
// 5.提交事务
transaction.commit();
// 6.关闭session
session.close();
// 7.关闭SessionFactory
sessionFactory.close();
}
}
2、单向多对多
public class Item {
private Integer id;
private String name;
//get/set...
}
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">
<!-- Generated 2017-3-27 21:23:17 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.hibernate.n2n.sibgle.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>
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">
<!-- Generated 2017-3-27 21:23:17 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.hibernate.n2n.single">
<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>
<!-- column-Set集合中的持久类在中间表的外键列的名称 -->
<many-to-many class="Item" column="I_ID" />
</set>
</class>
</hibernate-mapping>
Test
import static org.junit.Assert.*;
import java.util.Set;
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;
@Test
public void testN2NSave() {
Category category1 = new Category();
category1.setName("AA1");
Category category2 = new Category();
category2.setName("AA2");
Item item1 = new Item();
item1.setName("BB1");
Item item2 = new Item();
item2.setName("BB12");
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 category1 = (Category) session.get(Category.class, 3);
System.out.println(category1.getName());
Set<Item> items = category1.getItems();
System.out.println(items.size());
// session.delete(category1);
}
@Before
public void init() {
System.out.println("HibernateTest.init()");
// 1.创建一个sessionFactory对象
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
.buildServiceRegistry();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
// 2.创建一个session对象
session = sessionFactory.openSession();
// 3.开启事务
transaction = session.beginTransaction();
}
@After
public void destroy() {
System.out.println("HibernateTest.destroy()");
// 5.提交事务
transaction.commit();
// 6.关闭session
session.close();
// 7.关闭SessionFactory
sessionFactory.close();
}
}