【hibernate框架】性能优化之list_iterate的不同之处

简介:
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;

@Entity
public class Topic {
	private int id;
	private String title;
	private Category category;
	private Date createDate;
	private List<Msg> msgs = new ArrayList<Msg>();
	
	@OneToMany(mappedBy="topic")
	public List<Msg> getMsgs() {
		
		return msgs;
	}
	public void setMsgs(List<Msg> 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;

@Entity
public 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<Topic> topics=(List<Topic>)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<Topic> topics=(Iterator<Topic>)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<Topic> topics=(Iterator<Topic>)session.createQuery("from Topic").iterate();
		Query q=session.createQuery("from Topic");
		List<Topic> topics=q.list();
		for(Topic t:topics){
			System.out.println(t.getId()+"-"+t.getTitle());
		}
		List<Topic> 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<Category> categories = (Iterator<Category>)session.createQuery("from Category").iterate();
		
		while(categories.hasNext()) {
			Category c = categories.next();
			System.out.println(c.getName());
		}
		
		Iterator<Category> categories2 = (Iterator<Category>)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会首先检查缓存,缓存中有了,就不会再去数据库里去查了。

主要应付面试

转载请注明出处:http://blog.csdn.net/acmman/article/details/43937591

相关文章
|
6月前
|
SQL 缓存 Java
框架分析(9)-Hibernate
框架分析(9)-Hibernate
|
6月前
|
存储 安全 Java
java集合框架及其特点(List、Set、Queue、Map)
java集合框架及其特点(List、Set、Queue、Map)
|
26天前
|
缓存 Java 数据库连接
Hibernate:Java持久层框架的高效应用
通过上述步骤,可以在Java项目中高效应用Hibernate框架,实现对关系数据库的透明持久化管理。Hibernate提供的强大功能和灵活配置,使得开发者能够专注于业务逻辑的实现,而不必过多关注底层数据库操作。
13 1
|
1月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
58 5
|
3月前
|
存储 安全 Java
java集合框架复习----(2)List
这篇文章是关于Java集合框架中List集合的详细复习,包括List的特点、常用方法、迭代器的使用,以及ArrayList、Vector和LinkedList三种实现类的比较和泛型在Java中的使用示例。
java集合框架复习----(2)List
|
3月前
|
存储 安全 Java
java集合框架复习----(4)Map、List、set
这篇文章是Java集合框架的复习总结,重点介绍了Map集合的特点和HashMap的使用,以及Collections工具类的使用示例,同时回顾了List、Set和Map集合的概念和特点,以及Collection工具类的作用。
java集合框架复习----(4)Map、List、set
|
3月前
|
SQL Java 数据库连接
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。
Hibernate 是一款开源 ORM(对象关系映射)框架,封装了 JDBC,允许以面向对象的方式操作数据库,简化了数据访问层的开发。通过映射机制,它可以自动处理对象与数据库表之间的转换,支持主流数据库,提高了代码的可移植性和可维护性。其核心接口包括 SessionFactory、Session 和 Transaction 等,通过它们可以执行数据库的 CRUD 操作。配置方面,需在项目中引入 Hibernate 及数据库驱动依赖,并创建 `hibernate.cfg.xml` 配置文件来设置数据库连接和 Hibernate 行为参数。
47 1
|
3月前
|
数据库 Java 数据库连接
Struts 2 与 Hibernate 的完美邂逅:如何无缝集成两大框架,轻松玩转高效 CRUD 操作?
【8月更文挑战第31天】本文通过具体示例介绍了如何在 Struts 2 中整合 Hibernate,实现基本的 CRUD 操作。首先创建 Maven 项目并添加相关依赖,接着配置 Hibernate 并定义实体类及其映射文件。然后创建 DAO 接口及实现类处理数据库操作,再通过 Struts 2 的 Action 类处理用户请求。最后配置 `struts.xml` 文件并创建 JSP 页面展示用户列表及编辑表单。此示例展示了如何配置和使用这两个框架,使代码更加模块化和可维护。
98 0
|
3月前
|
测试技术 索引 Python
Python接口自动化测试框架(基础篇)-- 常用数据类型list&set()
本文介绍了Python中list和set两种数据类型的使用,包括它们的创建、取值、增删改查操作、排序以及内置函数的使用,还探讨了list的比较函数和set的快速去重功能。
34 0
|
3月前
|
存储 SQL Java