Hibernate关系映射---双向一对多增删查改实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ZZ2713634772/article/details/76180325

Hibernate关系映射---双向一对多增删查改实例

1、新建一个Java工程,添加hibernate3.3支持,连接test数据库

2、在src下新建com.etc.dao包,在包下新建User.java类:

package com.etc.dao;

import java.util.HashSet;
import java.util.Set;

public class User {
	private int userId;
	private String userName;
	private Set<Order> orders = new HashSet<Order>();//在一端加入多端的set集合
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public Set<Order> getOrders() {
		return orders;
	}
	public void setOrders(Set<Order> orders) {
		this.orders = orders;
	}
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	@Override
	public String toString() {
		return "User [userId=" + userId + ", userName=" + userName
				+ ", orders=" + orders + "]";
	}
	
}

3、在com.etc.dao下新建Order.java类:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.etc.dao.Order" table="t_order" catalog="test">
		<id name="orderId" type="java.lang.Integer">
			<column name="order_id"/>
			<generator class="native"/>
		</id>
		<property name="orderState" type="java.lang.String">
			<column name="order_state"/>
		</property>
		<property name="orderCreatedate" type="java.util.Date">
			<column name="order_createdate"/>
		</property>
		<!-- 在多端配置many-to-one -->
		<many-to-one name="user" class="com.etc.dao.User" fetch="join">
			<column name="user_id"/>
		</many-to-one>
	</class>
</hibernate-mapping>

4、在com.etc.dao下新建User.hbm.xml映射文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.etc.dao.User" table="t_user" catalog="test">
		<id name="userId" type="java.lang.Integer">
			<column name="user_id"/>
			<generator class="native"/>
		</id>
		<property name="userName" type="java.lang.String">
			<column name="user_name"/>
		</property>
		<!-- 在一端加入多端的set集合,并且指定在多端表的外键的名称 -->
		<set name="orders">
			<key>
				<column name="user_id"/>
			</key>
			<one-to-many class="com.etc.dao.Order"/>
		</set>
	</class>
</hibernate-mapping>

5、在com.etc.dao下新建Order.hbm.xml映射文件:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.etc.dao.Order" table="t_order" catalog="test">
		<id name="orderId" type="java.lang.Integer">
			<column name="order_id"/>
			<generator class="native"/>
		</id>
		<property name="orderState" type="java.lang.String">
			<column name="order_state"/>
		</property>
		<property name="orderCreatedate" type="java.util.Date">
			<column name="order_createdate"/>
		</property>
		<!-- 在多端配置many-to-one -->
		<many-to-one name="user" class="com.etc.dao.User" fetch="join">
			<column name="user_id"/>
		</many-to-one>
	</class>
</hibernate-mapping>

6、配置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">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
    	<property name="show_sql">true</property>
    	<property name="format_sql">true</property>
    	<!-- <property name="hbm2ddl.auto">create</property> -->
    	<property name="current_session_context_class">thread</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property>
    	<mapping resource="com/etc/dao/User.hbm.xml"/>
    	<mapping resource="com/etc/dao/Order.hbm.xml"/>
    </session-factory>

</hibernate-configuration>

7、新建test文件夹,在文件夹下新建com.etc.dao包,在包下新建UserDAOTest.java测试类:

package com.etc.dao;

import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class UserDAOTest {
	/**
	 * Description:新增:由一端操作多端(不建议),不可行
	 * @author zoey
	 * @date 2017年7月26日
	 */
	@Test
	public void testCreate1(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		User user = new User();
		user.setUserName("zoey");
		
		Order o1 = new Order();
		o1.setOrderState("1");
		o1.setOrderCreatedate(new Date());
		
		Order o2 = new Order();
		o2.setOrderState("0");
		o2.setOrderCreatedate(new Date());
		
		//将订单加入到用户中去
		user.getOrders().add(o1);
		user.getOrders().add(o2);
		//保存用户信息:双向关系中不建议设置cascade=all,建议从多端去操作一端(使用多对一的操作)
		session.save(user);
		session.getTransaction().commit();
	}
	/**
	 * Description:新增:由多端操作一端,标准做法,可行,建议使用
	 * @author zoey
	 * @date 2017年7月26日
	 */
	@Test
	public void testCreate2(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		
		User user = new User();
		user.setUserName("lan");
		
		Order o1 = new Order();
		o1.setOrderState("1");
		o1.setOrderCreatedate(new Date());
		
		
		Order o2 = new Order();
		o2.setOrderState("0");
		o2.setOrderCreatedate(new Date());
		
		//通过多端去操作一端,增加完订单之后,再增加用户
		o1.setUser(user);
		o2.setUser(user);
		
		session.save(user);
		session.save(o1);
		session.save(o2);
		
		session.getTransaction().commit();
	}
	/**
	 * Description:删除:一端操作多端(删除用户信息,同时将订单表的用户id设为null),可行
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testDelete1(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		User user = (User)session.get(User.class,1);
		session.delete(user);
		session.getTransaction().commit();
	}
	/**
	 * Description:删除:多端操作一端:只是删除订单信息,用户信息还是存在,可行,建议使用
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testDelete2(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		Order order = (Order)session.get(Order.class,3);
		session.delete(order);
		session.getTransaction().commit();
	}
	/**
	 * Description:更新:一端操作多端:修改用户,同时修改该用户下的订单 ,可行
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testUpdate1(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		User user = (User)session.get(User.class,1);
		user.setUserName("zoey");
		for(Order order:user.getOrders()){
			order.setOrderCreatedate(new Date());
		}
		session.getTransaction().commit();
	}
	/**
	 * Description:更新:多端操作一端:修改订单,同时修改该订单的用户,可行,建议使用
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testUpdate2(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		Order order = (Order)session.get(Order.class, 1);
		order.setOrderCreatedate(new Date());
		
		order.getUser().setUserName("lan");
		session.getTransaction().commit();
	}
	/**
	 * Description:查询:一端操作多端:查询用户信息,再查询该用户的订单信息,可行
	 * (执行两次sql,不建议在set中配置fetch=join)
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testRetrieve1(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		User user = (User)session.get(User.class, 1);
		System.out.println(user.getUserName());
		for(Order order:user.getOrders()){
			System.out.println(order.getOrderCreatedate());
		}
		session.getTransaction().commit();
	}
	/**
	 * Description:查询:多端操作一端:查询订单信息,再查询该订单的用户信息,可行
	 * (执行两次sql,可以在many-to-one中配置fethc=join),建议使用
	 * @author zoey
	 * @date 2017年7月27日
	 */
	@Test
	public void testRetrieve2(){
		SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
		Session session = sessionFactory.getCurrentSession();
		session.beginTransaction();
		Order order = (Order)session.get(Order.class,1);
		System.out.println(order.getOrderCreatedate());
		
		System.out.println(order.getUser().getUserName());
		session.getTransaction().commit();
	}
}

总结:

1、一对多双向关系:需要在一端加入多端的配置,也需要在多端加入一端的配置,java代码和xml映射文件中都需要配置相应的信息。于是,对于增删查改操作,我们基本都可以有两种选择:由一端操作多端、由多端操作一端。但是,我们建议,把一对多双向看成多对一单向,也就是,所有的增删查改操作都有多端来操作一端。

2、一对多双向关系中,不建议在一端配置cascase=all或者fetch=join属性。但是可以在多端的映射文件中配置。

3、可以在一端的映射文件中配置inverse=true,表示一端放弃控制多端。

<set name="orders" inverse="true">
	<key>
		<column name="user_id"/>
	</key>
	<one-to-many class="com.etc.dao.Order"/>
</set>
之后,所有的增删查改操作都有多端来控制一端。

所以,我们只需要把一对多双向,想成多对一关系来操作就可以了。

展开阅读全文

没有更多推荐了,返回首页