Hibernate中inverse属性-详细介绍
来源:互联网 发布:关于网络鬼片 编辑:程序博客网 时间:2024/06/05 10:37
这几天,复习Hibernate,没想到还感受了一把“温故而知新”的乐趣,废话少说,“实践才是检验真理的唯一标准” 直接上代码:
package com.hibernate.entity;import java.util.HashSet;import java.util.Set;/** * 部门实体类 * @author dabing * */public class Department {private int id;private String name;private Set<Employee> employees=new HashSet<Employee>();public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Set<Employee> getEmployees() {return employees;}public void setEmployees(Set<Employee> employees) {this.employees = employees;}}
package com.hibernate.entity;/** * 员工实体类 * @author dabing * */public class Employee {private int id;private String name;private Department department;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Department getDepartment() {return department;}public void setDepartment(Department department) {this.department = department;}}
Department.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"><hibernate-mapping><class name="com.hibernate.entity.Department"><id name="id"><generator class="sequence"><param name="sequence">department_id_seq</param></generator></id><property name="name"></property><set name="employees" table="Employee" inverse="false"><key column="d_id"></key><one-to-many class="com.hibernate.entity.Employee"/></set></class></hibernate-mapping>
Employee.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"><hibernate-mapping> <class name="com.hibernate.entity.Employee"> <id name="id"> <generator class="sequence"> <param name="sequence">employee_id_seq</param> </generator> </id> <property name="name"></property> <many-to-one name="department" column="d_id" class="com.hibernate.entity.Department"></many-to-one> </class></hibernate-mapping>
Hibernate辅助类:
package com.hibernate.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtil {private static Configuration configuration;private static SessionFactory sessionFactory;private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();static {configuration = new Configuration();configuration.configure();sessionFactory = configuration.buildSessionFactory();}public static Session getSession() {Session session = (Session) threadLocal.get();if (session == null || !session.isOpen()) {session = sessionFactory.openSession();threadLocal.set(session);}return session;}}
package com.entity;import org.hibernate.Session;import org.junit.Test;import com.hibernate.entity.Department;import com.hibernate.entity.Employee;import com.hibernate.util.HibernateUtil;public class TestInverse {public Session session=HibernateUtil.getSession();/** * * 注意: * * 一:代码1、代码2中: * * emp1.setDepartment(department)与emp2.setDepartment(department),说明了该员工属于那个部门,也就是在Employee与Department对象上建立起了关联 , * * 在数据库中,hibernate需要将对象上建立起的关联映射到数据库中, * * 也就是Employee(员工表)的外键更新为Department(部门表)的id主键,这样就在数据库中建立起了关联; * * (这也就是为什么会出现两条"update Employee set name=?, d_id=? where id=?"语句的原因) * * 注意: * * 1.如果在程序中先保存Employee(员工),然后在保存Department(部门),这时就相当于一个部门还有没有建立起来,就已经开始招员工了,等到部门建立起来 * 在将招收的员工 放到 该部门下(也就是update更新员工的外键列 ),所以这时会有两条update语句出现; * * 2.如果在程序中先保存Department(部门),然后在保存Employee(员工),因为这时Employee(员工)已经知道了所对应的Department(部门), * 所以这时就不会有这两条update语句出现了; * * * * * 二:代码3、代码4中: * * department.getEmployees().add(emp1)与 department.getEmployees().add(emp2),说明了该部门有哪些员工,也就是在Department与Employee对象上建立起了关联, * * 在数据库中,hibernate同样也需要将对象上建立起关联映射到数据库中(同样这里也是更新外键), * * 也就是Employee(员工表)的外键更新为Department(部门表)的id主键,这样就在数据库中建立起了关联; * * (这也就是为什么会出现两条"update Employee set d_id=? where id=?"语句的原因) * * * 三.在关系型数据库中: * * (在双向关联关系中) * * 不论是告诉员工(Employee)属于哪个部门(Department),程序中体现为 "emp1.setDepartment(department)" * * 还是告诉部门(Department)有哪些员工(Employee),在程序中体现为"department.getEmployees().add(emp2);" * * 还是都指定(也就是即告诉员工(Employee)属于哪个部门(Department),又告诉部门(Department)有哪些员工(Employee))的效果是一样的, * * 因为都会更新外键列的值, 所以说在关系型数据库中已经足够了, 但是,在对象关联关系中还不够完整.所以有时候 "在双向关联的时候设置双向关联关系"; * * * 四:谁在负责维护关联关系?(前提条件:映射文件中one方与many方的inverse属性都设置为false,也就是inverse属性为默认值时) * * <1> 代码1、代码2 中:现在的情况是:一旦指名了Employee员工属于哪个Department部门, * * 那么Employee员工就会负责维护关联关系,就会通知Hibernate更新数据库(也就是Employee员工需要记住它属于哪个Department部门) * * * <2>代码3、代码4 中:现在 的情况是:一旦指名了Department部门中有哪些Employee员工, * * 那么Department部门就会负责维护关联关系,就会通知Hibernate更新数据库(也就是Department部门需要记住它有哪些Employee员工) * * 我们得出结论:现在one方与many方都在负责维护关联关系,于是重复的通知Hibernate更新数据库, 试想效率是多么低下。 * * * * 五. inverse="true"(前提条件:应用与一对多的双向关联映射中): * * 1.inverse:"是否放弃维护关联关系"; * * 2.inverse="true" 意思: 表示该对象不负责(放弃)维护关联关系; (注意:Hibernate默认为false) * * 3.当你在部门(Department)中设置inverse="true"时, 这时就算你指名了Department部门中有哪些Employee员工时, * 也就是代码"department.getEmployees().add(emp1)",Hibernate也不会去更新数据库,因为这时部门(Department) * 已经不负责(放弃)维护关联关系 * * 最重要的一点:所谓的关系维护就是指外键列的更新; */@Testpublic void test_inverse(){Department department=new Department();department.setName("人力资源部");Employee emp1=new Employee();emp1.setName("张三");emp1.setDepartment(department); //代码1 对象模型,建立两个对象的关联 department.getEmployees().add(emp1); //代码3 对象模型,建立两个对象的关联Employee emp2=new Employee();emp2.setName("李四");emp2.setDepartment(department); //代码2 对象模型,建立两个对象的关联department.getEmployees().add(emp2); //代码4 对象模型,建立两个对象的关联session.beginTransaction();/** * 注意: * * 先保存emp1对象时,在生成的"insert into Employee (name, d_id, id) values (?, ?, ?)"语句中 ,d_id外键列这时肯定是null的; * * 原因: * * 因为我们在程序中设置了Employee与Department对象建立起了关联,也就是这句代码"emp1.setDepartment(department);", * * 因为我们这时是先保存的emp1对象,而department对象这时还没有保存(为null),所以说d_id外键列这时肯定是null的 * */session.save(department);session.save(emp1); session.save(emp2);session.getTransaction().commit();}}
对了,大家看了代码大半天,给大家说一个最重要的事情:“所谓的关系维护就是指外键列的更新”!
- Hibernate中inverse属性-详细介绍
- Hibernate inverse的属性介绍
- Hibernate的inverse,cascade属性简单介绍
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- Hibernate中inverse属性与cascade属性
- [*****] hibernate 中lazy、inverse、cascade属性
- hibernate 中lazy、inverse、cascade属性
- Hibernate中cascade与inverse属性详解
- Hibernate中cascade与inverse属性详解
- Hibernate中cascade与inverse属性详解
- Hibernate 中 元素的inverse 属性分析
- Hibernate中cascade与inverse属性详解
- [*****] hibernate 中lazy、inverse、cascade属性
- 黑马程序员_多线程
- 黑马程序员--多线程(一)
- java classpath
- Codeforces Round #180 (Div. 1)(完全)
- 女神瓦萨比-小黑中国力鉴淘宝给力明星店
- Hibernate中inverse属性-详细介绍
- 关于快速排序(quick sort)及其改进
- 苏一辰高精度乘法
- Git的一些入门知识
- adobe air 和 flash builder 和 flex 和flax 的区别。 越简单直观越好,不要官网的粘贴,看不懂。
- 黑马程序员--多线程(二)
- effective c++ 学习总结(第三章)
- Fuck libev (1) 第一个可运行例子
- Starling特色介绍