双项映射一对多关联关系

一. Hibernate 使用 <set> 元素来映射 set 类型的属性

二. <set> 元素来映射持久化类的 set 类型的属性
name: 设定待映射的持久化类的属性的

三. <key> 元素设定与所关联的持久化类对应的表的外键
column: 指定关联表的外键名

四. <one-to-many> 元素设定集合属性中所关联的持久化类
class: 指定关联的持久化类的类名


五.<set> 元素的 inverse 属性

在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系. inverse = false 的为主动方,inverse = true 的为被动方, 由主动方负责维护关联关系
在没有设置 inverse=true 的情况下,父子两边都维护父子
(一般情况下我们把多(n)的那一方设为主动方,把1的那一 方设为被动方)

六.代码

1.Order类

package cn.edu.sdut.hibernate.manytoone;

public class Order {

	private int orderId;
	private String orderName;
	private Customer customer;
	
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	public int getOrderId() {
		return orderId;
	}
	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}
	public String getOrderName() {
		return orderName;
	}
	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}
	
	public Order(String orderName, Customer customer) {
		super();
		this.orderName = orderName;
		this.customer = customer;
	}
	public Order() {
		super();
	}
	
	
}

2.Customer类

package cn.edu.sdut.hibernate.manytoone;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;



public class Customer {

	private int customerId;
	private String customerName;
	
//	private List<Order> set = new ArrayList<Order>();
//	
//	public List<Order> getSet() {
//		return set;
//	}
//	public void setSet(List<Order> set) {
//		this.set = set;
//	}
		private Set<Order> set = new HashSet<>();
	
	
	public Set<Order> getSet() {
		return set;
	}
	public void setSet(Set<Order> set) {
		this.set = set;
	}
	public int getCustomerId() {
		return customerId;
	}
	public void setCustomerId(int customerId) {
		this.customerId = customerId;
	}
	public String getCustomerName() {
		return customerName;
	}
	public void setCustomerName(String customerName) {
		this.customerName = customerName;
	}
	public Customer(String customerName) {
		super();
		this.customerName = customerName;
	}
	public Customer() {
		super();
	}
	
	
}
3.Order.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 2016-10-29 15:15:16 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="cn.edu.sdut.hibernate.manytoone.Order" table="ORDERS">
        <id name="orderId" type="int">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        <many-to-one name="customer" class="cn.edu.sdut.hibernate.manytoone.Customer">
            <column name="CUSTOMER_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

4.Customer.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 2016-10-29 15:15:16 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="cn.edu.sdut.hibernate.manytoone.Customer" table="CUSTOMERS">
        <id name="customerId" type="int">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id><pre name="code" class="java"><?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">csc</property>
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	<property name="connection.url">jdbc:mysql:///hibernate5</property>
    
    	<!-- 配置hibernate的基本信息 -->
    	<!-- hibernate 所使用的数据库方言 -->
    	<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
    	
    	<!-- 执行sql时是否在控制台上打印 -->
    	<property name="show_sql">true</property>
    	
    	<!-- 是否对sql进行格式化 -->
    	<property name="format_sql">true</property>
    	
    	<!-- 指定自动生成数据表的策略 -->
    	<property name="hbm2ddl.auto">update</property>
    	
    	<!-- 指定session的delete方法会把对象的id置为null -->
    	<property name="hibernate.use_identifier_rollback">true</property>
    	
    	<!-- 指定数据库的隔离级别 -->
    	<property name="connection.isolation">2</property>
    	
    	<!-- 配置c3p0数据池 -->
    	<property name="hibernate.c3p0.max_size">100</property>
    	<property name="hibernate.c3p0.min_size">20</property>
    	<property name="hibernate.c3p0.acquire_increment">5</property>
    	<property name="hibernate.c3p0.timeout">2000</property>
    	<property name="hibernate.c3p0.idle_test_period">2000</property>
    	<property name="hibernate.c3p0.max_statements">10</property>
    	
    	<!-- 设定JDBC的statment读取数据的时候每次在数据库中读取的记录的条数 -->
    	<property name="hibernate.jdbc.fetch_size">100</property>
    	<!-- 设定对数据进行批量操作,批次更新和批次插入的批次大小 -->
    	<property name="hibernate.jdbc.batch_size">30</property>
    	
    	<!-- 指定关联的xxx.hbm.xml文件 -->
    	<mapping resource="cn/edu/sdut/hibernate/helloworld/News.hbm.xml"/>
    	<mapping resource="cn/edu/sdut/hibernate/manytoone/Customer.hbm.xml"/>
    	<mapping resource="cn/edu/sdut/hibernate/manytoone/Order.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

<property name="customerName" type="java.lang.String"> <column name="CUSTOMER_NAME" /> </property> <set name="set" table="ORDERS" inverse="true"> <key column="CUSTOMER_ID"></key> <one-to-many class="cn.edu.sdut.hibernate.manytoone.Order"/> </set> <!-- <list name="set" table="ORDERS"> <key column="CUSTOMER_ID"></key> <index column="[index]" type="integer"></index> <one-to-many class="cn.edu.sdut.hibernate.manytoone.Order"/> </list> --> </class></hibernate-mapping>

 5.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">csc</property>
    	<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    	<property name="connection.url">jdbc:mysql:///hibernate5</property>
    
    	<!-- 配置hibernate的基本信息 -->
    	<!-- hibernate 所使用的数据库方言 -->
    	<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
    	
    	<!-- 执行sql时是否在控制台上打印 -->
    	<property name="show_sql">true</property>
    	
    	<!-- 是否对sql进行格式化 -->
    	<property name="format_sql">true</property>
    	
    	<!-- 指定自动生成数据表的策略 -->
    	<property name="hbm2ddl.auto">update</property>
    	
    	<!-- 指定session的delete方法会把对象的id置为null -->
    	<property name="hibernate.use_identifier_rollback">true</property>
    	
    	<!-- 指定数据库的隔离级别 -->
    	<property name="connection.isolation">2</property>
    	
    	<!-- 配置c3p0数据池 -->
    	<property name="hibernate.c3p0.max_size">100</property>
    	<property name="hibernate.c3p0.min_size">20</property>
    	<property name="hibernate.c3p0.acquire_increment">5</property>
    	<property name="hibernate.c3p0.timeout">2000</property>
    	<property name="hibernate.c3p0.idle_test_period">2000</property>
    	<property name="hibernate.c3p0.max_statements">10</property>
    	
    	<!-- 设定JDBC的statment读取数据的时候每次在数据库中读取的记录的条数 -->
    	<property name="hibernate.jdbc.fetch_size">100</property>
    	<!-- 设定对数据进行批量操作,批次更新和批次插入的批次大小 -->
    	<property name="hibernate.jdbc.batch_size">30</property>
    	
    	<!-- 指定关联的xxx.hbm.xml文件 -->
    	<mapping resource="cn/edu/sdut/hibernate/helloworld/News.hbm.xml"/>
    	<mapping resource="cn/edu/sdut/hibernate/manytoone/Customer.hbm.xml"/>
    	<mapping resource="cn/edu/sdut/hibernate/manytoone/Order.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
6.DoubleTest类

package cn.edu.sdut.hibernate.manytoone;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
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;

public class DoubleTest {

	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 destory(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@org.junit.Test
	public void testSaveManyToOne(){
		Customer customer = new Customer("aa");
		Order order1 = new Order();
		order1.setOrderName("11");
		Order order2 = new Order();
		order2.setOrderName("22");
		
		//设定关联关系
		order1.setCustomer(customer);
		order2.setCustomer(customer);
//		List<Order> list = new ArrayList<>();
//		list.add(order1);
//		list.add(order2);
//		customer.setSet(list);
		Set<Order> set = new HashSet<>();
		set.add(order1);
		set.add(order2);
		customer.setSet(set);
		//执行  save 操作: 先插入 Customer, 再插入 Order, 3 条 INSERT, 2 条 UPDATE
		//因为 1 的一端和 n 的一端都维护关联关系. 所以会多出 UPDATE
		//可以在 1 的一端的 set 节点指定 inverse=true, 来使 1 的一端放弃维护关联关系!
		//建议设定 set 的 inverse=true, 建议先插入 1 的一端, 后插入多的一端
		//好处是不会多出 UPDATE 语句
		session.save(customer);
		session.save(order1);
		session.save(order2);
		
		//如果按照先保存order然后再保存customer这样先进行三次插入操作然后再进行两次
		//更新操作,然后还有两次更新操作,为甚么会多了两次更新操作,是因为保存order的
		//时候没有不知道customer的ID,所以再进行两次更新操作
//		session.save(order1);
//		session.save(order2);
//		session.save(customer);
		
	}
	
	@org.junit.Test
	public void testGetManyToOne(){
		Customer customer = (Customer) session.get(Customer.class, 1);
		Set<Order> set = customer.getSet();
		//session.close();
		//获取 customer 对象时, 默认情况下, 其关联的 customer 里面的 set 是一个代理对象!
		//如果关闭session再操作set会出现org.hibernate.LazyInitializationException
		System.out.println(set.size());
	}
	
	@org.junit.Test
	public void testUpdateManyToOne(){
		//可以更新customer里面set里面的order对象的属性
		Customer customer = (Customer) session.get(Customer.class, 1);
		customer.getSet().iterator().next().setOrderName("csc");
	}
	
	@org.junit.Test
	public void testDeleteManyToOne(){
		//在不设定级联关系的情况下, 可以删除customer里面set里面的order对象
		Customer customer = (Customer) session.get(Customer.class,1);
		Order order = customer.getSet().iterator().next();
		System.out.println(order);
		session.delete(order);
	}
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值