一. 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);
}
}