0
点赞
收藏
分享

微信扫一扫

【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();
	}

测试结果:


看出了第二次使用的session缓存里面的数据,而没有去数据库再查。

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



总结:


原因是:先看list,list取完10个数据以后session中有了10个数据的缓存,第二次list再去取的时候,它仍然要再去数据库里加载一次,然后再刷新缓存,再把原来对象重新刷一遍。也就是list不会去读session的缓存,原因是作为一个查询来说,查询条件很难认定,不是list不想利用,而是很难利用。


iterate就不一样了,首先在第一遍的时候,他首先把id取出来,由于后面我们做了遍历,所以他把id对应的对象全都放在了缓存中,第二次再做遍历的时候,这个时候只要去缓存中查就行了。


什么时候用list?什么时候用iterate?工作的时候用list就行了。


小技巧:第一次用list,第二次再去访问的时候就可以用iterate了。因为iterate会首先检查缓存,缓存中有了,就不会再去数据库里去查了。



主要应付面试

举报

相关推荐

0 条评论