学习各种映射关系时总结:
①如何将对象之间的关联关系映射到数据库中
②如何检索出关联对象
1.多对一映射
它是使用最多的映射关系,性能上占有优势
关系模型和对象模型:两者并不是一一对应的
举个例子:告诉员工属于哪个部门和告诉部门有哪些员工对于 数据库(关系模型)来说只要有一个就可以
但是对于对象模型不是如此,告诉员工属于哪个部门之后,部门并不会知道自己有哪些员工
实例:
domain 包中添加
Department .java
/** * @Author:胡家威 * @CreateTime:2011-8-15 下午10:03:58 * @Description: */ package com.yinger.domain; public class Department { private int id; private String name; public int getId() { return id; } public String getName() { return name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } }
Employee.java
/** * @Author:胡家威 * @CreateTime:2011-8-15 下午10:05:08 * @Description: */ package com.yinger.domain; public class Employee { private int id; private String name; private Department depart; public int getId() { return id; } public String getName() { return name; } public Department getDepart() { return depart; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setDepart(Department depart) { this.depart = depart; } }
并添加两个新的 xml
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 package="com.yinger.domain"> <class name="Department"> <id name="id"> <generator class="native" /> </id> <property name="name"/> </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 package="com.yinger.domain"> <class name="Employee"> <id name="id"> <generator class="native" /> </id> <property name="name"/> <!-- 多对一映射 name是对应的属性名 column是对应的表的字段名[可以不指定] Hibernate 会自动的根据数据库中的这个字段的值到属性对应的类对应的表里查找对象 --> <many-to-one name="depart" column="depart_id"></many-to-one> </class> </hibernate-mapping>
然后在 Hibernate.cfg.xml 中添加两个新的mapping
<mapping resource="com/yinger/domain/Department.hbm.xml"/> <mapping resource="com/yinger/domain/Employee.hbm.xml"/>
最后,编写测试类和方法
/** * @Author:胡家威 * @CreateTime:2011-8-15 下午11:18:42 * @Description: */ package com.yinger.main; import org.hibernate.Session; import org.hibernate.Transaction; import com.yinger.domain.Department; import com.yinger.domain.Employee; import com.yinger.util.HibernateUtils; public class Many2One { public static void main(String[] args) { add(); } private static void add() { Department depart = new Department(); depart.setName("depart name"); Employee emp1 = new Employee(); emp1.setName("emp1 name"); emp1.setDepart(depart); Employee emp2 = new Employee(); emp2.setName("emp2 name"); emp2.setDepart(depart); Session s = null; Transaction tr = null; try{ s = HibernateUtils.getSession(); tr = s.beginTransaction(); s.save(depart); s.save(emp1); s.save(emp2); tr.commit(); }catch(Exception e){ if(tr!=null) tr.rollback(); }finally{ if(s!=null) s.close(); } } }
测试结果:控制台输出
数据库中的数据
建表语句:[MySQL 命令行中获取的]
修改save的顺序
s.save(emp1); s.save(emp2); s.save(depart);
Hibernate的sql语句:多了两天update,因为在保存(insert)emp时还没有建立department
2.一对多映射
它的关系模型和上面一样,也就是表的结构并不改变,但是对象模型改变了
实例:
在原有的 Department.java 中添加
属性 private Set<Employee> emps; 以及相应的get和set方法
删掉 Employee.hbm.xml 中的多对一映射
修改 Department.hbm.xml 添加
<!-- 一对多的映射,key属性一定要有,指定字段名,这个字段是“多”的那个表中的字段名 class属性是指set中的元素的类型 --> <set name="emps"> <key column="depart_id" /> <one-to-many class="Employee"/> </set>
最后编写测试类:One2Many.java
/** * @Author:胡家威 * @CreateTime:2011-8-15 下午11:18:42 * @Description: */ package com.yinger.main; import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.Transaction; import com.yinger.domain.Department; import com.yinger.domain.Employee; import com.yinger.util.HibernateUtils; public class One2Many { public static void main(String[] args) { add(); } private static void add() { Department depart = new Department(); depart.setName("depart name"); Employee emp1 = new Employee(); emp1.setName("emp1 name"); Employee emp2 = new Employee(); emp2.setName("emp2 name"); Set<Employee> emps = new HashSet<Employee>(); emps.add(emp1); emps.add(emp2); depart.setEmps(emps); Session s = null; Transaction tr = null; try{ s = HibernateUtils.getSession(); tr = s.beginTransaction(); s.save(emp1); s.save(emp2); s.save(depart); tr.commit(); }catch(Exception e){ if(tr!=null) tr.rollback(); }finally{ if(s!=null) s.close(); } } }
测试结果:三条 insert 和 两条 update,先保存emp,这时的emp的depart_id为null,所以当插入了depart之后,就要update了
因为这个时候的emp都是持久对象,Hibernate会自动的检测它们的改变并更新
即使修改了save顺序,结果还是一样,因为插入了depart之后,还要根据 depart.setEmps(emps); 确定depart和emp的关系,所以还是要更新
数据库的结果和上面的多对一是一样的
3.一对一映射
主对象和从对象
主对象如果没有从对象可以,但是从对象没有主对象是不行的
查找主对象时只用了一条sql语句,使用了outer join
查找从对象时用了两条语句,首先查从对象,然后查主对象(如果要使用从对象对应的主对象)
两种映射方法:① 基于主键的 一对一
② 基于外键的 一对一
测试实例:
添加两个domain Object:
Person.java
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:44:38 * @Description: */ package com.yinger.domain; public class Person { private int id; private String name; private IdCard idCard; public int getId() { return id; } public String getName() { return name; } public IdCard getIdCard() { return idCard; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } }
IdCard.java
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:45:35 * @Description: */ package com.yinger.domain; import java.util.Date; public class IdCard { private int id; private Date life; private Person person; public int getId() { return id; } public Person getPerson() { return person; } public void setId(int id) { this.id = id; } public void setPerson(Person person) { this.person = person; } public Date getLife() { return life; } public void setLife(Date life) { this.life = life; } }
添加 映射文件
如果是第一种,基于主键的一对一:此时 person表中id和id_card 表中的id一一对应
Person.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 package="com.yinger.domain"> <class name="Person"> <id name="id"> <generator class="native" /> </id> <property name="name"/> </class> </hibernate-mapping>
IdCard.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 package="com.yinger.domain"> <class name="IdCard" table="id_card"> <id name="id"> <generator class="foreign"> <param name="property">person</param> </generator> </id> <property name="life" /> <one-to-one name="person" constrained="true"/> </class> </hibernate-mapping>
如果是第二种,基于外键的一对一:此时 id_card 表中的字段 person_id 与 person 表中的 id对应
Person.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 package="com.yinger.domain"> <class name="Person"> <id name="id"> <generator class="native" /> </id> <property name="name"/> </class> </hibernate-mapping>
IdCard.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 package="com.yinger.domain"> <class name="IdCard" table="id_card"> <!-- 基于外键的一对一映射,加上了unique="true"约束,相当于就是一对一映射 首先假设多个idCard对应一个person,但是加上了unique约束之后就变成了一个idCard对应一个person --> <id name="id"> <generator class="native" /> </id> <property name="life" /> <many-to-one name="person" column="person_id" unique="true"></many-to-one> </class> </hibernate-mapping>
添加了 mapping 映射之后,编写测试类 One2One.java
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:52:21 * @Description: */ package com.yinger.main; import java.util.Date; import org.hibernate.Session; import org.hibernate.Transaction; import com.yinger.domain.IdCard; import com.yinger.domain.Person; import com.yinger.util.HibernateUtils; public class One2One { public static void main(String[] args) { add(); } private static void add() { Person p = new Person(); p.setName("person name"); IdCard card = new IdCard(); card.setLife(new Date()); //p.setIdCard(card); // 外键一对一映射的这种情况下 id_card表中的person_id字段没有值 card.setPerson(p); Session s = null; Transaction tr = null; try{ s = HibernateUtils.getSession(); tr = s.beginTransaction(); s.save(p); s.save(card); tr.commit(); }catch(Exception e){ if(tr!=null) tr.rollback(); }finally{ if(s!=null) s.close(); } } }
结果:
sql语句: 都是 两条 sql 语句
数据库数据:
基于 主键的 情况,id_card 表没有 person_id 字段
基于 外键的 情况,id_card 表有 person_id 字段
4.多对多映射
使用的不是很多,要注意数据量的大小对性能的影响,因为多对多需要查三张表
测试实例:
Teacher.java
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:44:38 * @Description: */ package com.yinger.domain; import java.util.Set; public class Teacher { private int id; private String name; private Set<Student> stus; public int getId() { return id; } public String getName() { return name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public Set<Student> getStus() { return stus; } public void setStus(Set<Student> stus) { this.stus = stus; } }
Student.java
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:44:38 * @Description: */ package com.yinger.domain; import java.util.Set; public class Student { private int id; private String name; private Set<Teacher> teas; public int getId() { return id; } public String getName() { return name; } public void setId(int id) { this.id = id; } public void setName(String name) { this.name = name; } public Set<Teacher> getTeas() { return teas; } public void setTeas(Set<Teacher> teas) { this.teas = teas; } }
hbm.xml
Teacher.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 package="com.yinger.domain"> <class name="Teacher"> <id name="id"> <generator class="native" /> </id> <property name="name"/> <set name="stus" table="teacher_student"> <key column="teacher_id"></key> <many-to-many class="Student" column="student_id"></many-to-many> </set> </class> </hibernate-mapping>
Student.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 package="com.yinger.domain"> <class name="Student"> <id name="id"> <generator class="native" /> </id> <property name="name"/> <set name="teas" table="teacher_student"> <key column="student_id"></key> <many-to-many class="Teacher" column="teacher_id"></many-to-many> </set> </class> </hibernate-mapping>
添加到了 cfg 中之后,编写测试类:
/** * @Author:胡家威 * @CreateTime:2011-8-15 下午11:18:42 * @Description: */ package com.yinger.main; import java.util.HashSet; import java.util.Set; import org.hibernate.Session; import org.hibernate.Transaction; import com.yinger.domain.Student; import com.yinger.domain.Teacher; import com.yinger.util.HibernateUtils; public class Many2Many { public static void main(String[] args) { add(); } private static void add() { Teacher t1 = new Teacher(); t1.setName("teacher name 1"); Teacher t2 = new Teacher(); t2.setName("teacher name 2"); Student s1 = new Student(); s1.setName("student name 1"); Student s2 = new Student(); s2.setName("student name 2"); Set<Teacher> teas = new HashSet<Teacher>(); teas.add(t1); teas.add(t2); s1.setTeas(teas); s2.setTeas(teas); // 这一部分和上面的部分产生的效果是一样的,但是不能同时存在,否则会因为唯一性约束导致事务回滚,数据库中没有任何数据 // Set<Student> stus = new HashSet<Student>(); // stus.add(s1); // stus.add(s2); // t1.setStus(stus); // t2.setStus(stus); Session s = null; Transaction tr = null; try{ s = HibernateUtils.getSession(); tr = s.beginTransaction(); s.save(s1); s.save(s2); s.save(t1); s.save(t2); tr.commit(); }catch(Exception e){ if(tr!=null) tr.rollback(); }finally{ if(s!=null) s.close(); } } }
测试结果:
控制台输出:
数据库中的数据,新创建了三张表,这种多对多映射就是通过创建一个关联表来实现的
5. 组件映射
当一个类的属性很特殊,不是数据库中支持的类型,而且又算不上是一个实体,没有表与之对应时可以使用 组件映射
如果组件的属性不能和表中的字段简单对应的时候可以选择使用自定义用户类型!
测试:
People.java
/** * @Author:胡家威 * @CreateTime:2011-8-17 下午09:16:04 * @Description: */ package com.yinger.domain; public class People { private int id; private Name name; public int getId() { return id; } public void setId(int id) { this.id = id; } public Name getName() { return name; } public void setName(Name name) { this.name = name; } }
Name.java
/** * @Author:胡家威 * @CreateTime:2011-8-17 下午09:16:36 * @Description: */ package com.yinger.domain; public class Name { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
People.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 package="com.yinger.domain"> <class name="People"> <id name="id"> <generator class="native" /> </id> <component name="name" class="Name"> <property name="firstName"></property> <property name="lastName"></property> </component> </class> </hibernate-mapping>
测试类:
/** * @Author:胡家威 * @CreateTime:2011-8-16 上午12:52:21 * @Description: */ package com.yinger.main; import org.hibernate.Session; import org.hibernate.Transaction; import com.yinger.domain.Name; import com.yinger.domain.People; import com.yinger.util.HibernateUtils; public class ComponentTest { public static void main(String[] args) { add(); } private static void add() { People p = new People(); Name n = new Name(); n.setFirstName("firstName"); n.setLastName("lastName"); p.setName(n); Session s = null; Transaction tr = null; try{ s = HibernateUtils.getSession(); tr = s.beginTransaction(); s.save(p); tr.commit(); }catch(Exception e){ if(tr!=null) tr.rollback(); }finally{ if(s!=null) s.close(); } } }
测试结果:
6.关系映射的总结
①对于关联关系的查询,Hibernate一般都是使用两条sql语句将它查出来,但是一对一的情况里的查主对象例外,它是一条sql
②分析各种情况可以根据表的结构开始,用 关系模型来分析 对象模型
7.集合映射
xml –> Java集合类型 -> 特点 xml中需要配置的信息
set:->Set 没有重复,不保存加入的顺序
array:->Class[] 有顺序的 list-index
list:->List 可以重复,有顺序的 list-index
bag:->List 不保存顺序的List list-index
map:->Map map键值对的映射类型 map-key
编写 xml 方法
使用原则:多数情况下都是使用set,需要保证顺序使用list,但是想用List而又不需要保证顺序使用bag
注意点:
① 定义成 Set,而不是 HashSet
② 原来是 HashSet,保存了之后就不再是 HashSet 了,强制转型时会报错的!
原因是Hibernate进行的封装,变成了 PersistentSet,实现了 Set 接口,但是和 HashSet 没有关系,不能转型!
关系级联的设置
cascade:关系级联的处理方式,默认是 none
多对多和多对一 一般不配置级联
一对一 一般是 delete(前提是主从对象是同生共死的关系)
一对多 一般是 save-update
delete 就是说,比如删除一个部门,那么就要删除这个部门的所有的员工,这个一般是不符合实际的
inverse :是否放弃维护关联关系
如果是true的话,当某个对象是持久对象时,如果和它关联的对象发生了改变,Hibernate是不会产生update语句来进行更新的,所以会产生错误
注意:如果是true的话,那么一对多中的“多”一定要被告知是对应哪个“一”,否则数据库中“一”的字段会出现 null!
相关推荐
**标题详解:** "Hibernate教程06_关系映射之一对一单向主键关联" 在Hibernate框架中,关系映射是将数据库中的表关系映射到对象模型上的过程。本教程聚焦于一对一(One-to-One)单向主键关联,这是一种特定类型的...
在“Hibernate开源框架学习”这个主题中,我们可以深入探讨以下几个关键知识点: 1. **对象关系映射(ORM)**:ORM是Hibernate的核心特性,它允许将Java对象映射到数据库表,通过对象的增删改查来实现对数据库的...
在Java后端开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。这个名为“Hibernate映射解析 七种映射关系 后端 - Java”的压缩包文件显然包含了关于Hibernate映射关系的详细...
### hibernate验证框架学习 #### 一、简介与入门 **Hibernate Validator** 是一个流行的 Java 验证框架,它实现了 **JSR 349**(即 Java Bean Validation API)规范,提供了强大的验证功能,帮助开发者确保应用...
关系映射是Hibernate的核心特性之一,它通过映射XML配置文件或注解将Java类与数据库表之间的关系进行定义,使得数据操作更加灵活和便捷。 **一、Hibernate关系映射的基本概念** 1. **实体类与数据库表映射**:在...
这个包与相关的博客内容配合,提供了学习Hibernate的完整资源。 **1. Hibernate框架的核心概念** - **对象关系映射(ORM)**: Hibernate是ORM工具的代表,它将数据库表映射为Java类,表中的行映射为类的对象,列...
**hibernate框架学习实例** Hibernate 是一个强大的Java持久化框架,它简化了数据库与对象之间的交互,使得开发者可以更加专注于业务逻辑而不必过多地处理SQL语句。本实例是针对hibernate 3.x版本设计的教学案例,...
理解ORM的概念是学习Hibernate的第一步。 2. **Hibernate配置**: 在使用Hibernate时,我们需要配置一个名为`hibernate.cfg.xml`的文件,其中包含了数据库连接信息、方言、缓存策略等。学习如何正确配置这些参数...
本节课程主要围绕“hibernate 第一节课”,我们将深入探讨Hibernate的核心概念、配置、对象关系映射(ORM)以及如何使用它来执行基本的数据库操作,如添加、删除、修改和查询(CRUD操作)。 1. Hibernate核心概念:...
Hibernate框架是Java领域中一款非常重要的对象关系映射(ORM)工具,它为开发者提供了在关系数据库和面向对象编程之间建立桥梁的便利性。通过使用Hibernate,开发人员可以避免直接编写大量的SQL语句,而是使用Java...
Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者将数据库操作转化为对象模型,大大简化了数据访问层的开发工作。通过提供一个灵活的API,Hibernate允许我们以面向对象的方式处理数据库,使得数据的...
Hibernate 是一款开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序对数据库的操作。这个框架允许开发者用面向对象的方式来处理数据库操作,从而避免了传统SQL语句的繁琐和易错性。在这个“hibernate框架...
Java框架Hibernate是一个强大的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发者可以使用Java对象来处理数据库事务,而无需关心底层SQL语句。这份"java框架Hibernate详细PDF教学"是专业培训机构内部...
Hibernate学习笔记整理 以下是 Hibernate 框架的详细知识点: Hibernate 介绍 Hibernate 是一个 ORM(Object-Relational Mapping)框架,用于将 Java 对象映射到数据库表中。它提供了一个简洁的方式来访问和操作...
在IT领域,尤其是在Java开发中,Hibernate框架是一个至关重要的组件,它简化了对象关系映射(ORM)的过程,使得开发者可以更加专注于业务逻辑而非数据库操作。本篇文章将深入探讨Hibernate框架的环境搭建过程,以及...
Java框架Hibernate是一个...学习Hibernate框架,不仅可以提升数据库操作的效率,还能帮助开发者更好地理解和实践面向对象的设计原则。结合实际项目练习,可以深入理解其工作原理和最佳实践,从而在软件开发中游刃有余。
《Hibernate DOC中文文档》是学习Hibernate框架的重要参考资料,它详细阐述了Hibernate的核心概念、配置、对象关系映射(ORM)以及各种操作技巧。对于初学者和有经验的开发者来说,这份文档都是掌握Hibernate不可或...
《Hibernate3.3_学习笔记》是一份详细记录了Hibernate3.3版本特性和使用方法的文档,旨在帮助开发者深入理解和应用这一强大的对象关系映射(ORM)框架。Hibernate是Java开发中的一个明星库,它简化了数据库操作,...
9. **性能优化**:学习Hibernate如何处理批处理、连接池等性能优化策略,并在我们的框架中应用。 10. **测试与文档**:创建单元测试以验证框架的功能,同时编写清晰的文档,帮助其他开发者理解和使用我们的框架。 ...
Hibernate是一种广泛应用于Java开发中的对象关系映射(ORM)框架,它的核心价值在于简化了数据库操作,通过将Java对象模型与SQL关系模型进行映射,使得开发者可以使用面向对象的方式来处理数据库。Hibernate不仅管理...