Hibernate总结(二)
在上一篇Hibernate总结(一)简单总结了一级缓存,快照,增删改查的简单使用,这一篇总结两张表的级联操作。
级联涉及到三种情况,many-many,1-many,many-1。
- 首先是1-many,many-1情况,所以先设置一个情景:客户与订单的关系
//因为太占版面缘故,没有列出get()/set()方法
public class Customer {
private Integer id;
private String name;
private Set<Order> orders = new HashSet<Order>();//1对多
}
public class Order {
private Integer id;
private String name;
private Customer customer;//多对1
}
接下来是hibernate.cfg.xml与两个实体类的配置文件Order.hbm.xml与Customer.hbm.xml,第一个不多说,主要是映射文件的配置
//Customer.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Customer" table="t_customer">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 一对多关系 -->
<!--
inverse:true 不维护关系,交给拥有外键一方维护
cascade:save-update(级联保存与级联更新),当然还有其它选项,delete(级联删除),all(级联保存,更新,删除),none(默认没有级联)
-->
<set name="orders" inverse="true" cascade="save-update">
<key column="cid"></key> <!-- 在Order表中的外键的名字-->
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
//Order.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Order" table="t_order">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对一关系 -->
<!-- 含有外键一方维护关系 -->
<many-to-one name="customer" column="cid" class="Customer"></many-to-one>
</class>
</hibernate-mapping>
一切准备就绪,开始级联的代码:
因为代码中大量使用了得到连接,关闭连接操作,所以我使用了模板设计模式,在我的文章《Hibernate-模板模式》有讲解
/**
* 级联保存:
* 1.inverse="true",维护关系,最好只有一方维护,而且是拥有外键一方维护
* 2.cascade="save-update",级联保存与级联更新
*/
@Test
public void test0() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Customer c=new Customer();
c.setName("King");
Order o1=new Order();
o1.setName("炒面");
Order o2=new Order();
o2.setName("肉"); o1.setCustomer(c);//由拥有外键一方维护关系
o2.setCustomer(c); s.save(c);
s.save(o1);
s.save(o2);//这样框架只执行了3条SQL语句
}
}.execute();
}
/**
* 级联删除:
* 1.inverse="false"为默认处理方式:把客户的订单的外键修改为null,然后再删除客户
* 2.inverse="true"若客户不处理,会出错
*/
@Test
public void test1() {
new SessionTemplate(){
@Override
public void fun(Session s) {
//这是没有使用级联删除的情况,这时cascade为save-update
Customer c=(Customer) s.get(Customer.class, 3);
for(Order o:c.getOrders()){
s.delete(o);
}
s.delete(c);//此时,inverse="true",所以前面删除了所有客户的订单才能删除客户 //更改配置文件,cascade为delete,这时就是级联删除
Customer c=(Customer) s.get(Customer.class, 3);
s.delete(c);//这时不需要手动删除订单了
}
}.execute();
}
/**
* 级联更新
* cascade为save-update
*/
@Test
public void test2() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Customer c=(Customer) s.get(Customer.class, 2);
for(Order o:c.getOrders()){
o.setName("羊杂汤");//持久态,不需要更新
}
}
}.execute();
}
查询涉及到了加载策略,所以很复杂,所以将在写在下一篇中。
- 接下来说many-many的情况,还是先设置一个情景:学生与课程的关系
public class Student {
private Integer id;
private String name;
private Set<Course> courses=new HashSet<>();//多对多
}
public class Course {
private Integer id;
private String name;
private Set<Student> students=new HashSet<>();//多对多
}
接下来是两个实体类与数据库表的映射文件:
//Student.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Student" table="t_student">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对多关系,在多对多中,需要双方都设置存储关系的表名 -->
<set name="courses" cascade="save-update" table="t_selectcourse">
<key column="sid"></key>
<many-to-many class="Course" column="cid"></many-to-many>
</set>
</class>
</hibernate-mapping>
//Course.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Course" table="t_course">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对多关系 -->
<!-- 维护权反转给对方 -->
<set name="students" inverse="true" table="t_selectcourse">
<key column="cid"></key>
<many-to-many class="Student" column="sid"></many-to-many>
</set>
</class>
</hibernate-mapping>
一切准备继续,开始代码工作:
/**
* 多对多
* 级联保存:
* 本来想也写上级联删除与级联更新,但是发现写的代码和我想要实现的结果不同,故没有贴出代码,额...我的意思就是我也不会...挺尴尬...
*/
@Test
public void test0() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Student s1=new Student();
s1.setName("King"); Course c1=new Course();
c1.setName("数学");
Course c2=new Course();
c2.setName("英语"); s1.getCourses().add(c1);//由学生维护关系
s1.getCourses().add(c2);//由学生维护关系 s.save(s1);
}
}.execute();
}
增删改查,现在就差“查”没有写出,我将在下一篇总结中写出Hibernate的关于查询的加载策略。
Hibernate总结(二)的更多相关文章
- Hibernate实例二
Hibernate实例二 一.测试openSession方法和getCurrentSession方法 hebernate中可以通过上述两种方法获取session对象以对数据库进行操作,下面的代码以及注 ...
- hibernate学习二(HelloWorld)
一.建立hibernate配置文件 在工程Hibernate_01_HelloWorld下的src上建立hibernate.cfg.xml,打开hibernate-release-4.3.11.Fin ...
- hibernate(二)annotation第一个示例
一.在数据库中创建teacher表(数据库hibernate) create table teache( id int auto_increment primary key, name ), titl ...
- hibernate学习(二)
hibernate 单向一对多映射 一.数据表设计 数据库名:hibernate5 数据表: ①表名:CUSTOMERS 字段: CUSTOMER_ID CUSTOMER_NAME ②表名:ORDE ...
- Hibernate(二)之Hibernate-api详解
一.Hibernate体系结构 二.Hibernate-api详解 2.1.Configuration配置对象 Configuration是用来加载配置文件的 我们Hibernate中主要有两个配置文 ...
- Hibernate(二)
1.1Hibernate的持久化类状态 1.1.1Hibernate的持久化类状态 持久化类:就是一个实体类和数据库表建立了映射关系. Hibernate为了方便的管理持久化类,将持久化类分成了三种状 ...
- Hibernate学习(二)关系映射----基于外键的单向一对一
事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似.只需要将原来的many-to-one元素增加unique="true"属性, ...
- Java框架之Hibernate(二)
本文主要介绍: 1 Criteria 接口 2 用 myeclipse 反向生成 3 hibernate 主键生成策略 4 多对一 5 一对多 6 使用List 集合的一对多 7 多对多 一.Cri ...
- SSH框架之hibernate《二》
Hibernate第二天 一.hibernate的持久化类和对象标识符 1.1持久化类的编写规范 1.1.1什么是持久化类: ...
- JAVA框架:hibernate(二)
一.事务操作. 代码: @Test public void tr_Up(){ Session session=hibernateUtils.getSession(); Transaction tran ...
随机推荐
- PHP面向对象07_PDO
oop007复习 2014-9-4 9:42:28 摘要: 1.pdo的作用 2.pdo的安装 3.pdo连接属性设置 4.pdo对象和PDOStatement对象 5.pdo预处理 6.pdo事务机 ...
- 完美C++(第5版)(双色)
完美C++(第5版)(双色) 薛正华 沈庚 韦远科 译 ISBN 978-7-121-23198-8 2014年6月出版 定价:148.00元 788页 16开 内容提要 <完美C++(第5版) ...
- mysql修改密码
mysql修改password >mysqladmin -u root -p password newpassword 就这么简单
- [WPF]有滑动效果的进度条
先给各位看看效果,可能不太完美,不过效果还是可行的. 我觉得,可能直接放个GIF图片上去会更好. 我这个不是用图片,而是用DrawingBrush画出来的.接着重做ProgressBar控件的模板,把 ...
- MySQL的用户和权限介绍
一.关于MySQL权限的几点常识: 1.MySQL的权限系统主要用来验证用户的操作权限. 2.在MySQL内部,权限信息存放在MySQL数据库的granttable里.当mysql启动后,grantt ...
- Parametric Curves and Surfaces
Parametric Curves and Surfaces eryar@163.com Abstract. This paper is concerned with parametric curve ...
- poj 1950 Dessert(dfs枚举,模拟运算过程)
/* 这个代码运行的时间长主要是因为每次枚举之后都要重新计算一下和的值! 如果要快的话,应该在dfs,也就是枚举的过程中计算出前边的数值(这种方法见第二个代码),直到最后,这样不必每一次枚举都要从头再 ...
- 拓扑排序(二)之 C++详解
本章是通过C++实现拓扑排序. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑排序的代码说明 4. 拓扑排序的完整源码和测试程序 转载请注明出处:http://www.cnblogs. ...
- tomcat对请求路径的匹配过程(原创)
1.匹配服务 如果有两个应用,一个应用只能通过80端口访问,另一个应用只能通过8080端口访问,这种情况下,可以分开两个服务,然后分别创建80端口和8080端口的连接器. 2.匹配主机 一个服务下配置 ...
- 轻松自动化---selenium-webdriver(python) (十)
本节重点 处理下拉框 switch_to_alert() accept() 下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框,再 ...