hibernate抓取问题
当使用xml配置类之间的关系时 ,例如 学生 班级,多对一关系
/**
* 默认情况会发出2条SQL语句,一条取student,一条取Classroom,其实这只需要一条sql
* 解决办法 通过设置XML中的<many-to-one name="classroom" column="cid" fetch="join"/> //默认fetch=select
* 可以完成对抓取的设置
*/
session = HibernateUtil.openSession();
Student stu = (Student)session.load(Student.class, 1); //只查一个学生
System.out.println(stu.getName()+","+stu.getClassroom().getName())
-----------------------------------------------------------------------------------------------------
缺点。有时候不需要班级信息也会查出来,占用内存 ,延迟加载就不起作用了
session = HibernateUtil.openSession();
Student stu = (Student)session.load(Student.class, 1);
//延迟加载就失效,自动查班级信息
System.out.println(stu.getName());
-----------------------------------------------------------------------------------------------------------------
但是当查询所有学生时 使用xml配置。并且使用fetch=join 如下代码 又会发查询学生sql和班级的sql
List<Student> stus = session.createQuery("from Student").list(); //查询全部学生
for(Student stu:stus) {
System.out.println(stu.getName()+","+stu.getClassroom().getName());
}
在XML中配置了fetch=join仅仅只是对load的对象有用,对HQL中查询的对象无用
解决办法1 。设置查询班级的数量 batch-size,但是查询的数据随着session关闭就没了,
<class name="Classroom" table="t_classroom" batch-size=''20''>
解决办法 2 使用fetch关键字 在hql中 ,如果使用了join fetch就无法使用count(*)
List<Student> stus = session.createQuery("select stu from " +
"Student stu join fetch stu.classroom").list();
for(Student stu:stus) {
System.out.println(stu.getName()+","+stu.getClassroom());
}
-------------------------------------------------------------------------------------------------------------------
当使用annotation配置类之间关系时。
----------------------------------------------------------------------------------------------------------
/**
* 对于Annotation的配置而言,默认就是基于join的抓取的,所以只会发出一条SQL
*/
session = HibernateUtil.openSession();
Student stu = (Student)session.load(Student.class, 1); //只查一个学生
System.out.println(stu.getName()+","+stu.getClassroom().getName());
-------------------------------------------------------------------------------------------------------
但是annotation默认没有延迟加载。如果查询全部学生。会自动查处关联的班级信息。发大量sql语句 这也是个问题
List<Student> stus = session.createQuery("from Student").list(); //查所有学生
for(Student stu:stus) {
System.out.println(stu.getName());
}
解决 使用annotation时设置ManToOne(fetch=FetchType.Lazy) 延迟加载 相当于xml配置中 默认也就是fetch='select'
影响 1 但是一下代码又会发2条sql
session = HibernateUtil.openSession();
Student stu = (Student)session.load(Student.class, 1);
System.out.println(stu.getName()+","+stu.getClassroom().getName())
影响 2
当又想查询所有学生和所在班级信息 如下代码,又会发多条SQL。查学生SQL。和班级SQL
List<Student> stus = session.createQuery("from Student").list();
for(Student stu:stus) {
System.out.println(stu.getName()+","+stu.getClassroom().getName());
}
------------------------------------------------------------------------------------------------------
@ManyToOne(fetch=FetchType.LAZY)//LAZY就是XML中的select,EAGER就表示XML中的join
annotation默认是EAGER
@BatchSize(size=20)
public class Classroom 相当于xml中的batch-size 设置
-------------------------------------------------
总结,当你使用xml时。默认有延迟。当查询一个对象时。同时也查他的关联对象,会发多条sql。先查对象,再发sql查关联对象。使用fetch=join配置,也是只对load对象有用(就是load方法里传的class),hql中的对象(hibernate自己发送的hql语句中查询的对象)没用还是发好几条sql.解决要不就设置batch-size要不就自己用 join fetch 自己写hql
使用annotation时,默认是没延迟。查询一个对象。只发一条。但是查询多个对象时 ,又和xml中使用fetch=join 的情况一下样 ,但是你设置fetcg=FetchType.LAZY ,查询单一对象时,又会发两条,所以 要不就设置batch-size要不就自己用 join fetch 自己写hql
所以有时候。用别人的东西。不了解别人的东西就会问题很多。但你花很多时间去研究他。不如花时间研究数据库,用原生 sql ,
懂数据库的人,可能不用hibernate, 想用好还得精通hibernate。
不懂数据库的人。估计也不会花心思研究hibernate。研究了hibernate。你还得懂数据库
hibernate抓取问题的更多相关文章
- Hibernate 抓取策略fetch-1 (select join subselect)
原文 :http://4045060.blog.51cto.com/4035060/1088025 部分参考:http://www.cnblogs.com/rongxh7/archive/2010/0 ...
- 029 hibernate抓取策略
实例A引用实例B,B如果是代理的话(比如多对一关联中):如果遍历A的查询结果集(假设有10条记录),在遍历A的时候,访问B变量,将会导致n次查询语句的发出!这个时候,如果在B一端的class上配置ba ...
- hibernate抓取策略
抓取策略(fetching strategy) 是指:当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候, Hibernate如何获取关联对象的策略.抓取策略可以在O/R映射的 ...
- Hibernate 抓取策略fetch-2 (批量抓取batch-size以及hibernate.jdbc.fetch_size、hibernate.jdbc.batch_size)
类关系: User N~1 Group 测试代码: System.out.println("1"); List stuList = session.createQuery(&quo ...
- Hibernate 抓取策略
抓取策略: 为了改变SQL语句执行的方式 当应用程序需要在Hibernate实体对象的关联关系间进行导航的时候,Hibernate如何获取关联对象的策略 抓取策略可以在O/R映射的元数据中声明,也可以 ...
- Hibernate批量抓取
------------------siwuxie095 Hibernate 批量抓取 以客户和联系人为例(一对多) 1.批量抓取 同时查询多个对象的关联对象,是 Hibernate 抓取策略的一种 ...
- Hibernate之加载策略(延迟加载与即时加载)和抓取策略(fetch)
假设现在有Book和Category两张表,表的关系为双向的一对多,表结构如下: 假设现在我想查询id为2的那本书的书名,使用session.get(...)方法: Session session=H ...
- 【Java EE 学习 48】【Hibernate学习第五天】【抓取策略】【二级缓存】【HQL】
一.抓取策略. 1.hibernate中提供了三种抓取策略. (1)连接抓取(Join Fetch):这种抓取方式是默认的抓取方式.使用这种抓取方式hibernate会在select中内连接的方式获取 ...
- Hibernate的抓取策略
立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...
随机推荐
- Gym - 100971J ——DFS
Statements Vitaly works at the warehouse. The warehouse can be represented as a grid of n × mcells, ...
- Linux系统优化及状态监控
1.查看系统进程命令 top 进入后可按s 加时间,指定多长时间刷新一次 2.查看cpu信息 cat /proc/cpuinfo 3.查看内存信息 cat /proc/meminfo 4.清理内存:主 ...
- 下了个蓝屏代码查看工具,就中病毒了。。。什么鬼病毒,竟然还是用的VBS
扫描所有盘下面的html文件,加入VBS脚本...真是奇葩,多少年前的病毒了... http://files.cnblogs.com/files/guangshan/lpdmcxq.rar 这个是病毒 ...
- Replication--将LSN转换成16进制
在复制中经常会使用到16进制的LSN,但在日志fn_dblog中的LSN是数字形式,于是从网上找到以下转换函数CREATE FUNCTION dbo.fn_convertnumericlsntobin ...
- Ocelot
Ocelot——初识基于.Net Core的API网关 Ocelot API网关的实现剖析 微服务网关Ocelot API网关Ocelot 使用Polly 处理部分失败问题 谈谈微服务中的 API 网 ...
- 工作中的Buff加成-结构化思考力:自创独门武功 3-3-3原则
3-3-3原则 3秒钟 *思考三秒钟 沟通前根据交谈内容思考3秒钟,思考下具体需要表达什么,思考的主要点为What.Why.How. *冷静三秒钟 在沟通过程中,若遇到气氛不和谐,比如生气.愤恨等时, ...
- hdu5693 D game&&hdu 5712 D++ game
题目链接:5693 题目链接:5712 对于这个D game.注意消除之后两遍的序列是可以拼合到一起的!我们可以想到有区间DP的做法.我们设\(f[i][j]\)表示区间i,j可以被消除. 显然如果这 ...
- 【Android 多媒体应用】使用MediaCodec解码使用AudioTrack播放音频数据
1.MainActivity.java import android.app.Activity; import android.os.Bundle; import android.os.Environ ...
- linux上 查看mysql的binglog日志
查看mysqlbinglog日志 mysqlbinlog --no-defaults --database=数据库名称 --start-datetime= > /mysql.txt 备注: -- ...
- CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)
题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\ ...