`
lovnet
  • 浏览: 6720798 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

Oracle培训(三十七)——Hibernate第三章知识点总结——第三章--实体关联关系映射

 
阅读更多

Oracle培训(三十七)——Hibernate第三章知识点总结——第三章--实体关联关系映射

Hibernate基础回顾

Hibernate映射基础

Hibernate-mapping/class/id/generator/property

Hibernate ID生成器

Hibernate内置ID生成器、自定义ID生成器

Hibernate数据类型

基本数据类型、JDBC数据类型、自定义数据类型

Hibernate对象生命周期

三种状态特征、区分、转换,持久态对象特性

目标

理解各个关联关系映射中数据建模

掌握并熟练应用一对一关联

掌握并熟练应用一对多关联

掌握并熟练应用多对多关联

知识点预览

ORM映射规则

一对一关联

一对多关联

多对多关联

ORM映射规则

1. 映射概述

a) /表映射

b) 属性/字段映射

c) Map class associations to tables’ foreign key relationships

1:1/1:m/m:n

d) Map objects (instances of classes) to table rows

一对一关联

1. 一对一关联包括两种实现形式:

a) 唯一外键关联

b) 共享主键关联

2. 唯一外键关联

a) 唯一外键关联的一对一关系只是一对多关系的一个特例;

b) 唯一外键的实现是通过一方的主键作为另一方关联表的外键,并对外键做唯一性限制;

3. 唯一外键关联样例—数据模型

4. 唯一外键关联样例—POJO类片段

package com.oracle.entity;

public class Order {
private Integer Id;
private String name;
private Integer cost;
private Date createdDate;
private Address addr;
public Address getAddr() {
	return addr;
}
public void setAddr(Address addr) {
	this.addr = addr;
}
}

package com.oracle.entity;

public class Address {
private Integer Id;
private String street;
private String city;
private String zip;
private Order order;
public Order getOrder() {
	return order;
}
public void setOrder(Order order) {
	this.order = order;
}
}


5. 唯一外键关联样例—映射配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Order" table="T_ORDER">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="createdDate" ></property>
<one-to-one name="addr" class="com.oracle.entity.Address" outer-join="true“ 
cascade="all"></one-to-one>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Address" table="T_ADDRESS">
<id name="Id" >
	<generator class="native" />
</id>
<property name="street" ></property>
<property name="city" ></property>
<property name="zip" ></property>

<many-to-one name="order" column="order_id" unique="true" ></many-to-one>
</class>
</hibernate-mapping>


6. 唯一外键关联样例-摘要

7. 共享主键关联

a) 如果两张表是通过这种一对一关系相关联的,那么这两张表就共享同样的主关键字值

b) Hibernate中,通过one-to-one节点对一对一关系进行定义

8. 主键关联样例—数据模型

9. 共享主键关联样例—POJO类片段

package com.oracle.entity;

public class Order {
private Integer Id;
private String name;
private Integer cost;
private Date createdDate;
private Address addr;
public Address getAddr() {
	return addr;
}
public void setAddr(Address addr) {
	this.addr = addr;
}
}

package com.oracle.entity;

public class Address {
private Integer Id;
private String street;
private String city;
private String zip;
private Order order;
public Order getOrder() {
	return order;
}
public void setOrder(Order order) {
	this.order = order;
}
}


10. 共享主键关联样例—映射配置文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Order" table="T_ORDER">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="createdDate" ></property>

<one-to-one name="addr" class="com.oracle.entity.Address" outer-join="true“
cascade="all"></one-to-one>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Address" table="T_ADDRESS">
<id name="Id" >
      <generator class="foreign">
	<param name="property">order</param>
     </generator>
</id>
<property name="street" ></property>
<property name="city" ></property>
<property name="zip" ></property>

<one-to-one name="order" constrained="true" ></one-to-one>

</class>
</hibernate-mapping>


11. 共享主键关联样例—摘要

12. 一对一关联—持久化代码片段

package com.oracle.test;
import java.util.Date;

public class TestOnetoOne {
	public static void main(String[] args) {

		Address addr = new Address();
		addr.setCity("上海");
		addr.setStreet("南京东路");
		addr.setZip("021");
		
		Order order=new Order();
		order.setName("order1");
		order.setCost(200);
		order.setCreatedDate(new Date());
		order.setAddr(addr);
		addr.setOrder(order);

Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s = null;
Transaction tran = null;
try {
sf = cfg.buildSessionFactory();
s = sf.openSession();
tran = s.beginTransaction();
s.save(order);

tran.commit();
} catch (HibernateException e) {
e.printStackTrace();
tran.rollback();
}finally{
if(s!=null){s.close();}if(sf!=null){sf.close();}
}


13. cascade属性

a) cascade属性,级联操作,指的是当主控方执行操作时(样例中的Order),关联对象(样例中的Address)是否执行同步操作,如主控方执行save-updatedelete方法时,是否同时对关联对象执行save-updatedelete

b) cascade属性可选值:

none:所有情况下均不进行级联

save-update:在执行save-update时进行级联操作

delete:在执行delete时进行级联操作

all:所有情况下均进行级联操作

14. outer-join属性

a) outer-join属性,级联对象加载策略,指的是当主控方被加载时(样例中的Order),关联对象(样例中的Address)是以一个left outer join关联SQL语句加载还是另外使用一个单独的查询SQL加载。

b) select {……} from t_order left outer join t_address on order.id=addr.id where order.id=?

c) select {…} from t_order where id=?;select {…} from t_address where order_id=?

d) outer-join属性可选值:

true:总是使用outer-join

false:不使用outer-join

auto:如果关联对象没有采用Proxy机制,则使用outer-join

一对多关联

1. 一对多关联是应用最广泛的关联,一对多关联包括两种形式:

单向一对多关联

双向一对多关联

2. 一对多关联—数据模型

3. 单向一对多关联—POJO类片段

public class Order {
private Integer Id;
private String name;
private Integer cost;
private Date createdDate;
private Set<Item> items;
         ……
}

public class Item {
private Integer Id;
private String name;
private Double cost;
private Integer amount;
          ……
}


4. 单向一对多关联—映射配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Order" table="T_ORDER">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="createdDate" ></property>

<set name="items" cascade="all" >
<key column="order_id"></key>
<one-to-many class="com.oracle.entity.Item"/>
</set>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Item" table="T_ITEM">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="amount" ></property>


</class>
</hibernate-mapping>


5. 一对多关联样例—摘要

6. 单向一对多关联—持久化代码片段

package com.oracle.test;
public class TestOnetoMany {
	public static void main(String[] args) {

		Set<Item> items=new HashSet<Item>();
		Item item1 = new Item();
		item1.setName("item1");
		item1.setAmount(1);
		item1.setCost(12.5);
		items.add(item1);
		Item item2 = new Item();
		item2.setName("item2");
		item2.setAmount(1);
		item2.setCost(13.8);
		items.add(item2);
		
		Order order=new Order();
		order.setName("order1");
		order.setCost(200);
		order.setItems(items);

Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s = null;
Transaction tran = null;
try {
sf = cfg.buildSessionFactory();
s = sf.openSession();
tran = s.beginTransaction();
s.save(order);

tran.commit();
} catch (HibernateException e) {
e.printStackTrace();
tran.rollback();
}finally{
if(s!=null){s.close();}if(sf!=null){sf.close();}
}


7. 双向一对多关联—POJO类片段

package com.oracle.entity;

import java.util.Date;
import java.util.Set;

public class Order {
private Integer Id;
private String name;
private Integer cost;
private Date createdDate;
private Set<Item> items;
public Set<Item> getItems() {
	return items;
}
public void setItems(Set<Item> items) {
	this.items = items;
}

package com.oracle.entity;

public class Item {
private Integer Id;
private String name;
private Double cost;
private Integer amount;
private Order order;
public Order getOrder() {
	return order;
}
public void setOrder(Order order) {
	this.order = order;
}

}


8. 双向一对多关联—映射配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Order" table="T_ORDER">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="createdDate" ></property>

<set name="items" cascade="all" inverse="true">
<key column="order_id"></key>
<one-to-many class="com.oracle.entity.Item"/>
</set>
</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Item" table="T_ITEM">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="cost" ></property>
<property name="amount" ></property>

<many-to-one name="order" column="order_id" ></many-to-one>

</class>
</hibernate-mapping>


9. 双向一对多关联样例—摘要

10. 双向一对多关联—持久化代码片段

package com.oracle.test;
public class TestOnetoMany {
	public static void main(String[] args) {
		Set<Item> items=new HashSet<Item>();
		Item item1 = new Item();
		item1.setName("item1");
		item1.setAmount(1);
		item1.setCost(12.5);
		items.add(item1);
		Item item2 = new Item();
		item2.setName("item2");
		item2.setAmount(1);
		item2.setCost(13.8);
		items.add(item2);
		Order order=new Order();
		order.setName("order1");
		order.setCost(200);
		item1.setOrder(order);
		item2.setOrder(order);
		order.setItems(items);
Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s = null;
Transaction tran = null;
try {
sf = cfg.buildSessionFactory();
s = sf.openSession();
tran = s.beginTransaction();
s.save(order);

tran.commit();
} catch (HibernateException e) {
e.printStackTrace();
tran.rollback();
}finally{
if(s!=null){s.close();}if(sf!=null){sf.close();}
}


11. inverse属性

a) inverse属性,反转,用来指定关联关系的方向,指定由谁来负责关系的维护,inverse=false的一方负责关系的维护

b)one-to-many关系中,将many一方设为关系维护方(inverse=false),有助于性能的改善

12. lazy属性

a) lazy属性,延迟加载,即是否把主控方属性及关联对象一次性加载到内存中,lazy=false,不立即加载,等到用时再去数据库加载关联对象,lazy=true,立即加载关联对象

b)session关闭后再去加载关联对象,会报异常

多对多关联

1. 多对多关联

a) 多对多关联是最复杂的一个关联

b) 表示这一信息的最好方式是通过中间的关联类

c) Hibernate中,可以这个关联类映射为实体,任何一端映射两个一对多的关联

2. 多对多关联—数据模型

3. 多对多关联样例—POJO类片段

package com.oracle.entity;
public class Student {
private Integer Id;
private String name;
private String sex;
private Date birthday;
private Set<Course>  courses=new HashSet<Course>();
public Set<Course> getCourses() {
	return courses;
}
public void setCourses(Set<Course> courses) {
	this.courses = courses;
}
public void addCourse(Course c){
	this.courses.add(c);
	c.addStudent(this);
}

}
package com.oracle.entity;

public class Course {
private Integer Id;
private String name;
private String description;
private Set<Student> students=new HashSet<Student>();
public Set<Student> getStudents() {
	return students;
}
public void setStudents(Set<Student> students) {
	this.students = students;
}
public void  addStudent(Student s){
	this.students.add(s);
}
}


4. 多对多关联样例—映射文件配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Student" table="T_STUDENT">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="sex" ></property>
<property name="birthday" ></property>
<!– all 包含delete -->
<set name="courses"  cascade="save-update" table="ENROLLMENT" >
<key column="SID"></key>
<many-to-many class="com.oracle.entity.Course" column="CID"></many-to-many>
</set>

</class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.oracle.entity.Course" table="T_COURSE">
<id name="Id" >
	<generator class="native" />
</id>
<property name="name" ></property>
<property name="description" ></property>
<!– 多对多的任意一方配置inverse=“true”-->
<set name="students"  cascade="save-update" table="ENROLLMENT" inverse="true">
<key column="CID"></key>
<many-to-many class="com.oracle.entity.Student" column="SID"></many-to-many>
</set>

</class>
</hibernate-mapping>


5. 多对多关联样例—摘要

6. 多对多关联—持久化代码片段

public class TestManytoMany {
	public static void main(String[] args) {
		Course c1=new Course();
		c1.setName("corejava");
		c1.setDescription("java 语言基础!");

		Course c2=new Course();
		c2.setName("jdbc");
		c2.setDescription("java 连接数据库!");
		
		Student s1=new Student();
		s1.setName("rose");
		s1.addCourse(c1);
		
		Student s2=new Student();
		s2.setName("jack");
		s2.addCourse(c1);
		s2.addCourse(c2);
Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s = null;
Transaction tran = null;
try {
sf = cfg.buildSessionFactory();
s = sf.openSession();
tran = s.beginTransaction();
s.save(s1);
s.save(s2);
tran.commit();
} catch (HibernateException e) {
e.printStackTrace();
tran.rollback();
}finally{
if(s!=null){s.close();}if(sf!=null){sf.close();}
}

}
}


总结

一对一关联

唯一外键/共享主键

cascade/outer-join

一对多关联

单向/双向

inverse/lazy

多对多关联

中间表

问题

e-learning系统部分功能持久化实现

教师(T)、学生(S)、课程(C)

s:c=m:n

c:t=1:m

控制台出现课程列表(包括任课老师,已选学员人数),输入学生信息进行课程选择,相应的把最新课程列表展示出来。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics