1 many-to-one多对一端加property-ref关联主表的java对应类外键属性:
注:property-ref对应的是java类属性,不是表的字段
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 2017-9-17 15:48:32 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="cn.com.pojo.n21.both.notPK">
<class name="Order" table="ORDERS_NOPK">
<id name="orderId" type="java.lang.Integer">
<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.com.pojo.n21.Customer" fetch="join"> <column name="CUSTOMER" /> </many-to-one> -->
<!-- 映射多对一的关联关系 :多端有个外键-->
<!-- 使用 <many-to-one> 元素来映射多对一关联关系. name: 多这一端关联的一那一端的属性名 class: 一端属性对应的类名 column: 一端在多端对应的数据表中的外键名字 property-ref: 当一端是非主键的多对一端时候使用 -->
<!-- 在多端设置外键 -->
<many-to-one name="customer" class="Customer" property-ref="cyId">
<column name="CUSTOMER_ID"/>
</many-to-one>
</class>
</hibernate-mapping>
Order.java
package cn.com.pojo.n21.both.notPK;
public class Order {
private Integer orderId;
private String orderName;
private Customer customer;
public Order() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Order [orderId=" + orderId + ", orderName=" + orderName
+ "]";
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
2 set一对多端也加property-ref关联主表的java对应类外键属性:
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 2017-9-17 15:48:32 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="cn.com.pojo.n21.both.notPK">
<class name="Customer" table="CUSTOMERS_NOPK">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="customerName" type="java.lang.String">
<column name="CUSTOMER_NAME" />
</property>
<property name="cyId" type="java.lang.Integer">
<column name="cy_id" not-null="true" unique="true"/>
</property>
<!-- 映射 1 对多 集合属性 -->
<!-- set属性: -->
<set name="orders" table="ORDERS" cascade="delete" inverse="true">
<!-- key: 指定多端表中的外键列名字 -->
<key column="CUSTOMER_ID" property-ref="cyId"></key>
<!-- class指定映射java类 -->
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
Customer.java
package cn.com.pojo.n21.both.notPK;
import java.util.HashSet;
import java.util.Set;
public class Customer {
private Integer id;
private Integer cyId;
private String customerName;
/* * 1 声明集合类型时候,需要用接口类型,因为hibernate在存取集合类型时, * 返回的是hibernate内置的集合类型,而不是javaSE一个标准的集合实现。 * 2 把集合set进行初始化,可以防止发生空指针异常; */
private Set<Order> orders = new HashSet<>();
public Customer() {
super();
// TODO Auto-generated constructor stub
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
public Integer getCyId() {
return cyId;
}
public void setCyId(Integer cyId) {
this.cyId = cyId;
}
@Override
public String toString() {
return "Customer [id=" + id + ", cyId=" + cyId + ", customerName="
+ customerName + ", orders=" + orders + "]";
}
}
3 测试:
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 配置连接数据库的基本信息 -->
<property name="connection.username">root</property>
<property name="connection.password">123456</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.MySQLDialect</property>
<!-- 执行操作时候是否在控制台打印sql -->
<property name="show_sql">true</property>
<!-- 是否对sql进行格式化 -->
<property name="format_sql">true</property>
<!-- 指定自动生成表的策略 update create-->
<property name="hbm2ddl.auto">create</property>
<!-- 指定关联的.hbm.xml -->
<mapping resource="cn/com/pojo/n21/both/notPK/Customer.hbm.xml"/>
<mapping resource="cn/com/pojo/n21/both/notPK/Order.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Many2OneTest.java
package cn.com.pojo.n21.both.notPK;
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 Many2OneTest {
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 tesSave(){
Customer c = new Customer();
c.setCyId(102);
c.setCustomerName("BB");
Order o1 = new Order();
o1.setOrderName("ORDER-O1");
Order o2 = new Order();
o2.setOrderName("ORDER-O2");
//设定双向关联关系
o1.setCustomer(c);
o2.setCustomer(c);
c.getOrders().add(o1);
c.getOrders().add(o2);
//执行save
// 先插入1端,再插入多端,3条insert语句,2条update
// 因为1端和n端都维护关联关系,所以多出2个update
// 可以在1端的set节点指定inverse=true,使1端放弃维护关联关系,此时不会有update
// 建议设定set的inverse=true,建议先插入1端再插入多端,不会出现update语句。
session.save(o1);
session.save(o2);
session.save(c);
}
}
测试结果: