您的位置:首页 > 其它

映射

2016-06-19 23:25 323 查看


映射


集合映射

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>


关联映射


一对一



外键+唯一性约束

<!--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>


多对一映射与一对多

员工与部门



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.  映射的部门属性  :  dept
2.  映射的部门属性,对应的外键字段: dept_id
3.  部门的类型
-->
<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属性:

保存数据

有影响。

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

获取数据

无。

解除关联关系?

有影响。
inverse=false, 可以解除关联
inverse=true, 当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)

删除数据对关联关系的影响?

有影响。
inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
inverse=true, 没有控制权:如果删除的记录有被外键引用,会报错,违反主外键引用约束! 如果删除的记录没有被引用,可以直接删除。


cascade 属性

cascade 表示级联操作 【可以设置到一的一方或多的一方】

none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除


cascade和inverse有什么区别?

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


多对多映射

学生和老师的关系



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属性,在多对多种维护关联关系的影响?

保存数据

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

获取数据

无。

解除关系

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

删除数据

有影响。
inverse=false, 有控制权。 先删除中间表数据,再删除自身。
inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: