Hibernate双向一对多级联添加

 本例以Hibernate,Spring集成测试,以Oracle为数据库,以管理“部门---->员工”为例

 Oracle数据表如下:

 

--部门表

create table t_dept
(
 d_id number primary key,
 d_name varchar2(20) not null,
 d_remark varchar2(100) not null
);

--创建部门表的序列
create sequence dept_seq
start with 1
increment by 1;

--员工表
create table t_emp
(
 e_id number primary key,
 d_id number references t_dept(d_id) not null,
 e_name varchar2(20) not null,
 e_sex varchar(4) not null
);

--创建员工表的序列
create sequence emp_seq
start with 100
increment by 1;

--测试数据
insert into t_dept values(dept_seq.nextval,'开发一部','it is good');
insert into t_dept values(dept_seq.nextval,'开发二部','it is bad');

insert into t_emp values(emp_seq.nextval,1,'张三','男');
insert into t_emp values(emp_seq.nextval,1,'李四','男');
insert into t_emp values(emp_seq.nextval,2,'王五','男');
insert into t_emp values(emp_seq.nextval,2,'赵六','男');


 

 

生成的实体类如下:

TDept.java

package com.svse.entity;

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

/**
 * TDept entity.
 * 
 * @author MyEclipse Persistence Tools
 */

public class TDept implements java.io.Serializable {

 // Fields

 private Long DId;
 private String DName;
 private String DRemark;
 private Set TEmps = new HashSet(0);

 // Constructors

 /** default constructor */
 public TDept() {
 }

 /** minimal constructor */
 public TDept(String DName, String DRemark) {
  this.DName = DName;
  this.DRemark = DRemark;
 }

 /** full constructor */
 public TDept(String DName, String DRemark, Set TEmps) {
  this.DName = DName;
  this.DRemark = DRemark;
  this.TEmps = TEmps;
 }

 // Property accessors

 public Long getDId() {
  return this.DId;
 }

 public void setDId(Long DId) {
  this.DId = DId;
 }

 public String getDName() {
  return this.DName;
 }

 public void setDName(String DName) {
  this.DName = DName;
 }

 public String getDRemark() {
  return this.DRemark;
 }

 public void setDRemark(String DRemark) {
  this.DRemark = DRemark;
 }

 public Set getTEmps() {
  return this.TEmps;
 }

 public void setTEmps(Set TEmps) {
  this.TEmps = TEmps;
 }

}

 

TEmp.java

package com.svse.entity;

/**
 * TEmp entity.
 * 
 * @author MyEclipse Persistence Tools
 */

public class TEmp implements java.io.Serializable {

 // Fields

 private Long EId;
 private TDept TDept=new TDept();
 private String EName;

 // Constructors

 /** default constructor */
 public TEmp() {
 }

 /** full constructor */
 public TEmp(TDept TDept, String EName) {
  this.TDept = TDept;
  this.EName = EName;

 }

 // Property accessors

 public Long getEId() {
  return this.EId;
 }

 public void setEId(Long EId) {
  this.EId = EId;
 }

 public TDept getTDept() {
  return this.TDept;
 }

 public void setTDept(TDept TDept) {
  this.TDept = TDept;
 }

 public String getEName() {
  return this.EName;
 }

 public void setEName(String EName) {
  this.EName = EName;
 }

}


 

 

 

 

配置的TDept.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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.svse.entity.TDept" table="T_DEPT" schema="SCOTT">
        <id name="DId" type="java.lang.Long">
            <column name="D_ID" precision="22" scale="0" />
            <generator class="sequence" >
             <param name="sequence">dept_seq</param>
            </generator>
        </id>
        <property name="DName" type="java.lang.String">
            <column name="D_NAME" length="20" not-null="true" />
        </property>
        <property name="DRemark" type="java.lang.String">
            <column name="D_REMARK" length="100" not-null="true" />
        </property>
        <!-- 如果在删除一方的时候把多方也删掉,则在一方的set上配置cascade="delete" ,否则在删除一方的时候,如果找到子记录,则报错,违反约束条件 -->
        <set name="TEmps" inverse="true" cascade="delete">
            <key>
                <column name="D_ID" precision="22" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.svse.entity.TEmp" />
        </set>
    </class>
</hibernate-mapping>


TEmp.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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.svse.entity.TEmp" table="T_EMP" schema="SCOTT">
        <id name="EId" type="java.lang.Long">
            <column name="E_ID" precision="22" scale="0" />
            <generator class="sequence" >
             <param name="sequence">emp_seq</param>
            </generator>
        </id>
        
        <!-- 在批量添加多方的时候级联添加一方,配置cascade="save-update" -->
        <many-to-one name="TDept" class="com.svse.entity.TDept" fetch="select" cascade="save-update"> 
            <column name="D_ID" precision="22" scale="0" not-null="true" />
        </many-to-one>
        
        
        <property name="EName" type="java.lang.String">
            <column name="E_NAME" length="20" not-null="true" />
        </property>
    </class>
</hibernate-mapping>


 

 

 

用Junit测试添加多方,同时自动添加一方:

测试:添加多方时级联添加一方
 @Test
 public void test1(){
  TDept dept=new TDept();
  dept.setDName("开发3部");
  dept.setDRemark("it is good....");
  
  //第一个员工对象
  TEmp emp1=new TEmp();
  emp1.setEName("aaa");
  emp1.setTDept(dept);
  
  //第二个员工对象
  TEmp emp2=new TEmp();
  emp2.setEName("bbb");
  emp2.setTDept(dept);
 
  //第二个员工对象
  TEmp emp3=new TEmp();
  emp3.setEName("ccc");
  emp3.setTDept(dept);
  
  List<TEmp> empList=new ArrayList<TEmp>();
  empList.add(emp1);
  empList.add(emp2);
  empList.add(emp3);

  empService.addManyToOne(empList);//添加员工,在这里传一个list  
  
  System.out.println("dept & emps have been saved...");
 }


 

 

addManyToOne(empList)这个添加员工方法的代码如下,因为一次要添加多个员工,所以传进去的是一个Lis集合,批量添加


 

/******
	 * 批量添加员工
	 * @param li
	 */
	public void addManyToOne(List<TEmp> li) {
		System.out.println("传进来几个emp:  "+li.size());
		Session session=null;
		try {
			
				session=getHibernateTemplate().getSessionFactory().openSession();//获取session
				session.beginTransaction();//开启事务
				//创建员工对象
				TEmp emp=null;
				//循环获取员工对象
				for(int i=0;i<li.size();i++){
					emp=(TEmp)li.get(i);
					System.out.println("第"+(i+1)+"个name是:"+emp.getEName());
					getHibernateTemplate().save(emp);//保存
				}
				session.getTransaction().commit();//提交事务
			
			
			
		} catch (RuntimeException re) {
			session.beginTransaction().rollback();
			throw re;
		} finally{
			session.close();
		}
	}


 

注意在多方配置casacde="save-update",在保存多方的时候,会自动保存一方

 

 

还有一种情况就是在添加一方的同时添加多方,配置差不多,就是在一方的set上配置cascade="save-update"

 

Junit测试代码如下:

 

	测试:添加一方的时候添加很多个多方
	@Test
	public void test1(){
		TDept dept=new TDept();
		dept.setDName("开发3部");
		dept.setDRemark("it is good....");
		
		//第一个员工对象
		TEmp emp1=new TEmp();
		emp1.setEName("aaa");
		emp1.setTDept(dept);
		
		//第二个员工对象
		TEmp emp2=new TEmp();
		emp2.setEName("bbb");
		emp2.setTDept(dept);
	
		//第三个员工对象
		TEmp emp3=new TEmp();
		emp3.setEName("ccc");
		emp3.setTDept(dept);
		
		 Set emps = new HashSet(0);
		 emps.add(emp1);
		 emps.add(emp2);
		 emps.add(emp3);

		 dept.setTEmps(emps);
		 
		 //添加部门
		 deptService.add(dept);
		 
		 
		System.out.println("dept & emps have been saved...");
	}


 

TDept.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">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.svse.entity.TDept" table="T_DEPT" schema="SCOTT">
        <id name="DId" type="java.lang.Long">
            <column name="D_ID" precision="22" scale="0" />
            <generator class="sequence" >
            	<param name="sequence">dept_seq</param>
            </generator>
        </id>
        <property name="DName" type="java.lang.String">
            <column name="D_NAME" length="20" not-null="true" />
        </property>
        <property name="DRemark" type="java.lang.String">
            <column name="D_REMARK" length="100" not-null="true" />
        </property>
        <!-- 如果想在添加一方的时候添加多方,则在一方配置cascade="save-update",在多方不需要添加其它配置 -->
        <set name="TEmps" inverse="true" cascade="save-update">
            <key>
                <column name="D_ID" precision="22" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.svse.entity.TEmp" />
        </set>
    </class>
</hibernate-mapping>

 

 

其它:

      如果在一方设置casacde="remove",则表示在删除一方的时候,会删除与它关联的实体对象,如果没有设置这个属性,那么当删除一方的时候,如果找到对应的子记录,则删除报错,违反约束。


最后,欢迎访问风格清新简洁的轻博客网站[指尖一刻]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值