Hibernate框架开发笔记 lesson2 关联关系映射

来源:互联网 发布:怎么用手机在知乎提问 编辑:程序博客网 时间:2024/05/23 12:23

关联关系映射

   jdbc:    使用   join  多表连接

   Hibernate:  对象   关联映射 通过一个对象,就可以把关联的对象查询出来


一对一(唯一外键一对一)

    学生 和学生证(paper) 的关系一对一

例表如下

   Student     table  
      sid(pk)  sname  sex

   Paper   table
      pid(pk)   pdesc  sid(fk)
   
   在Student实体类的添加关系属性
      private Paper paper ; 表示这个个学生对象拥有这个学生证

配置student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="entity">
   <class name="Student"  table="student">
    <id name="sid"   type="integer">
  
         配置主键生成器():
           assigned:  程序员自己指定  一般不用  因为程序员不知道数据库内数据随意指定会造成主键重复
           increment:  自增的   底层原理max(id)+1     企业生产环境一般不用(多人同时操作时会造成主键重复冲突)   
           native  :  本地数据库的自增策略(根据安装的数据库类型)实现主键自增 删除记录后,再添加不会出现之前的主键值
                             mysql:  auto_increment,  要求建表的时候一定加上auto_increment
                             oracle: sequence  通过序列(oracle中的对象)来自增   要求有对应的序列 
                             sqlserver: identity  要求建表的 时候  加上identity
           uuid  :  采用uuid算法 会生成32位 由 字母 数字  组成的  不重复的字符串 
           sequecne:  只能用在支持sequece序列的数据库(oracle等)中
         <generator class="native"></generator>
    </id>
<property name="sname" type="string"></property>
    <property name="sex" type="string"></property>
 <!--  配置关系属性    与Paper的一对一的关系
      配置关系属性四要素:
         1)关系属性名
  (要配的属性)   
         2)关系属性名对应
类名  (底层实际要找对应的表名)
         3)配置外键:间接配置外键  通过参照了Paper类的关系属性(student) 间接获取外键列
   
                      直接配置的  column="sid"
             间接配置: property-ref="属性名"
          4)级联  cascade 选配  操作一个对象是否要影响另一个对象   谨慎配置     none/delete/save-update/all
    -->
    <one-to-one name="paper" class="Paper"  property-ref="student" cascade="all">
    </one-to-one>
   </class>
</hibernate-mapping>
                 

    在Paper实体类的添加关系属性
       private Student  student ; 表示这个个学生证对象属于这个学生

 配置student.hbm.xml

   <!-- 配置关系属性   与Student的一对一的关系
       unique:true   外键不能重复  通过这个属性 使many to one 表达成了一对一
       配置关系属性的四要素:
        a.name  配置关系属性名  
        b.class   配置关系属性对应类
        c.column   直接配置外键
        d.配置级联  cascade none/save-update/delete/all
       -->
  <many-to-one name="student" class="Student" column="sid"unique="true" cascade="none"></many-to-one>
 

  共享主键一对一

  person  和 passport 一对一   用一列同时充当主键和外键
例表如下
  person(人)
  pid(pk)   pname   psex
   101        张三    男
   102        李四    女
 passport(护照)
         pid(pk+fk)    ptype    expire  
          101           美国护照      2
          102           英国护照      3

    在Passport实体类添加关系属性
 Person  person   一个护照属于一个人 

配置 person.hbm.xml

   <!-- 配置关系属性  与Passport的一对一的关系 
       在共享主键一对一中: 不用配置外键 
         hibernate能知道Passport对应的表的主键就是外键
      -->
     <one-to-one name="passport" class="Passport" cascade="none">
     </one-to-one>

配置 passport.hbm,xml

<id name="pid"  type="integer">
  <!-- 
    主键生成器:  不能自己指定 ,必须参照别人的
      foreign:参照外部一个属性  来获取主键值  一般只用在共享主键一对一
          配置的是Passport的关系属性名(person)
   -->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>

<!-- 配置关系属性 与Person的一对一的关系 
 在共享主键一对一中不需要配置外键,
   hibernate知道passport表的主键就是外键
   constrained:当前方是子表
-->
<one-to-one name="person"  class="Person"   cascade="none" constrained="true"></one-to-one>
                constrained = "true" 表明当前一方为子表 (需参照父表)

一对多:

  班级和学生的一对多
表如下
      grade
   gid(pk)       gname     
      1                  3a
      2                  3b
 
 student
          sid   sname  sex   gid(fk)
           10     张三     男       1
           20     李四     女       1 


grade 实体类中配置与学生一对多的关系属性
   private Set<Student>students = new HashSet<Student>()

student 实体类中配置与班级多对一的关系属性
   private Grade grade; 



配置grade.hbm.xml

  
<!-- 配置关系属性 
 与Student的一对多的关系
a.关系属性名  name
b.关系属性类名 class
c.外键 column
d.级联  cascade

  inverse:反转   student与grade的外键关系 交给谁来维护  只有set标签有
      true: 对方来维护  一般是交给多方来维护
            提升性能
 
fetch: 抓取策略  查询的机制    意义不大

      lazy:懒加载(延迟加载)
      false:       立即加载       在查询班级的时候 立即将这个班级中学生信息查询出来
      true :       延迟加载   在查询班级的时候 不会立即将这个班级的学生信息查询出来, 
      在使用或者获取学生的信息的时候 才去延迟查询.
 

<set  name="students" cascade="all"  lazy="true" inverse="true">配属性名
<key column="gid"></key>           配外键
<one-to-many class="Student"/>  配关系属性类名
 </set>

配置 student.hbm.xml

<many-to-one name="grade"  class="Grade"  column="gid"   cascade="none">
    </many-to-one>

多对多

  学生和课程多对多
 
例表如下
   student
     sid(pk)    sname    sex   
 101       张三       男      
 102       李四       女      
  sc(关系表  中间表)   
   sid(fk)    cid(fk)
     101       10
     101       20
     102       10
     102       20
 
   course
      cid(pk)       cname     
        10             struts2  
         20            hibernate   


 
sql:
  查询张三选了哪些课程(课程名称):
    select s.sname,c.cname
   from  student  s    join   sc    on  s.sid=sc.sid
      join   course  c    on    c.cid= sc.cid   where  s.sname='张三';  
       
   select s.sname,c.cname
   from  student  s    join   sc    on  s.sid=sc.sid and  s.sname='张三'
      join   course  c    on    c.cid= sc.cid ;


 
 student实体类中配置与课程多对多的关系属性
   private Set<Course>courses = new HashSet<Course>()

course 实体类中配置与学生多对一的关系属性
   private Set<Student>students= new HashSet<Student>(); 

配置student.hbm.xml

<!-- 配置关系属性  与Course的多对多关系
      结论:   三表 俩外键 
     1)关系属性名
     2)关系属性类
     3)外键
     4)级联
    -->
    <set name="cs"  table="sc" cascade="all" inverse="true"> 关系属性名 中间表
      <key  column="sid"></key>   学生表和关系表的关系外键
      <many-to-many class="Course"  column="cid"></many-to-many>  关系属性类名 ,关系表和另一个表的外键
    </set>

 配置course.hbm.xml

 <!-- 配置关系属性    与Student多对多关系  -->
    <set name="students" table="sc">
       <key column="cid"></key>
    <many-to-many class="Student"  column="sid"> </many-to-many>
    </set>


扩展:  

  设计表的原则(规范):三范式
     第一范式:   
   字段不可分割的  原子性的
     第二范式:
       每个表必须要有唯一标识的列 (表中必须有主键)     
     第三范式:
    a表的的一列参照了b的某列,     
    a表的别的列只能参照b表的其他列(参照唯一)
 

0 0