数据的多对一关系
来源:互联网 发布:智能音箱 知乎 编辑:程序博客网 时间:2024/05/16 17:07
实体是Employee和Department,它们之间是多对一的关系。
Department类:
Employee类:
Department.hbm.xml:
Employee.hbm.xml:
many-to-one没有inverse属性,因为关系的维护是many的一方,不可能放弃对关系的维护。
many-to-one的lazy属性有三个取值:false, proxy, no-proxy。
1. 测试cascade属性:
结果是报org.hibernate.TransientObjectException异常,因为没有保存Department实例。
可以加cascade属性,解决问题:
2. 测试fetch
查询语句如下:
Hibernate: select employee0_.id as id1_0_, employee0_.name as name1_0_, employee0_.department as department1_0_, employee0_.skill as skill1_0_, employee0_.sell as sell1_0_, employee0_.type as type1_0_ from Employee employee0_ where employee0_.id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
因为fetch设置为select,所以对每个实体,都分别用一个SELECT语句
如果把fetch设置为join,也就是连表查询,只使用一个SELECT语句。如下:
Hibernate: select employee0_.id as id1_1_, employee0_.name as name1_1_, employee0_.department as department1_1_, employee0_.skill as skill1_1_, employee0_.sell as sell1_1_, employee0_.type as type1_1_, department1_.id as id0_0_, department1_.name as name0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.department=department1_.id where employee0_.id=?
3. 测试lazy
当fetch为select时,设置lazy为proxy或者no-proxy。
结果是报org.hibernate.LazyInitializationException异常。
因为fetch为select,而且lazy为proxy或者no-proxy,所以开始仅仅查询Employee,当需要用SELECT语句查询Department时,Session已经关闭。
解决办法:
1. 设置lazy为false,hibernate会第一时间把Employee和Department查询出来。
如果fetch为select,使用两个SELECT查询语句。
如果fetch为join,使用一个SELECT连表查询语句。
2. 设置fetch为join,这时不管lazy的取值,hibernate会进行连表查询,把两个实体都查询出来。
Department类:
- public class Department {
- private int id;
- private String name;
- public Department() {
- }
- public Department(String name) {
- this.name = name;
- }
- // getters and setters are omitted
- }
public class Department { private int id; private String name; public Department() { } public Department(String name) { this.name = name; } // getters and setters are omitted}
Employee类:
- public class Employee {
- private int id;
- private String name;
- private Department department;
- public Employee() {
- }
- public Employee(String name) {
- this.name = name;
- }
- // getters and setters are omitted
public class Employee { private int id; private String name; private Department department; public Employee() { } public Employee(String name) { this.name = name; } // getters and setters are omitted
Department.hbm.xml:
- <hibernate-mapping
- package=“com.john.myhibernate.domain”>
- <class name=“Department”>
- <id name=“id”>
- <generator class=“native”/>
- </id>
- <property name=“name” length=“20” not-null=“true”/>
- </class>
- </hibernate-mapping>
<hibernate-mapping package="com.john.myhibernate.domain"> <class name="Department"> <id name="id"> <generator class="native"/> </id> <property name="name" length="20" not-null="true"/> </class></hibernate-mapping>
Employee.hbm.xml:
- <hibernate-mapping package=“com.john.myhibernate.domain”>
- <class name=“Employee”>
- <id name=“id”>
- <generator class=“native”/>
- </id>
- <property name=“name” length=“20” not-null=“true”/>
- <many-to-one name=“department” column=“department_id” class=“Department” fetch=“select”/>
- </class>
- </hibernate-mapping>
<hibernate-mapping package="com.john.myhibernate.domain"><class name="Employee"> <id name="id"> <generator class="native"/> </id> <property name="name" length="20" not-null="true"/> <many-to-one name="department" column="department_id" class="Department" fetch="select"/></class></hibernate-mapping>
many-to-one没有inverse属性,因为关系的维护是many的一方,不可能放弃对关系的维护。
many-to-one的lazy属性有三个取值:false, proxy, no-proxy。
1. 测试cascade属性:
- public void testSaveCascade() {
- Session s = null;
- Transaction tx = null;
- Department depart = new Department();
- depart.setName(”FCI”);
- Employee em1 = new Employee(“John”);
- em1.setDepartment(depart);
- Employee em2 = new Employee(“Lucy”);
- em2.setDepartment(depart);
- try {
- s = HibernateUtil.getSession();
- tx = s.beginTransaction();
- s.save(em1);
- s.save(em2);
- tx.commit();
- } catch (HibernateException e) {
- tx.rollback();
- e.printStackTrace();
- } finally {
- if (s != null)
- s.close();
- }
- }
public void testSaveCascade() { Session s = null; Transaction tx = null; Department depart = new Department(); depart.setName("FCI"); Employee em1 = new Employee("John"); em1.setDepartment(depart); Employee em2 = new Employee("Lucy"); em2.setDepartment(depart); try { s = HibernateUtil.getSession(); tx = s.beginTransaction(); s.save(em1); s.save(em2); tx.commit(); } catch (HibernateException e) { tx.rollback(); e.printStackTrace(); } finally { if (s != null) s.close(); } }
结果是报org.hibernate.TransientObjectException异常,因为没有保存Department实例。
可以加cascade属性,解决问题:
- <many-to-one name=“department” column=“department_id” class=“Department” fetch=“select” cascade=“save-update”/>
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update"/>
2. 测试fetch
- Session s = null;
- s = HibernateUtil.getSession();
- Employee em = (Employee) s.get(Employee.class, 2);
- System.out.println(em.getName());
- System.out.println(em.getDepartment());
Session s = null; s = HibernateUtil.getSession(); Employee em = (Employee) s.get(Employee.class, 2); System.out.println(em.getName()); System.out.println(em.getDepartment());
查询语句如下:
Hibernate: select employee0_.id as id1_0_, employee0_.name as name1_0_, employee0_.department as department1_0_, employee0_.skill as skill1_0_, employee0_.sell as sell1_0_, employee0_.type as type1_0_ from Employee employee0_ where employee0_.id=?
Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_ from Department department0_ where department0_.id=?
因为fetch设置为select,所以对每个实体,都分别用一个SELECT语句
如果把fetch设置为join,也就是连表查询,只使用一个SELECT语句。如下:
Hibernate: select employee0_.id as id1_1_, employee0_.name as name1_1_, employee0_.department as department1_1_, employee0_.skill as skill1_1_, employee0_.sell as sell1_1_, employee0_.type as type1_1_, department1_.id as id0_0_, department1_.name as name0_0_ from Employee employee0_ left outer join Department department1_ on employee0_.department=department1_.id where employee0_.id=?
3. 测试lazy
当fetch为select时,设置lazy为proxy或者no-proxy。
- <many-to-one name=“department” column=“department_id” class=“Department” fetch=“select” cascade=“save-update” lazy=“no-proxy”/>
<many-to-one name="department" column="department_id" class="Department" fetch="select" cascade="save-update" lazy="no-proxy"/>
- Session s = null;
- s = HibernateUtil.getSession();
- Employee em = (Employee) s.get(Employee.class, 2);
- s.close();
- System.out.println(em.getName());
- System.out.println(em.getDepartment());
Session s = null; s = HibernateUtil.getSession(); Employee em = (Employee) s.get(Employee.class, 2); s.close(); System.out.println(em.getName()); System.out.println(em.getDepartment());
结果是报org.hibernate.LazyInitializationException异常。
因为fetch为select,而且lazy为proxy或者no-proxy,所以开始仅仅查询Employee,当需要用SELECT语句查询Department时,Session已经关闭。
解决办法:
1. 设置lazy为false,hibernate会第一时间把Employee和Department查询出来。
如果fetch为select,使用两个SELECT查询语句。
如果fetch为join,使用一个SELECT连表查询语句。
2. 设置fetch为join,这时不管lazy的取值,hibernate会进行连表查询,把两个实体都查询出来。
转发了原创作者的文章,在此说声对不起了。重点内容**
原创地址:http://czj4451.iteye.com/blog/1625965**
0 0
- 数据的多对一关系
- 多对一的关系映射
- 数据库一对一,多对一,多对多的关系
- 多对一关联关系
- Hibernate一对多、多对一关联关系的使用
- Hibernate的关系映射-------多对一与一对多
- hibernate的一对多和多对一关系映射
- hibernate双边的多对一、一对多关系
- hibernate 一对多 多对一 关系的理解
- Hibernate中一对多、多对一关系的映射
- Hibernate 多对一与一对多的关系
- MyBatis 一对多和多对一的关系
- 关联映射的关系(多对一)
- Hibernate中关联关系:多对一的学习
- Hibernate HelloWorld-06 单向多对一的映射关系
- Hibernate HelloWorld-07 双向多对一的映射关系
- Hibernate建立多对一的单向关联关系
- 数据1对多关系的一种思路
- bouml的简易教程(中文)
- 机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)
- java设计模式
- js 中getElementsByClassName的兼容性写法
- Tcar:智能车之ds18b20温度传感器实现温度采集模块
- 数据的多对一关系
- 【Nagios】【运维】Nagios 快速实现数据可视化的几种方式->统计图
- Android IPC机制-AIDL详解
- ARM指令格式
- 斯坦福自然语言组的NLP及计算语言学的资料汇总
- Runtime消息转发机制
- centos6.7 mini 安装 Galera Cluster
- QT编写多线程TCP文件接收服务器
- python写的crf训练代码