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 ...
随机推荐
- MyBatis学习总结(八)——Mybatis3.x与Spring4.x整合
一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-myba ...
- [java] 找出字符串中出现最多的字符和出现的次数
逛园子看到一童鞋做的华为上机题目,写来好长的代码,懒得看,感觉不可能这么难,于是动手敲了下. import java.util.Scanner; public class StringTest { / ...
- CCNA网络工程师学习进程(3)常规网络设计模型与基本的网络协议
本节介绍分层的网络设计模型与基本的网络协议,包括ARP协议,ICMP协议和IP协议. (1)三层网络架构: 一个好的园区网设计应该是一个分层的设计.一般分为接入层.汇聚层(分布层).核 ...
- Java多线程synchronized同步
非线程安全问题 “非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程问题”.也即是说,方法中的变量永远是线程安全的. 如果多个线程共同访问1个对象中的实例变量,则可能线程 ...
- JAVA设计模式《二》
上一篇为大家介绍了一下设计模式中的责任链模式,本篇为大家介绍一下关于设计模式中的单例模式与模板方法模式.单例模式的作用在于,保证应用中某个实例有且只有一个,单例模式又被分为:饱汉模式与饿汉模式,两者的 ...
- 记录asp.net在IE10下事件丢失排错经过
最近项目中运用了地区三级联动,用的是最普通的DropDownList回发来实现的,如下图 一直用着都挺好的,可最近客户最近新换了台服务器,我把网站迁移过去就有了问题,三级联动失效了. 首先申明一点,这 ...
- tomcat架构之-----基本概念
一直都没有搞明白tomcat中server.service.Engine.Host.Context概念的意义,最近认真看了<Tomcat 6 Developer Guide>,有了进一步的 ...
- nginx反向代理docker registry报”blob upload unknown"解决办法
问题症状:keepalived+nginx反向代理后端docker registry群集时,使用docker客户机向registry push镜像时出现 "blob upload unkno ...
- Spark入门实战系列--2.Spark编译与部署(上)--基础环境搭建
[注] 1.该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取: 2.Spark编译与部署将以CentOS 64位操作系统为基础,主要是考虑到实际应用 ...
- Fort.js – 时尚、现代的表单填写进度提示效果
Fort.js 是一款用于时尚.现代的表单填写进度提示效果的 JavaScript 库,你需要做的就是添加表单,剩下的任务就交给 Fort.js 算法了,使用非常简单.提供了Default.Gradi ...