您的位置:首页 > 编程语言 > Java开发

hibernate实现非主键映射外键双向多对一关系

2017-11-14 15:34 435 查看
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);
}
}


测试结果:





内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hibernate java