本例以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",则表示在删除一方的时候,会删除与它关联的实体对象,如果没有设置这个属性,那么当删除一方的时候,如果找到对应的子记录,则删除报错,违反约束。
最后,欢迎访问风格清新简洁的轻博客网站[指尖一刻]