hibernate的CRUD操作
一对多关系映射的crud操作:
1.单项的保存操作
/**
* 保存操作
* 正常的保存:创建一个联系人,需要关联客户
*/
@Test
public void test1(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.查询一个客户
Customer c1=s.get(Customer.class,1L);
//2.创建一个联系人
LinkMan l=new LinkMan();
l.setLkmName("一对多的联系人");
//3.建立客户联系人的关联关系(让联系人知道他属于哪个客户)
l.setCustomer(c1);
//4.保存联系人
s.save(l);
tx.commit();
}
2.双向的保存操作:
/**
* 创建一个客户和一个联系人,创建客户和联系人的双向关系
* 使用符合原则的保存
* 先保存主表的实体,再保存从表的实体
* 此时保存会有问题:
* 保存应该只是两条insert语句,而执行结果是多了一条Update
*/
@Test
public void test2(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.创建一个客户
Customer c1=new Customer();//瞬时态对象
c1.setCusname("一对多别的客户2");
//2.创建一个联系人
LinkMan l=new LinkMan();//瞬时态对象
l.setLkmName("一对多的联系人2");
//3.建立客户联系人的关联关系(双向)
l.setCustomer(c1);
c1.getLinkmans().add(l);
//4.保存,要符合原则
s.save(c1);//持久态,会有一级缓存和快照,有OID,和session有关系
s.save(l);//持久态,会有一级缓存和快照,有OID,和session有关系
tx.commit();
}
注意:在此函数执行的时候,先执行了两条insert语句,然后执行了一条update语句,其原因如下:

是因为Hibernate的快照技术,使得先后执行的语句在快照区的内容不一样,只能在最后commit的时候重新刷新数据库,从而有了一条update语句。
解决办法:让客户在执行操作的时候,放弃维护关联关系的权利。
* 配置的方式,在customer的映射配置文件的set标签使用inverse属性
* inverse:是否放弃维护关联关系的权利,true:是,false:否(默认值)
<set name="linkmans" table="cust_linkman" inverse="true">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan"></one-to-many></set>
3.一对多的级联保存
加入有很多订单,一个一个保存太麻烦,直接用级联保存,就可以一次保存完,而不再用传统的方式一个一个去保存,方法如下:
/**
* 保存操作,级联操作
* 使用级联保存,配置的方式,
* 使用customer的set标签
* 在上面加入cascade属性
* cascade:配置级联操作
* 级联保存更新的保存:save-update
* 也可以配置在<one-to-many/>这个标签上
*/
@Test
public void test3(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.创建一个客户
Customer c1=new Customer();//瞬时态对象
c1.setCusname("一对多别的客户4");
//2.创建一个联系人
LinkMan l=new LinkMan();//瞬时态对象
l.setLkmName("一对多的联系人4");
//3.建立客户联系人的关联关系(双向)
l.setCustomer(c1);
c1.getLinkmans().add(l);
//4.保存,要符合原则
s.save(c1);//只保存了c1
tx.commit();
}
@Test
public void test4(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.创建一个客户
Customer c1=new Customer();//瞬时态对象
c1.setCusname("一对多别的客户5");
//2.创建一个联系人
LinkMan l=new LinkMan();//瞬时态对象
l.setLkmName("一对多的联系人5");
//3.建立客户联系人的关联关系(双向)
l.setCustomer(c1);
c1.getLinkmans().add(l);
//4.保存,要符合原则
s.save(l);//只保存了l
tx.commit();
}
注意:在此时的实体类的映射配置中需要加入:
1,<set/>标签级联保存
<set name="linkmans" table="cust_linkman" inverse="true" cascade="save-update">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan"></one-to-many>
</set>
2. <many-to-one name="customer" class="Customer" column="lkm_cust_id" cascade="save-update"></many-to-one>
用这两种方式都可以实现只需要在代码中保存一个实体,即可保存所有级联实体,只不过配置时候注意要对应配置。
4. 更新操作,双向的操作
/**
* 更新操作:创建一个联系人,查询一个已有客户
* 建立新联系人和已有客户的双向关联关系
* 更新联系人
*/
@Test
public void test5(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.查询一个客户
Customer c1=s.get(Customer.class,3L);
//2.创建一个联系人
LinkMan l=new LinkMan();
l.setLkmName("一对多的联系人1");
//3.建立客户联系人的关联关系(双向)
l.setCustomer(c1);
c1.getLinkmans().add(l);
//4.更新客户
s.update(c1);
tx.commit();
}
需要注意的是在此时如果set的配置标签里面如果配置了inverse="true"的话,会忽略更新的,这儿需要注意一下,但是cascade必须是save-update,因为在update之前是没有保存那个联系人l,如果不设置这个的话直接报错的。
5.删除操作
1.删除的时候如果是从表,则直接删除,若是主表,同时从表的外键可以为null的时候,删除主表的同时直接将其从表中的外键直接置为null
/**
* 删除操作
* 删除从表就是单表
* 删除主表数据
* 先看从表数据引用
* 有引用:hibernate会吧从表中的外键置位null,然后再删除
* 无引用:直接删
*/
@Test
public void test6(){
//此时的外键允许为null
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
//1.查询一个客户
Customer c1=s.get(Customer.class,68L);
//删除ID为68的客户
s.delete(c1);
tx.commit();
}
2.若果从表中要删除某个主表的数据,并且要删除与它级联的从表中的数据,则需要配置级联删除,如下,但是不建议使用该级联删除,是一个很危险的操作
<set name="linkmans" table="cust_linkman" inverse="false" cascade="save-update,delete">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan"></one-to-many>
</set>
若从表的外键约束为not null的话,想要在主表中删除某数据,并且此数据在从表中有对应的外键引用,则需要配置主表的额inverse=true,只有配置了这个才可以级联删除,因为只有这样的话,主表才不会维护他的约束,才可以允许级联删除不。
6.对象导航查询
一对多的查询操作:OID查询,QBC查询,SQL查询
hibernate中的最后一种查询方式,对象导航查询
当两个实体类之间有关联关系时候(可以是任一一种)
通过调用getXXX方法即可达到实现查询功能(是有hibernate提供的方法)
eg:customer.getLinkMans()就可以得到当前客户的所有联系人
通过linkman.getCustomer()就可以得到当前联系人的所属客户
- 注意:一对多时候,根据一的一方查询多的一方是,需要使用延迟加载lazy=true(默认配置即可)
<set name="linkmans" table="cust_linkman" lazy="true">
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan"></one-to-many>
</set>
/**
*查询ID为1的客户下的所属联系人
*/
@Test
public void test1(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
Customer c=s.get(Customer.class, 1L);//查询ID为1的客户
/*System.out.println(c);
System.out.println(c.getLinkmans());*/
Set<LinkMan> linkmans=c.getLinkmans();
System.out.println(c);
System.out.println(linkmans);//注意此时是连查询带打印,而不是先查询,在打印
tx.commit();
}
2.多对一时候,根据多的一方查询一的一方时候,不需要使用延迟加载,而是立即加载,需要配置一下,需要找到联系人的<many-to-one>标签上,使用lazy属性,取值有false(立即加载),proxy(看是load方法是延迟加载,还是立即加载)
<class name="LinkMan" table="cust_linkman" lazy="false"><many-to-one name="customer" class="Customer" column="lkm_cust_id" lazy="proxy"></many-to-one>
</class>
/**
*查询ID为5的联系人属于哪个客户
*.多对一时候,根据多的一方查询一的一方时候,不需要使用延迟加载,而是立即加载,
*需要配置一下,需要找到联系人的<many-to-one>标签上,
*使用lazy属性,
* 取值有:
* false(立即加载),
* proxy(看是load方法是延迟加载,还是立即加载)
*/ @Test
public void test2(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
LinkMan l=s.get(LinkMan.class,5L);
System.out.println(l);
System.out.println(l.getCustomer());//注意此时是连查询带打印,而不是先查询,在打印
tx.commit();
}
- 关于load方法的是否延迟加载
在多的一方配置文件里面的class属性设置lazy=false(这个地方的lazy只负责load方法的加载方式),即立即加载的时候,如果此时设置<many-to-one>里面的属性为lazy=proxy时候,则是根据load方法是否延迟加载来定的,但是<many-to-one>中lazy的级别大于class中配置lazy的级别
/**
* 关于load方法改为立即加载的方式
* 找到查询实体类的映射配置文件,它的class属性上边也有一个lazy属性,是否延迟加载,
* true为延迟加载,false为立即加载
*/
@Test
public void test3(){
Session s=HibernateUtils.getCurrentSession();
Transaction tx=s.beginTransaction();
Customer c=s.load(Customer.class, 1L);//查询ID为1的客户
System.out.println(c);
tx.commit();
}
Class标签的lazy;只能管load的方法是否是延迟加载
Set标签的lazy:管查询关联的集合对象是否延迟加载
Many-to-one标签的lazy:只管查询关联的主表实体是否是立即加载
hibernate的CRUD操作的更多相关文章
- hibernate之CRUD操作
CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...
- java框架篇---hibernate之CRUD操作
CRUD是指在做计算处理时的增加(Create).读取(Retrieve)(重新得到数据).更新(Update)和删除(Delete)几个单词的首字母简写. 下面列举实例来讲解这几个操作: 实体类: ...
- 【Java EE 学习 44】【Hibernate学习第一天】【Hibernate对单表的CRUD操作】
一.Hibernate简介 1.hibernate是对jdbc的二次开发 2.jdbc没有缓存机制,但是hibernate有. 3.hibernate的有点和缺点 (1)优点:有缓存,而且是二级缓存: ...
- hibernate入门-基本配置及简单的crud操作
框架来说主要是需要写大量的配置文件,hibernate相比mybatis来说更强大,移植性更好: 1.类和数据库的映射配置:配置文件命名一般--类名.hbm.xml (user.hbm.xml),与实 ...
- 【SSH三大框架】Hibernate基础第五篇:利用Hibernate完毕简单的CRUD操作
这里利用Hibernate操作数据库完毕简单的CRUD操作. 首先,我们须要先写一个javabean: package cn.itcast.domain; import java.util.Date; ...
- hibernate Session的CRUD操作
使用Session里面的方法进行CRUD操作 (1) 增加 save 方法 (2) 查找 get 方法(根据id查) (3) 修改 update 方法 (4) 删除 delete 方法 1.增加 /* ...
- Hibernate 系列 03 - 使用Hibernate完成持久化操作
引导目录: Hibernate 系列教程 目录 康姆昂,北鼻,来此狗.动次打次,Hibernate继续走起. 目录: 使用Hibernate实现按主键查询 使用Hibernate实现数据库的增.删.改 ...
- Hibernate基本CRUD
1 hibernate 框架介绍 冬眠:开发的代码基本不变. 1.1回顾jdbc Java提供的标准的数据访问的API 作用:完成应用程序java程序中的数据和db中的数据进行交换. 工作过程: A ...
- Java实战之02Hibernate-01简介、常用接口、CRUD操作
一.Hibernate简介 1.Hibernate在开发中所处的位置 2.ORM映射 Object :面向对象领域的 Relational:关系数据库领域的 Mapping:映射 Object: Re ...
随机推荐
- 002Angular2工程目录解构
|--my-app 工程名 |--e2e 端到端测试 |--node_modules package.json列出的第三方模块放在此处 |--src |--app |--app.component.c ...
- 使用CKRule实现PVC配方计算
1,PVC计算的基本原理 配方员设计好配方,再进行抽象提炼,会出现相对于软件而言可以理解的逻辑,如属性的概念,对厂企生成的PVC产品而言,一般都有产品大类名称,花纹,颜色,长度,宽度,厚度等概念,这对 ...
- Jmeter性能测试 入门--转载
转载: Jmeter性能测试 入门 Jmeter是一款优秀的开源测试工具, 是每个资深测试工程师,必须掌握的测试工具,熟练使用Jmeter能大大提高工作效率. 熟练使用Jmeter后, 能用Jmete ...
- java面试题之 -----面向切面编程
这种在运行时,动态地将代码切入到类的指定方法.指定位置上的编程思想就是面向切面的编程. 面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是 ...
- Dynamics CRM 之汇总字段
用插件汇总数据,速度很慢,导数据的时候更慢!那就用汇总字段- - 新建个汇总字段,字段类型选择汇总.点击编辑进入逻辑编辑 相关实体:对当前实体或者相关联的实体的字段值进行判断筛选. 筛选器:对相关实体 ...
- Flask入门模板过滤器与测试器(五)
1 模板引擎之过滤器 概念 : 过滤器本质上是个转换函数,第一个参数是待过滤的变量.如果它有第二个参数,模板中就必须传进去. 过滤器使用管道符| 放在{{ }} Jinja2模板引擎提供了丰富的内置过 ...
- netstat 和 lsof 查看网络状态
netstat和lsof都是linux下的工具,可以用于查看系统的网络状态. netstat netstat可以打印 网络连接,路由表,接口统计数据,还有多播和masquerade连接相关的东西(不熟 ...
- linux服务基础之CentOS6编译安装mariadb
1. 下载mariadb https://downloads.mariadb.org/mariadb/+releases/ 2. 解压到指定目录 # tar xf mariadb--linux-x86 ...
- FMDB初步使用小结
频繁的网络请求会给用户不好的体验,在最近开发的一个项目中有一个获取个人详细信息的界面,由于是子页面,进入页面后需要重新加载数据并刷新页面,而,每一次请求服务器再返回数据不仅用户体验不好,也花费手机流量 ...
- WebService 之CXF(rs)之HelloWorld
1.建立mavenjava项目 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http ...