Hibernate性能:fetching策略
来源:互联网 发布:不是方阵有逆矩阵吗 编辑:程序博客网 时间:2024/05/16 09:29
Hibernate有一些fetching策略,来优化Hibernate所生成的select语句,以尽可能地提高效率。在映射关系中声明fetching策略,定义Hibernate怎样获取其相关的集合和实体。
有四种fetching策略:
在XML映射文件中声明fetch策略:
复制代码以标注的形式声明fetch策略:
复制代码下面我们来探讨fetch策略如何影响到Hibernate生成的SQL语句。
1、fetch=”select” 或 @Fetch(FetchMode.SELECT)
这是默认的fetch策略。这可以延迟加载所有相关的集合。请看示例代码:
复制代码
输出如下:
复制代码Hibernate生成两个select语句:
“join”fetch策略将禁用延迟加载所有相关的集合。请看示例代码:
复制代码输出如下:
复制代码Hibernate只生成一个select语句,当Stock被初始化时,它获取所有其相关的集合。
3、batch-size=”10” 或 @BatchSize(size=10) 这个“batch-size”fetching策略总是被许多Hibernate开发者感到难以理解。请看示例代码:复制代码 输出如下:
复制代码
4、另一个示例
接下来看一看另一个例子。假设想要打印输出所有的股票记录以及其相关的股票日记录(集合),one by one。
复制代码1、没有batch-size fetching策略时,输出:
复制代码如果在数据库中有20条股票记录,Hibernate默认的fetching策略将生成20+1个select语句,这将对数据库造成一定的冲击。
2、启用batch-size=”10” fetching策略时,输出:
复制代码现在,Hibernate将预提取集合,使用select in语句。如果在数据库中有20条股票记录,Hibernate将生成3个select语句。
5、 fetch=”subselect” 或 @Fetch(FetchMode.SUBSELECT)
Fetching策略能够将其所有相关集合放在一个子select语句中。请看下面的查询:
复制代码启用“subselect”,它将生成两个select语句:
6、结论
Fetching策略非常具有弹性,是一个优化Hibernate查询的非常重要的技巧。不过如果用在错误的地方,那将会是一个灾难。
有四种fetching策略:
- fetch-“join”:禁用延迟加载,总是立即加载所有的集合和实体。
- fetch-“select”(默认):延迟加载所有的集合和实体。
- batch-size=”N”:获取上限为“N”个的集合或实体,没有记录。
- fetch-“subselect”:将其集合组织到一个子查询语句中。
在XML映射文件中声明fetch策略:
- <hibernate-mapping>
- <class name="com.xuejava.common.Stock" table="stock">
- <set name="stockDailyRecords" cascade="all" inverse="true"
- table="stock_daily_record" batch-size="10" fetch="select">
- <key>
- <column name="STOCK_ID" not-null="true" />
- </key>
- <one-to-many class="com.xuejava.common.StockDailyRecord" />
- </set>
- </class>
- </hibernate-mapping>
- @Entity
- @Table(name = "stock", catalog = "xuejava")
- public class Stock implements Serializable{
- ...
- @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
- @Cascade(CascadeType.ALL)
- @Fetch(FetchMode.SELECT)
- @BatchSize(size = 10)
- public Set<StockDailyRecord> getStockDailyRecords() {
- return this.stockDailyRecords;
- }
- ...
- }
1、fetch=”select” 或 @Fetch(FetchMode.SELECT)
这是默认的fetch策略。这可以延迟加载所有相关的集合。请看示例代码:
- //call select from stock
- Stock stock = (Stock)session.get(Stock.class, 114);
- Set sets = stock.getStockDailyRecords();
- //call select from stock_daily_record
- for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
- StockDailyRecord sdr = (StockDailyRecord) iter.next();
- System.out.println(sdr.getDailyRecordId());
- System.out.println(sdr.getDate());
- }
输出如下:
- Hibernate:
- select ...from xuejava.stock
- where stock0_.STOCK_ID=?
- Hibernate:
- select ...from xuejava.stock_daily_record
- where stockdaily0_.STOCK_ID=?
- 获取Stock记录的select语句-session.get(Stock.class,114)
- 获取其相关集合的select语句-sets.iterator()
“join”fetch策略将禁用延迟加载所有相关的集合。请看示例代码:
- //call select from stock and stock_daily_record
- Stock stock = (Stock)session.get(Stock.class, 114);
- Set sets = stock.getStockDailyRecords();
- //no extra select
- for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
- StockDailyRecord sdr = (StockDailyRecord) iter.next();
- System.out.println(sdr.getDailyRecordId());
- System.out.println(sdr.getDate());
- }
- Hibernate:
- select ...
- from
- xuejava.stock stock0_
- left outer join
- xuejava.stock_daily_record stockdaily1_
- on stock0_.STOCK_ID=stockdaily1_.STOCK_ID
- where
- stock0_.STOCK_ID=?
3、batch-size=”10” 或 @BatchSize(size=10) 这个“batch-size”fetching策略总是被许多Hibernate开发者感到难以理解。请看示例代码:
- Stock stock = (Stock)session.get(Stock.class, 114);
- Set sets = stock.getStockDailyRecords();
- for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
- StockDailyRecord sdr = (StockDailyRecord) iter.next();
- System.out.println(sdr.getDailyRecordId());
- System.out.println(sdr.getDate());
- }
- Hibernate:
- select ...from xuejava.stock
- where stock0_.STOCK_ID=?
- Hibernate:
- select ...from xuejava.stock_daily_record
- where stockdaily0_.STOCK_ID=?
batch-size什么也没做。请看下面的解释:
batch-size fetching策略并不是定义集合中有多少记录被预加载。相反,它其实是定义有多少集合应该被加载。4、另一个示例
接下来看一看另一个例子。假设想要打印输出所有的股票记录以及其相关的股票日记录(集合),one by one。
- List<Stock> list = session.createQuery("from Stock").list();
- for(Stock stock : list){
- Set sets = stock.getStockDailyRecords();
- for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
- StockDailyRecord sdr = (StockDailyRecord) iter.next();
- System.out.println(sdr.getDailyRecordId());
- System.out.println(sdr.getDate());
- }
- }
- Hibernate:
- select ...
- from xuejava.stock stock0_
- Hibernate:
- select ...
- from xuejava.stock_daily_record stockdaily0_
- where stockdaily0_.STOCK_ID=?
- Hibernate:
- select ...
- from xuejava.stock_daily_record stockdaily0_
- where stockdaily0_.STOCK_ID=?
- 继续重复select语句....这取决于数据表中有多少条stock记录。
- 获取所有Stock记录的select语句
- 获取其相关集合的select语句
- 获取其相关集合的select语句
- 获取其相关集合的select语句
- ……
2、启用batch-size=”10” fetching策略时,输出:
- Hibernate:
- select ...
- from xuejava.stock stock0_
- Hibernate:
- select ...
- from xuejava.stock_daily_record stockdaily0_
- where
- stockdaily0_.STOCK_ID in (
- ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
- )
- 获取所有Stock记录的select语句
- 预提取其相关集合的select in语句(一次10个集合)
- 预提取其相关集合的select in语句(接下来一次10个集合)
5、 fetch=”subselect” 或 @Fetch(FetchMode.SUBSELECT)
Fetching策略能够将其所有相关集合放在一个子select语句中。请看下面的查询:
- List<Stock> list = session.createQuery("from Stock").list();
- for(Stock stock : list){
- Set sets = stock.getStockDailyRecords();
- for ( Iterator iter = sets.iterator();iter.hasNext(); ) {
- StockDailyRecord sdr = (StockDailyRecord) iter.next();
- System.out.println(sdr.getDailyRecordId());
- System.out.println(sdr.getDate());
- }
- }
- 获取所有Stock记录的select语句;
- 在一个子查询语句中获取其相关集合的语句。
6、结论
Fetching策略非常具有弹性,是一个优化Hibernate查询的非常重要的技巧。不过如果用在错误的地方,那将会是一个灾难。
- Hibernate性能:fetching策略
- hibernate 抓取策略(Fetching strategies)
- Hibernate中的数据的获取策略(fetching)
- Hibernate 优化技术之抓取策略(Fetching strategies)
- Hibernate性能优化策略
- Hibernate性能优化策略
- Hibernate性能优化策略
- Hibernate性能优化策略
- Hibernate: Understanding Lazy Fetching
- Hibernate抓取--fetching
- Hibernate学习44 -- 抓取策略4 -- 批量抓取(Batch fetching)
- Hibernate之性能优化策略
- 抓取策略(Fetching strategies)
- 抓取策略(Fetching strategies)
- Hibernate – fetching strategies examples
- Hibernate – fetching strategies examples
- Hibernate 性能优化策略和缓存详解
- Hibernate性能优化策略(一)
- java多线程总结三:sleep()、join()、interrupt()示例
- java多线程总结二:后台线程(守护线程)
- android点餐系统
- java多线程总结一:线程的两种创建方式及优劣比较
- 第7章 图——最短路径之某个源点到其余各顶点的最短路径
- Hibernate性能:fetching策略
- 如何让推销BI产品
- JS常用正则表达式
- [C# 基础知识系列]专题七: 泛型深入理解(一)
- 时钟类---swing画图、Timer、JFrame用法示例
- 黑马程序员——Struts个人学习笔记(一)
- n个色子的点数
- Multiply Strings
- HQL与Criteria对照