各种关联映射

来源:互联网 发布:淘宝图标图片单个 编辑:程序博客网 时间: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();

                     }

              }

       }

}

原创粉丝点击