映射

来源:互联网 发布:js校验身份证号 编辑:程序博客网 时间:2024/04/30 15:41

映射

集合映射

  • JavaBean
// javabean设计public class User {private int userId;private String userName;// 一个用户,对应的多个地址private Set<String> address;private List<String> addressList = new ArrayList<String>(); //private String[] addressArray; // 映射方式和list一样     <array name=""></array>private Map<String,String> addressMap = new HashMap<String, String>();}
  • 集合映射配置
<?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="cn.csx.a_collection"><class name="User" table="t_user"><id name="userId" column="id"><generator class="native"></generator></id><property name="userName"></property><!-- set集合属性的映射name 指定要映射的set集合的属性table 集合属性要映射到的表key  指定集合表(t_address)的外键字段element 指定集合表的其他字段type 元素类型,一定要指定 --> <set name="address" table="t_address"> <key column="uid"></key> <element column="address" type="string"></element> </set>  <!--  list集合映射 list-index  指定的是排序列的名称 (因为要保证list集合的有序)  -->  <list name="addressList" table="t_addressList">    <key column="uid"></key>    <list-index column="idx"></list-index>    <element column="address" type="string"></element>  </list>    <!--   map集合的映射  key  指定外键字段  map-key 指定map的key   element  指定map的value   -->  <map name="addressMap" table="t_addressMap">  <key column="uid"></key>  <map-key column="shortName" type="string" ></map-key>  <element column="address" type="string" ></element>  </map>   </class></hibernate-mapping>

关联映射

一对一

image

  • 外键+唯一性约束
<!--IdCard.hbm.xml--><hibernate-mapping package="cn.csx.i_hbm_oneToOne">   <class name="IdCard" table="idCard">      <id name="id">           <generator class="native"/>      </id>      <property name="number"/><!-- person属性,Person类型。         表达的是本类与Person的一对一。         采用基于外键的一对一映射方式,本方有外键方。 --><many-to-one name="person" class="Person" column="personId" unique="true"/>   </class></hibernate-mapping><!--Person.hbm.xml--><hibernate-mapping package="cn.csx.i_hbm_oneToOne">   <class name="Person" table="person">      <id name="id">           <generator class="native"/>      </id>      <property name="name"/><!-- idCard属性,IdCard类型。         表达的是本类与IdCard的一对一。         采用基于外键的一对一映射方式,本方无外键方。         property-ref属性:            写的是对方映射中外键列对应的属性名。 --><one-to-one name="idCard" class="IdCard" property-ref="person"/>   </class></hibernate-mapping>
  • 基于主键
<!--IdCard.hbm.xml--><hibernate-mapping package="cn.csx.i_hbm_oneToOne2">   <class name="IdCard" table="idCard2">      <id name="id"><!-- 当使用基于主键的一对一映射时,            有外键方的主键生成策略一定要是foreign。            参数property:               生成主键值时所根据的对象。-->         <generator class="foreign">              <param name="property">person</param>         </generator>      </id>      <property name="number"/><!-- person属性,Person类型。         表达的是本类与Person的一对一。         采用基于主键的一对一映射方式,本方有外键方。 -->      <one-to-one name="person" class="Person" constrained="true"/>   </class></hibernate-mapping><!--Person.hbm.xml--><hibernate-mapping package="cn.csx.i_hbm_oneToOne2">   <class name="Person" table="person2">      <id name="id">           <generator class="native"/>      </id>      <property name="name"/><!-- idCard属性,IdCard类型。         表达的是本类与IdCard的一对一。         采用基于主键的一对一映射方式,本方无外键方。-->      <one-to-one name="idCard" class="IdCard"/>   </class></hibernate-mapping>

多对一映射与一对多

员工与部门

image

  • Dept类和Employee类
public class Dept {private int deptId;private String deptName;// 【一对多】 部门对应的多个员工private Set<Employee> emps = new HashSet<Employee>();}public class Employee {private int empId;private String empName;private double salary;// 【多对一】员工与部门private Dept dept;}
  • Dept.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="cn.itcast.b_one2Many"><class name="Dept" table="t_dept"><id name="deptId"><generator class="native"></generator></id><property name="deptName" length="20"></property><!-- 一对多关联映射配置  (通过部门管理到员工)Dept 映射关键点:1.  指定 映射的集合属性: "emps"2.  集合属性对应的集合表: "t_employee"3.  集合表的外键字段   "t_employee. dept_id"4.  集合元素的类型 --> <set name="emps">   <!-- table="t_employee" -->  <key column="dept_id"></key>  <one-to-many class="Employee"/> </set>  </class></hibernate-mapping>
  • Employee.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="cn.itcast.b_one2Many"><class name="Employee" table="t_employee"><id name="empId"><generator class="native"></generator></id><property name="empName" length="20"></property><property name="salary" type="double"></property><!-- 多对一映射配置Employee 映射关键点:1.  映射的部门属性  :  dept2.  映射的部门属性,对应的外键字段: dept_id3.  部门的类型 --> <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one> </class></hibernate-mapping>
  • 总结:

在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!

Inverse属性

  • Inverse属性,是在维护关联关系的时候起作用的,指定由哪一方来维护关联。

表示控制权是否转移。(在一的一方起作用)

  • Inverse , 控制反转。

  • Inverse = false 不反转; 当前方有控制权

    • True 控制反转; 当前方没有控制权
  • 维护关联关系中,是否设置inverse属性:

  1. 保存数据
    • 有影响。

    如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL

  1. 获取数据
    • 无。
  1. 解除关联关系?
    • 有影响。
    • inverse=false, 可以解除关联
    • inverse=true, 当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
  1. 删除数据对关联关系的影响?
    • 有影响。
    • inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
    • inverse=true, 没有控制权:如果删除的记录有被外键引用,会报错,违反主外键引用约束! 如果删除的记录没有被引用,可以直接删除。

cascade 属性

  • cascade 表示级联操作 【可以设置到一的一方或多的一方】
    • none 不级联操作, 默认值
    • save-update 级联保存或更新
    • delete 级联删除
    • save-update,delete 级联保存、更新、删除
    • all 同上。级联保存、更新、删除

cascade和inverse有什么区别?

可以这样理解,cascade定义的是关系两端对象到对象的级联关系;而inverse定义的是关系和对象的级联关系。

多对多映射

学生和老师的关系

image

  • Student和Teacher类
public class Student {    private Long id;    private String name;    private Set<Teacher> teachers=new HashSet<Teacher>();    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Set<Teacher> getTeachers() {        return teachers;    }    public void setTeachers(Set<Teacher> teachers) {        this.teachers = teachers;    }}public class Teacher {    private Long id;    private String name;    private Set<Student> students=new HashSet<Student>();    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Set<Student> getStudents() {        return students;    }    public void setStudents(Set<Student> students) {        this.students = students;    }}
  • Student.hbm.xml
<?xml version="1.0"?><!--  ~ Hibernate, Relational Persistence for Idiomatic Java  ~  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.  --><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping>    <!--name是类名,table是表名-->    <class name="cn.csx.hbm_properties_many2many.Student" table="Student">        <id name="id">            <generator class="native"/>        </id>        <property name="name"/>        <!-- teachers属性,Set集合。表达的是本类与Teacher的多对多。table属性:中间表(集合表)key子元素:集合外键(引用当前表主键的那个外键) -->        <set name="teachers" table="teacher_student" inverse="false">            <key column="studentId"/>            <many-to-many class="cn.csx.hbm_properties_many2many.Teacher" column="teacherId"/>        </set>    </class></hibernate-mapping>
  • Teacher.hbm.xml
<hibernate-mapping><!--name是类名,table是表名--><class name="cn.csx.hbm_properties_many2many.Teacher" table="Teacher">        <id name="id">            <generator class="native"/>        </id>        <property name="name"/><!-- students属性,Set集合。         表达的是本类与Student的多对多。-->        <set name="students" table="teacher_student" inverse="true">            <key column="teacherId"/>            <many-to-many class="cn.csx.hbm_properties_many2many.Student" column="studentId"/>        </set>    </class></hibernate-mapping>
  • 设置inverse属性,在多对多种维护关联关系的影响?
  1. 保存数据

    • 有影响。
    • inverse=false ,有控制权,可以维护关联关系;保存数据的时候会把对象关系插入中间表;
    • inverse=true, 没有控制权, 不会往中间表插入数据。
  2. 获取数据

    • 无。
  3. 解除关系

    • 有影响。
    • inverse=false ,有控制权, 解除关系就是删除中间表的数据。
    • inverse=true, 没有控制权,不能解除关系。
  4. 删除数据

    • 有影响。
    • inverse=false, 有控制权。 先删除中间表数据,再删除自身。
    • inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除
0 0