hibernate-性能优化(3种缓存)-19

1. 注意session.clear()的运用,尤其是在不断分页循环的时候

a.在一个大集合中进行遍历,遍历msg,取出其中含有敏感字体的对象
b.另外一种形式的内存泄漏 // java有内存泄漏吗? 代码级别没有,实际操作中会有,例如:打开数据库、读文件不关闭链接,hibernate的分页没有进行session.clear()

2. 1+N问题(典型面试题)

例如:一个Category,对应一个topic,Category和topic各有10条,当想取出所有topic时,默认hibernate会发出1+10(取10个category)条sql语句,这种情况被称为1+N问题。

a和c根据具体情况使用

解决方案: a. 把fetchtype设成lazy
b.@BatchSize(size=5) 设置在Category的类名上(此方案不特别好)
c. join fetch
使用session.createCriteria(Topic.class),默认使用join fetch,只发出一条sql语句

3. list和iterate(不太重要,一般情况下用list(),面试可能会问)

a. list取所有
b. iterate先取ID,等用到的时候再根据ID取对象
c. session中list第二次发出,仍会查询数据库
d.iterate第二次,首先找session缓存

4. 一级缓存、查询缓存、查询缓存(面试题)

a. 什么是缓存
经常被访问的数据,存放到内存中,便于访问
b. 什么是一级缓存
session级别的缓存
e.g. 同一个session,load某条数据两次,但hibernate只发出一条sql语句(即只查询一次数据库),因为第二次已从缓存中取得结果
不同的session,各load某条数据一次,hibernate还是发出两条sql语句,它们的session缓存不共享
c. 什么是二级缓存
SessionFactory级别的缓存,可以跨越session存在(让多个session共享同一块缓存)
什么样的数据适合放入二级缓存?e.g. 组织机构、用户权限等
1. 经常被访问
2. 改动不大不会经常改动
3. 数量有限
d. 打开二级缓存
hibernate.cfg.xml中设定

<property name="cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.region.factory_cl‌​ass">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>

添加ehcache.xml文件

...
 <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />
...

给需要二级缓存的对象,配置二级缓存

@Entity


@Cache(usage =CacheConcurrencyStrategy.READ_WRITE  //  放到二级缓存中可读可改
       ,region = "sampleCache1") // 二级缓存的名字  对应ehcache.xml文件中的名字
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;
    }
}

e. load默认用二级缓存,iterate默认用二级缓存
f. list默认向二级缓存加数据,但查询的时候不用二级缓存(因为查询的条件不同,没发用;如果查询条件相同时,可以从二级缓存查,这种缓存被称为查询缓存(三级缓存))
g. 如果query需要用二级缓存,第一步:那么需要打开查询缓存

        <property name="hibernate.cache.use_query_cache">true</property>

第二步:需要在查询的时候设置一些参数
Query q = session.createQuery(” from Category “);
(List)q.setCacheable(true).list();

//  只发一条sql语句
@Test
    public void testQueryCache(){

        Session session = sf.getCurrentSession();
        session.beginTransaction();
        Query q = session.createQuery(" from Category ");
        List<Category> categories = (List<Category>)q.setCacheable(true).list();
        for(Category c:categories){
            System.out.println(c.getName());
        }
        session.getTransaction().commit();


        Session session2 = sf.getCurrentSession();
        session2.beginTransaction();
        Query q2 = session2.createQuery(" from Category ");
        List<Category> categories2 = (List<Category>)q2.setCacheable(true).list();
        for(Category c:categories2){
            System.out.println(c.getName());
        }
        session2.getTransaction().commit();


    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值