博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【hibernate框架】性能优化之list_iterate的不同之处
阅读量:6275 次
发布时间:2019-06-22

本文共 8693 字,大约阅读时间需要 28 分钟。

list与iterate的不同之处:
还是用上一次的例子,话题topic和版块category
Topic.java:
package com.bjsxt.hibernate;import java.util.ArrayList;import java.util.Date;import java.util.List;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.ManyToOne;import javax.persistence.NamedQueries;import javax.persistence.NamedQuery;import javax.persistence.OneToMany;import javax.persistence.Temporal;import javax.persistence.TemporalType;import org.hibernate.annotations.BatchSize;@Entitypublic class Topic {	private int id;	private String title;	private Category category;	private Date createDate;	private List
msgs = new ArrayList
(); @OneToMany(mappedBy="topic") public List
getMsgs() { return msgs; } public void setMsgs(List
msgs) { this.msgs = msgs; } @Temporal(TemporalType.TIME) public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } @ManyToOne(fetch=FetchType.LAZY) public Category getCategory() { return category; } public void setCategory(Category category) { this.category = category; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
Category.java:
package com.bjsxt.hibernate;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import org.hibernate.annotations.BatchSize;@Entitypublic class Category {	private int id;	private String name;	@Id	@GeneratedValue	public int getId() {		return id;	}	public void setId(int id) {		this.id = id;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}}
添加数据(每一个板块ci下有一个话题ti)
@Test	public void testSave() {		Session session = sf.openSession();		session.beginTransaction();				//每一个版块ci下面有一个话题ti		for(int i=0; i<10; i++) {			Category c = new Category();			c.setName("c" + i);			Topic t=new Topic();			t.setCategory(c);			t.setTitle("t"+i);			t.setCreateDate(new Date());			session.save(c);			session.save(t);		}		session.getTransaction().commit();		session.close();	}
下面进行list与iterate的不同测试
1.list取所有
@Test	public void testOneAddNProblem1(){		Session session = sf.openSession();		session.beginTransaction();		List
topics=(List
)session.createQuery("from Topic").list(); for(Topic t:topics){ System.out.println(t.getId()+"-"+t.getTitle()); } session.getTransaction().commit(); session.close(); }
结果:
Hibernate: 
    select
        topic0_.id as id2_,
        topic0_.category_id as category4_2_,
        topic0_.createDate as createDate2_,
        topic0_.title as title2_ 
    from
        Topic topic0_
1-t0
2-t1
3-t2
4-t3
5-t4
6-t5
7-t6
8-t7
9-t8
10-t9
2.iterate先取ID,等用到的时候在根据ID来取对象。
@Test	public void testListAndIterate(){		Session session = sf.openSession();		session.beginTransaction();		Iterator
topics=(Iterator
)session.createQuery("from Topic").iterate(); for(Topic t=topics.next();t!=null;t=topics.next()){ System.out.println(t.getId()+"-"+t.getTitle()); } session.getTransaction().commit(); session.close(); }
测试结果:
Hibernate: 
    select
        topic0_.id as col_0_0_ 
    from
        Topic topic0_
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
1-t0
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
2-t1
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
3-t2
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
4-t3
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
5-t4
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
6-t5
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
7-t6
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
8-t7
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
9-t8
Hibernate: 
    select
        topic0_.id as id2_0_,
        topic0_.category_id as category4_2_0_,
        topic0_.createDate as createDate2_0_,
        topic0_.title as title2_0_ 
    from
        Topic topic0_ 
    where
        topic0_.id=?
10-t9
所以我们可以看出,先取ID,等用到的时候在根据ID来取对象。
3.session中list第二次发出,仍会到数据库查询。
测试代码:
@Test	public void testListAndIterate2(){		Session session = sf.openSession();		session.beginTransaction();		//Iterator
topics=(Iterator
)session.createQuery("from Topic").iterate(); Query q=session.createQuery("from Topic"); List
topics=q.list(); for(Topic t:topics){ System.out.println(t.getId()+"-"+t.getTitle()); } List
topics2=q.list(); for(Topic t:topics2){ System.out.println(t.getId()+"-"+t.getTitle()); } session.getTransaction().commit(); session.close(); }
测试结果:
Hibernate: 
    select
        topic0_.id as id2_,
        topic0_.category_id as category4_2_,
        topic0_.createDate as createDate2_,
        topic0_.title as title2_ 
    from
        Topic topic0_
1-t0
2-t1
3-t2
4-t3
5-t4
6-t5
7-t6
8-t7
9-t8
10-t9
Hibernate: 
    select
        topic0_.id as id2_,
        topic0_.category_id as category4_2_,
        topic0_.createDate as createDate2_,
        topic0_.title as title2_ 
    from
        Topic topic0_
1-t0
2-t1
3-t2
4-t3
5-t4
6-t5
7-t6
8-t7
9-t8
10-t9
4.iterate第二次,首先找session级缓存
测试代码:
@Test	public void testListAndIterate3(){		Session session = sf.openSession();		session.beginTransaction();		Iterator
categories = (Iterator
)session.createQuery("from Category").iterate(); while(categories.hasNext()) { Category c = categories.next(); System.out.println(c.getName()); } Iterator
categories2 = (Iterator
)session.createQuery("from Category").iterate(); while(categories2.hasNext()) { Category c = categories2.next(); System.out.println(c.getName()); } session.getTransaction().commit(); session.close(); }
测试结果:
Hibernate: 
    select
        category0_.id as col_0_0_ 
    from
        Category category0_
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c0
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c1
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c2
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c3
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c4
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c5
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c6
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c7
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c8
Hibernate: 
    select
        category0_.id as id0_0_,
        category0_.name as name0_0_ 
    from
        Category category0_ 
    where
        category0_.id=?
c9
Hibernate: 
    select
        category0_.id as col_0_0_ 
    from
        Category category0_
c0
c1
c2
c3
c4
c5
c6
c7
c8
c9
看出了第二次使用的session缓存里面的数据,而没有去数据库再查。
总结:
原因是:先看list,list取完10个数据以后session中有了10个数据的缓存,第二次list再去取的时候,它仍然要再去数据库里加载一次,然后再刷新缓存,再把原来对象重新刷一遍。也就是list不会去读session的缓存,原因是作为一个查询来说,查询条件很难认定,不是list不想利用,而是很难利用。
iterate就不一样了,首先在第一遍的时候,他首先把id取出来,由于后面我们做了遍历,所以他把id对应的对象全都放在了缓存中,第二次再做遍历的时候,这个时候只要去缓存中查就行了。
什么时候用list?什么时候用iterate?工作的时候用list就行了。
小技巧:第一次用list,第二次再去访问的时候就可以用iterate了。因为iterate会首先检查缓存,缓存中有了,就不会再去数据库里去查了。

主要应付面试

转载请注明出处:

你可能感兴趣的文章
Spark学习之Spark 集群资源调度
查看>>
京东Taro:用技术解放小程序生产力 | 点评家
查看>>
Dart编程语言入门学习
查看>>
小程序登录逻辑
查看>>
vscode透明主题、霓虹灯字体
查看>>
多线程基础知识
查看>>
iOS汇编基础(四)指针和macho文件
查看>>
Laravel 技巧锦集
查看>>
Android 使用 ViewPager+RecyclerView+SmartRefreshLayout 实现顶部图片下拉视差效果
查看>>
Flutter之基础Widget
查看>>
写给0-3岁产品经理的12封信(第08篇)——产品运营能力
查看>>
ArcGIS Engine 符号自动化配置工具实现
查看>>
小程序 · 跳转带参数写法,兼容url的出错
查看>>
开源干货!!!.NET Core + Vue.js(iview-admin) 通用动态权限(RBAC)管理系统框架[DncZeus]开源啦!!!...
查看>>
flutter error
查看>>
Flask框架从入门到精通之模型数据库配置(十一)
查看>>
10年重新出发
查看>>
2019年-年终总结
查看>>
聊聊elasticsearch的RoutingService
查看>>
让人抓头的Java并发(一) 轻松认识多线程
查看>>