Inverse属性
Inverse属性,是在维护关联关系的时候起作用的。 表示控制权是否转移。(在一的一方起作用)
Inverse = true, 控制反转。
Inverse = false 不反转; 当前方有控制权
True 控制反转; 当前方没有控制权
<set name="emps" table="t_Employee" cascade="save-update,delete" inverse="false"> <key column="dept_id"></key> <one-to-many class="Employee"/> </set>
在一对多的维护关联关系中,是否设置inverse属性:
1. 保存数据
有影响。
如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL
测试结果如下:
2. 获取数据
无
3. 解除关联关系?
有影响
inverse=false, 可以解除关联
inverse=true, 当前(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
测试如下:
//解除关系 @Test public void testRemoveRelation() { Session session=sf.openSession(); session.beginTransaction(); //获取部门 Dept dept=(Dept)session.get(Dept.class, 2); //解除关系 dept.getEmps().clear(); session.getTransaction().commit(); session.close(); }
4. 删除数据对关联关系的影响?
有影响。
inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
inverse=true, 没有控制权: 如果删除的记录有被外键引用,会报错,违反外键约束! 如果删除的记录没有被引用,可以直接删除。
cascade 属性
cascade 表示级联操作 【可以设置到一的一方或多的一方】
none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除
hibernate常见面试题: inverse与cascade区别?
Cascade代表是否执行级联操作,Inverse代表是否由己方维护关系。
测试如下:
/** * 级联删除 */ @Test public void delete() { Session session=sf.openSession(); session.beginTransaction(); //获取部门 Dept dept=(Dept)session.get(Dept.class, 4); session.delete(dept); session.getTransaction().commit(); session.close(); }
会直接把Dept表的主键为4的元组删除,同时也会删除另外一张表中关联了该属性且值为4的记录
多对多映射
概述:
代码示例:
1、JavaBean
Project.java
package com.gqx.manytomany; import java.util.HashSet; import java.util.Set; /** * 封装项目信息 * @author 郭庆兴 * */ public class Project { private int prj_id; private String prj_name; //项目下的多个员工 private Set<Developer> developers=new HashSet<Developer>(); public int getPrj_id() { return prj_id; } public void setPrj_id(int prj_id) { this.prj_id = prj_id; } public String getPrj_name() { return prj_name; } public void setPrj_name(String prj_name) { this.prj_name = prj_name; } public Set<Developer> getDevelopers() { return developers; } public void setDevelopers(Set<Developer> developers) { this.developers = developers; } }
Developer.java
package com.gqx.manytomany; import java.util.HashSet; import java.util.Set; /** * 开发人员信息 * @author 郭庆兴 * */ public class Developer { private int d_id; private String d_name; //开发人员,参与多个项目 private Set<Project> projects=new HashSet<Project>(); public int getD_id() { return d_id; } public void setD_id(int d_id) { this.d_id = d_id; } public String getD_name() { return d_name; } public void setD_name(String d_name) { this.d_name = d_name; } public Set<Project> getProjects() { return projects; } public void setProjects(Set<Project> projects) { this.projects = projects; } }
2、映射文件
Developer.hbm.xml
<?xml version="1.0"?> <!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.gqx.manytomany"> <class name="Developer" table="t_developer" > <id name="d_id"> <generator class="native"></generator> </id> <property name="d_name" length="20"></property> <!-- 多对多的映射关系: 1、映射的集合的属性 name 2、集合属性,对应的中间表:"t_relation" 3、外键字段:did 4、外键字段,对应的中间表(t_relation)的字段:prjId" 5、集合元素的类型 --> <set name="projects" table="t_relation" > <key column="did"></key> <many-to-many column="prjId" class="Project"></many-to-many> </set> </class> </hibernate-mapping>
Project.hbm.xml
<?xml version="1.0"?> <!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.gqx.manytomany"> <class name="Project" table="t_project" > <id name="prj_id"> <generator class="native"></generator> </id> <property name="prj_name" length="20"></property> <!-- 多对多的映射关系: 1、映射的集合的属性 2、集合属性,对应的中间表:"t_relation" 3、外键字段:prjId 4、外键字段,对应的中间表(t_relation)的字段:did 5、集合属性元素的类型 --> <set name="developers" table="t_relation" inverse="false"> <key column="prjId"></key> <many-to-many column="did" class="Developer"></many-to-many> </set> </class> </hibernate-mapping>
3、测试类
package com.gqx.manytomany; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; public class Demo { private static SessionFactory sf; static{ sf=new Configuration(). configure(). addClass(Developer.class).addClass(Project.class) .buildSessionFactory(); } //只能通过一方维护另一方,不能重复维护 //developer_zs.getProjects().add(project_oa); //但是在一对多或是多对一种,是候可以的 @Test public void test() { Session session=sf.openSession(); session.beginTransaction(); //创建项目对象 Project project_ds=new Project(); project_ds.setPrj_name("电商系统"); Project project_oa=new Project(); project_oa.setPrj_name("OA系统"); //创建员工对象 Developer developer_zs=new Developer(); developer_zs.setD_name("张三"); Developer developer_ls=new Developer(); developer_ls.setD_name("李四"); Developer developer_ww=new Developer(); developer_ww.setD_name("王五"); //关系 通过项目方来保存 project_ds.getDevelopers().add(developer_ww); project_ds.getDevelopers().add(developer_ls); project_oa.getDevelopers().add(developer_ls); project_oa.getDevelopers().add(developer_zs); session.save(project_oa); session.save(project_ds); session.save(developer_ww); session.save(developer_ls); session.save(developer_zs); session.getTransaction().commit(); session.close(); } //解除关系 @Test public void testRemoveRelation() { Session session=sf.openSession(); session.beginTransaction(); Project prj=(Project)session.get(Project.class, 1); prj.getDevelopers().clear(); session.getTransaction().commit(); session.close(); } //删除 /* * inverse=true:有控制权,先删除中间表,在删除自身 * inverse=false:没有控制权。不能删除 */ @Test public void testRemove() { Session session=sf.openSession(); session.beginTransaction(); Project prj=(Project)session.get(Project.class, 2); session.delete(prj); session.getTransaction().commit(); session.close(); } }