各种关联映射
来源:互联网 发布:淘宝图标图片单个 编辑:程序博客网 时间:2024/06/11 12:46
一、多对一:employee表与department表
1、插入
1-1、外键允许为空的时候:
保存顺序:先保存了department表,后保存了employee表
执行结果:Hibernate: insert into Department (name) values (?)
Hibernate: insert into Employee (name, depart_id) values(?, ?)
代码如下图:
保存顺序为:先保存了employeet表,后保存了department表
执行结果为:Hibernate: insert into Employee (name, depart_id) values(?, ?)
Hibernate: insert intoDepartment (name) values (?)
Hibernate:update Employee set name=?, depart_id=? where id=?
注:这里出现update的原因是:再插入employee时候,外键depart_id还没有产生,再插入department表的时候,外键存在了,进而要更新employee表
代码如下图:
1-2、外键不允许为空的时候:
保存顺序:先保存了department表,后保存了employee表
执行结果:Hibernate: insertinto Department (name) values (?)
Hibernate: insert into Employee (name, depart_id) values(?, ?)
代码如下:
:
保存顺序为:先保存了employeet表,后保存了department表
执行结果为:会抛如下异常Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value:com.hbsi.domain.Employee.depart
注:因为 <many-to-one name="depart" column="depart_id"not-null="true"/> 映射的时候设置的为不为空,但是先保存employee时,键值为空的所以抛异常
代码如下:
2、查询
会执行查询语句两次,一次employee表的查询,一次department表的查询,是由于employee表的外键在设置类型的时候,设置成了department类对象类型,实现了多次查询
涉及到懒加载的问题:由于session已经关闭
解决懒加载问题:Hibernate.initialize(e.getDepart());解决懒加载问题9
二、一对多:departmnet表与Employee表
Employee表格的映射文件:
<?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.hbsi.domain">
<class name="Employee">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="depart"column="depart_id" not-null="true"/>
</class>
</hibernate-mapping>
Department.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.hbsi.domain">
<class name="Department">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="emps">
<key column="depart_id"/>
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
测试类:
package com.hbsi.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hbsi.domain.Department;
import com.hbsi.domain.Employee;
import com.hbsi.hibrnate.HibrnateUtil;
public class One2Many {
publicstatic void main(String[] args) {
add();
//query(6);
}
publicstatic Department add(){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
Departmentdep=new Department();
dep.setName("departone");
Employeeel=new Employee();
el.setName("tom");
el.setDepart(dep);//对象模型:两个对象建立了关联
Employeee2=new Employee();
e2.setName("jerry");
e2.setDepart(dep);
Set<Employee>set=new HashSet<Employee>();
set.add(el);
set.add(e2);
dep.setEmps(set);//告诉部门有哪些员工
s.save(dep);
s.save(el);
s.save(e2);
tx.commit();
return dep;
}finally{
if(s!=null){
s.close();
}
}
}
//能否正确查找
publicstatic Department query(int depId){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
//查询
Departmentd=(Department)s.get(Department.class,depId);
System.out.println(d.getName()+"----"+d.getEmps().size());
tx.commit();
returnd;
}finally{
if(s!=null){
s.close();
}
}
}
}
插入时执行的语句:
Hibernate: insert intoDepartment (name) values (?)
Hibernate: insert into Employee(name, depart_id) values (?, ?)
Hibernate: insert into Employee(name, depart_id) values (?, ?)
查询时执行的语句:先查询department表格在查询demployee表格
Hibernate: select department0_.idas id1_0_, department0_.name as name1_0_ from Department department0_ wheredepartment0_.id=?
Hibernate: select emps0_.depart_id asdepart3_1_1_, emps0_.id as id1_, emps0_.id as id2_0_, emps0_.name as name2_0_,emps0_.depart_id as depart3_2_0_ from Employee emps0_ where emps0_.depart_id=?
三、一对一主键关联关系:person表和idcard表
主要是改变从对象idcard表格中的id的生成方式,让person的主键作为idcard表的主键
Person.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.hbsi.domain">
<class name="Person">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"/>
<one-to-one name="idCard"/>
</class>
</hibernate-mapping>
Idcard.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.hbsi.domain">
<class name="IdCard" table="id_card">
<id name="id"column="id">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="userfulLife"column="userful_life"/>
<one-to-one name="person"/>
</class>
</hibernate-mapping>
测试类:
package com.hbsi.test;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hbsi.domain.Department;
import com.hbsi.domain.Employee;
import com.hbsi.domain.IdCard;
import com.hbsi.domain.Person;
import com.hbsi.hibrnate.HibrnateUtil;
public class One2One {
publicstatic void main(String[] args) {
//add();
query(2);
}
//能否正确插入
publicstatic Person add(){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
//增加
IdCardidCard=new IdCard();
idCard.setUserfulLife(newDate());
Personp=new Person();
p.setName("rose");
p.setIdCard(idCard);
idCard.setPerson(p);
s.save(p);
s.save(idCard);
tx.commit();
returnp;
}finally{
if(s!=null){
s.close();
}
}
}
//查找主对象
publicstatic Person query(int personId){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
//查询
Personp=(Person)s.get(Person.class, personId);
System.out.println(p.getName()+"----"+p.getIdCard().getUserfulLife());
tx.commit();
returnp;
}finally{
if(s!=null){
s.close();
}
}
}
//查找从对象idcard,
public static IdCard query1(int id){
Session s=null;
Transaction tx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
//查询
IdCard i=(IdCard)s.get(IdCard.class,id);
System.out.println(i.getPerson().getName());
tx.commit();
return i;
}finally{
if(s!=null){
s.close();
}
}
}
}
插入:
插入时可以不设置主对象person的idcard值,即:p.setIdCard(idCard);
但是,不能不指出idcard归哪个person,即:idCard.setPerson(p);
查询主对象person:
左外连接,只做一次查询。
Hibernate: select person0_.id as id3_1_,person0_.name as name3_1_, idcard1_.id as id4_0_, idcard1_.userful_life asuserful2_4_0_ from Person person0_ left outer join id_card idcard1_ onperson0_.id=idcard1_.id where person0_.id=?
查询从对象idcard:
查询两次:第一次查询idcard,第二次用左外连接查询person
四、多对多:在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型;Hibernate会为我们创建中间关联表,转换成两个一对多。
<set name="teacher"table="teacher_student">
<keycolumn="teacher_id"/>
<many-to-manyclass="Student" column="student_id"/>
</set>
Student.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.hbsi.domain">
<class name="Student">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="teacher"table="teacher_student">
<key column="student_id"/>
<many-to-many class="Teacher" column="teacher_id"/>
</set>
</class>
</hibernate-mapping>
Teacher.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.hbsi.domain">
<class name="Teacher">
<id name="id"column="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 以teacher_id为主键来查中间表,然后以中间表中student_id来查询最终的student表,
teacher_id和student_id都是分别以teacher和student表格的主键作为hibrnate自动生成的中间表的主键-->
<set name="students"table="teacher_student"><!-- table属性指定中间表的名字 -->
<key column="teacher_id"/><!-- 以teacher_id为主键来查插中间表 -->
<many-to-many class="Student" column="student_id"/><!-- 最终查询的是student表 -->
</set>
</class>
</hibernate-mapping>
测试类:
package com.hbsi.test;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hbsi.domain.Employee;
import com.hbsi.domain.Student;
import com.hbsi.domain.Teacher;
import com.hbsi.hibrnate.HibrnateUtil;
public class many2many {
/**
* @param args
*/
publicstatic void main(String[] args) {
//TODO Auto-generated method stub
add();
query(1);
}
publicstatic void add(){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
Set<Teacher>ts=new HashSet<Teacher>();
Teacher t1=new Teacher();
t1.setName("t1name");
ts.add(t1);
Teachert2=new Teacher();
t2.setName("t2 name");
ts.add(t2);
Set<Student>ss=new HashSet<Student>();
Students1=new Student();
s1.setName("s1");
ss.add(s1);
Students2=new Student();
s2.setName("s2");
ss.add(s2);
t1.setStudents(ss);
t2.setStudents(ss);
//s1.setTeacher(ts);
//s2.setTeacher(ts);
s.save(t1);
s.save(t2);
s.save(s1);
s.save(s2);
tx.commit();
}finally{
if(s!=null){
s.close();
}
}
}
//查找
publicstatic void query(int id){
Sessions=null;
Transactiontx=null;
try{
s=HibrnateUtil.getSession();
tx=s.beginTransaction();
Teachert=(Teacher)s.get(Teacher.class, id);
System.out.println("教师的姓名:"+t.getName());
System.out.println("students:"+t.getStudents().size());
Iterator<Student>it=t.getStudents().iterator();
while(it.hasNext()){
Studentstudent=it.next();
System.out.println(student.getName());
}
Studentstudnet1=(Student)s.get(Student.class, id);
System.out.println("学生的姓名:"+t.getName());
System.out.println("教师列表:");
Iterator<Teacher>ite=studnet1.getTeacher().iterator();
while(ite.hasNext()){
Teacherteacher=ite.next();
System.out.println(teacher.getName());
}
tx.commit();
}finally{
if(s!=null){
s.close();
}
}
}
}
- 各种关联映射
- 各种关联映射的实例
- Hibernate各种关联映射关系梳理
- 关联映射
- 关联映射
- 关联映射
- 关联映射
- 关联映射
- 关联映射
- 关联映射
- 关联映射-双向关联
- 关联映射(hibernate映射)
- Hibernate关联映射-----一对一关联
- JPA关联映射 - 一对一映射
- Hibernate集合映射、关联映射
- 关联关系映射
- 关联关系映射
- 关联关系映射
- android的Handler
- 个人感受
- java.lang.Integer.toHexString(b[n] & 0XFF)中0XFF使用
- 【信息采集】IBM AIX系统硬件信息查看命令(shell脚本)
- Activity概述
- 各种关联映射
- python学习2--列表和元组
- C#、devExpress 的 给bandedGrid加菜单功能 :复制、粘贴的例子
- Vb.net声明API
- 【大气红歌】著名民通歌唱家拉齐的音乐之路
- Android 中Monkey的用法
- JSP中include指令和include动作的区别
- C++前向声明注意
- 经历