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 ...
随机推荐
- VS2012 MVC4 学习笔记-概览
1. 访问请求过程 访问收到后路由(Router)根据路径由分配给对应的控制器(Control),然后由控制器返回页面视图(View) 路由设置一个默认的控制器,类似 主页的样子吧 <未完待续& ...
- iOS-旧项目中手动内存管理(MRC)转ARC
在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事.我参 加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题, ...
- seajs模块化开发
seajs是一个起辅助作用的库,所以它可以更方便开发,而它可以解决以下问题: 1.命名问题,就是冲突 2.性能问题,就是只要一个功能,但却使用一个大插件中的一个小功能,所以要手动拆分出这个功能 3.j ...
- select元素javascript常用操作 转
/*------------------------------------------------------ *作者:xieyu @ 2007-08-14 *语言:JavaScript *说明:s ...
- Java多线程系列--“基础篇”11之 生产消费者问题
概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p ...
- 这10道javascript笔试题你都会么
1.考察this var length = 10; function fn() { console.log(this.length); } var obj = { length: 5, metho ...
- JS实现单击按钮后弹出新的窗口页面
点击按钮后,弹出指定大小的页面窗口. 效果图: 源码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu ...
- iOS_UIImage_图片剪切
- (UIImage *)imagecutWithRect:(CGRect)rect { CGImageRef subImageRef = CGImageCreateWithImageInRect(s ...
- 【Android】[转] Android中Bitmap,byte[],Drawable相互转化
一.相关概念 1.Drawable就是一个可画的对象,其可能是一张位图(BitmapDrawable),也可能是一个图形(ShapeDrawable),还有可能是一个图层(LayerDrawable) ...
- form上传文件以及跨域异步上传
要设置了enctype属性才能上传,需要使用上传的jar包,这里使用的是cos-26Dec2008.jar, 而且后台获取值的时候,getfile要放在第一位 一次设置好上传格式后没有上传文件,也就没 ...