标签:hibernate
基本需求是:一个项目可以有多个开发人员,一个开发人员可以参加多个项目,因此项目和开发人员是多对多的关系。本文中的学习重点,还和前几篇文章一样,都是JavaBean类的映射文件中的配置。
Project.java
package com.rk.hibernate.h_many2many;
import java.util.Set;
public class Project
{
private int prjId;
private String prjName;
private Set<Developer> devps;
public int getPrjId()
{
return prjId;
}
public void setPrjId(int prjId)
{
this.prjId = prjId;
}
public String getPrjName()
{
return prjName;
}
public void setPrjName(String prjName)
{
this.prjName = prjName;
}
public Set<Developer> getDevps()
{
return devps;
}
public void setDevps(Set<Developer> devps)
{
this.devps = devps;
}
}Project.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.rk.hibernate.h_many2many" auto-import="true"> <class name="Project" table="T_Project"> <id name="prjId" column="id"> <generator class="native"></generator> </id> <property name="prjName" column="name"></property> <set name="devps" table="R_Project_Developer" inverse="true" cascade="save-update"> <key column="prjId"></key> <many-to-many column="devpId" class="Developer"></many-to-many> </set> </class> </hibernate-mapping>
Developer.java
package com.rk.hibernate.h_many2many;
import java.util.Set;
public class Developer
{
private int devpId;
private String devpName;
private Set<Project> prjs;
public int getDevpId()
{
return devpId;
}
public void setDevpId(int devpId)
{
this.devpId = devpId;
}
public String getDevpName()
{
return devpName;
}
public void setDevpName(String devpName)
{
this.devpName = devpName;
}
public Set<Project> getPrjs()
{
return prjs;
}
public void setPrjs(Set<Project> prjs)
{
this.prjs = prjs;
}
@Override
public String toString()
{
return "Developer [devpId=" + devpId + ", devpName=" + devpName + "]";
}
}Developer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.rk.hibernate.h_many2many" auto-import="true"> <class name="Developer" table="T_Developer"> <id name="devpId" column="id"> <generator class="native"></generator> </id> <property name="devpName" column="name"></property> <set name="prjs" table="R_Project_Developer"> <key column="devpId"></key> <many-to-many column="prjId" class="Project"></many-to-many> </set> </class> </hibernate-mapping>
App.java
package com.rk.hibernate.h_many2many;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class App
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Project.class)
.addClass(Developer.class)
.buildSessionFactory();
}
// 1. 多对多,保存 【只能通过一方维护另外一方,不能重复维护!】
@Test
public void testSave()
{
int i = 0;
Session session = sf.openSession();
session.beginTransaction();
// 创建项目对象
Project prj1 = new Project();
prj1.setPrjName("AO项目" + i);
Project prj2 = new Project();
prj2.setPrjName("电商项目" + i);
// 创建开发人员对象
Developer devp1 = new Developer();
devp1.setDevpName("张三" + i);
Developer devp2 = new Developer();
devp2.setDevpName("李四" + i);
Developer devp3 = new Developer();
devp3.setDevpName("王五" + i);
// 关系 【项目方来维护】
Set<Developer> set1 = new HashSet<Developer>();
set1.add(devp1);
set1.add(devp2);
Set<Developer> set2 = new HashSet<Developer>();
set2.add(devp2);
set2.add(devp3);
prj1.setDevps(set1);
prj2.setDevps(set2);
// 保存
session.save(devp1);
session.save(devp2);
session.save(devp3);
session.save(prj1);
session.save(prj2);
session.getTransaction().commit();
session.close();
System.out.println("执行结束!");
}
}| 序号 | 操作类型 | 是否影响 | 具体说明 |
|---|---|---|---|
| 1 | 保存数据 | 有影响 | inverse=false ,有控制权,可以维护关联关系; 保存数据的时候会把对象关系插入中间表; inverse=true, 没有控制权, 不会往中间表插入数据。 |
| 2 | 获取数据 | 无 | 获取数据只是参照中间表中保存的关系,并不会对这种关系进行修改,因此获取数据不会受到影响。 |
| 3 | 解除关联关系 | 有影响 | inverse=false ,有控制权, 解除关系就是删除中间表的数据。 inverse=true, 没有控制权,不能解除关系。 |
| 4 | 删除数据 | 有影响 | inverse=false, 有控制权。 先删除中间表数据,再删除自身。 inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除 |
App_Inverse.java
package com.rk.hibernate.h_many2many;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class App_Inverse
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Project.class)
.addClass(Developer.class)
.buildSessionFactory();
}
// 多对多
//1. 设置inverse属性,对保存数据影响?
// 有影响。
// inverse=false ,有控制权,可以维护关联关系; 保存数据的时候会把对象关系插入中间表;
// inverse=true, 没有控制权, 不会往中间表插入数据。
@Test
public void testSave()
{
int i = 6;
Session session = sf.openSession();
session.beginTransaction();
// 创建项目对象
Project prj1 = new Project();
prj1.setPrjName("AO项目" + i);
Project prj2 = new Project();
prj2.setPrjName("电商项目" + i);
// 创建开发人员对象
Developer devp1 = new Developer();
devp1.setDevpName("张三" + i);
Developer devp2 = new Developer();
devp2.setDevpName("李四" + i);
Developer devp3 = new Developer();
devp3.setDevpName("王五" + i);
// 关系 【项目方来维护】
Set<Developer> set1 = new HashSet<Developer>();
set1.add(devp1);
set1.add(devp2);
Set<Developer> set2 = new HashSet<Developer>();
set2.add(devp2);
set2.add(devp3);
prj1.setDevps(set1);
prj2.setDevps(set2);
// 保存
// session.save(devp1);
// session.save(devp2);
// session.save(devp3);
session.save(prj1); //上面的三条语句注释掉后,如果想保存成功,必须要设置级联保存
session.save(prj2);
session.getTransaction().commit();
session.close();
System.out.println("执行结束!");
}
//2 .设置inverse属性, 对获取数据影响? 无
@Test
public void testGet()
{
Session session = sf.openSession();
session.beginTransaction();
Project prj = (Project) session.get(Project.class, 3);
System.out.println(prj.getPrjName());
System.out.println(prj.getDevps());
session.getTransaction().commit();
session.close();
System.out.println("执行结束!");
}
//3. 设置inverse属性, 对解除关系影响?
// 有影响。
// inverse=false ,有控制权, 解除关系就是删除中间表的数据。
// inverse=true, 没有控制权,不能解除关系。
@Test
public void testClearRelation()
{
Session session = sf.openSession();
session.beginTransaction();
Project prj = (Project) session.get(Project.class, 3);
prj.getDevps().clear();
session.getTransaction().commit();
session.close();
System.out.println("执行结束!");
}
//4. 设置inverse属性,对删除数据的影响?
// inverse=false, 有控制权。 先删除中间表数据,再删除自身。
// inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除
@Test
public void testDelete()
{
Session session = sf.openSession();
session.beginTransaction();
Project prj = (Project) session.get(Project.class, 13);
if(prj != null)
{
session.delete(prj);
}
session.getTransaction().commit();
session.close();
System.out.println("执行结束!");
}
}标签:hibernate
原文地址:http://lsieun.blog.51cto.com/9210464/1825920