`
king_tt
  • 浏览: 2259822 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

    Hibernate 一对多、多对一、级联、加载、反转

    在Java持久化框架Hibernate中,一对多(One-to-Many)、多对一(Many-to-One)、级联(Cascading)、加载(Loading)和反转(Inversing)是关系映射的重要概念,它们对于理解如何在数据库和对象之间有效地管理关联至...

    Hibernate双向一对多

    标题"Hibernate双向一对多"指的是Hibernate框架中的一个重要关系映射概念,即在一个实体类中,一个实例可以与多个另一个实体类的实例相关联,而在另一个实体类中,每个实例也可以关联到该实体类的一个实例。...

    Hibernate双向一对多经典实例

    **标题:“Hibernate双向一对多经典实例”** 在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够用面向对象的方式处理数据。本实例将聚焦于Hibernate中的一对多关系...

    Hibernate双向一对一关联映射(注解版)

    本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...

    Nhibernate一对多级联保存_双向映射[归类].pdf

    在Nhibernate中,一对...总结来说,Nhibernate中的一对多级联保存和双向映射是用于管理复杂对象关系的重要特性。通过恰当的注解配置,可以实现父对象与子对象的自动保存和关系导航,简化了ORM的使用,提升了开发效率。

    hibernate双向一对多关联映射(注解版)

    在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系映射方式,它模拟了数据库中的外键关联,使得一个实体可以拥有多个另一个实体的实例。在这个注解版的实现中,我们将深入探讨如何使用Hibernate的...

    Hibernate双向关联代码示例

    **Hibernate双向关联详解** 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本示例将深入探讨Hibernate中的双向关联,这是一种常见且重要的数据模型映射技术。 双向关联...

    hibernate双向一对多关联映射(XML)

    在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系数据库模型与对象模型之间的映射方式。这种映射允许在一个实体类中存在多个另一个实体类的实例,而在另一个实体类中也可能存在对第一个实体类的...

    hibernate多对多双向关联

    **标题解析:**“hibernate多对多双向关联” 在Java编程中,Hibernate是一个流行的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理数据库操作。"多对多双向关联"是Hibernate中一种关系映射类型,涉及两...

    hibernate双向多对多关联映射(注解版)

    在这个“hibernate双向多对多关联映射(注解版)”的主题中,我们将深入探讨如何使用Hibernate的注解配置来处理数据库中的双向多对多关联关系。 首先,多对多关联在数据库设计中是指两个实体之间存在多个对应关系,...

    Hibernate-基础联表模板

    综上所述,"Hibernate-基础联表模板"涵盖了Hibernate中关于联表查询的基础知识,包括各种查询方式、关联关系的定义、Fetch策略以及查询结果的处理等,是开发者进行数据库操作的有力助手。通过这个模板,开发者可以...

    hibernate 级联(cascade和inverse)一对多

    例如,你可以创建一个父实体,添加一些子实体,并设置级联操作为`CascadeType.ALL`,然后调用父实体的保存方法,观察数据库中是否同时保存了父实体和子实体。 四、数据库配置和Jar包 为了使用Hibernate,你需要正确...

    hibernate表之间3种双向关联映射

    总结来说,Hibernate中的双向关联映射是对象关系映射的重要组成部分,包括双向多对多、双向一对多和双向一对一。理解并熟练运用这些映射方式,有助于开发者更好地实现Java应用程序与数据库间的交互,提高开发效率和...

    hibernate 双向一对一基于主键的关联映射

    双向关联需要在两个类中都添加`@OneToOne`注解,并指定`mappedBy`属性来定义被引用方。 ```java @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; /...

    hibernate双向一对多增删查改的例子

    在Java的持久化框架Hibernate中,双向一对多关联是一种常见的数据模型关系,它涉及到两个实体类,一个实体可以有多个另一个实体的实例。本示例将深入探讨如何使用Hibernate进行双向一对多关系的增删查改操作。 首先...

    Hibernate ORM - 一对多双向连接表关联关系

    在Hibernate中,这需要在两个类中都添加对应的导航属性,并使用`@ManyToOne`和`@OneToOne`注解。 4. **配置关联**:可以通过XML映射文件(hbm.xml)或使用Java配置(@JoinColumn,@JoinTable等)来定义关联。XML...

    Hibernate分页显示和添加

    本示例将探讨如何使用Hibernate实现分页显示数据,并进行基本的添加操作。分页是处理大量数据时必不可少的功能,它可以提高用户体验,避免一次性加载过多数据导致页面响应变慢。 首先,我们需要理解Hibernate的核心...

    hibernate一对多,多对一,一对多双向关联

    “Hibernate 一对多,多对一,一对多双向关联”是指在Java持久化框架Hibernate中,实体间常见的三种关联关系。在数据库设计中,这种关联关系是常见的,例如一个用户可以有多个订单(一对多),一个订单对应一个用户...

    Hibernate ORM - 一对多双向关联关系

    标题“Hibernate ORM - 一对多双向关联关系”指的是在数据库建模中,Hibernate ORM(对象关系映射)框架如何处理一个实体类(如User)与多个实体类(如Article)之间的关系。在这种关系中,一个用户可以拥有多个文章...

    hibernate_联级操作

    hibernate联级操作

Global site tag (gtag.js) - Google Analytics