码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码

时间:2015-07-28 20:36:33      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

一级缓存及二级缓存

一级缓存也是Session 缓存

????一个链接用户的多次查询使用缓存

????跨用户 则无缓存

????hibernate自带的

get和load都会填充并利用一级缓存

二级缓存(需要我们自己配置)

????SessionFactory 缓存

????可以跨用户的

?

list 方法会使用一级缓存 ,但是不会填充一级缓存

iterator会填充过一级缓存 耗时的

?

N+1问题

当我们使用iterate 进行迭代 又要使用内部的数据,则会发送1+nsql

第一条先load 拿到id 对象改变对象则会改变

再取get每一个的id

?

?

Saveor update

/*

???? * 如果一个对先查找出来的,则会调用update语句

???? * 如果没有查 则调用insert语句

???? */

????public static void testSaveorUpdate(Emp e){

????????Session session=HibernateSessionFactory.getSession();

????????Transaction tx=session.beginTransaction();

????????session.saveOrUpdate(e);

????????tx.commit();

????????HibernateSessionFactory.closeSession();

????}

?

?

例子代码

package com.pcx.dao;

?

import java.util.Iterator;

import java.util.List;

?

import org.hibernate.Session;

?

import com.pcx.model1.Dept;

import com.pcx.model1.Emp;

import com.pcx.util.HibernateSessionFactory;

?

public class CacheTest {

????public static void main(String[] args) {

????????Emp e=fetchTest2();

????????System.out.println(e.getDept());

????}

????//

????public static void cacheTest(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????????

????}

????//getload都是會填充一级缓存的

????public static void cacheTest2(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.load(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????????

????}

????

????public static void cacheTest3(){

????????Session session=HibernateSessionFactory.getSession();

????????String hql="from Emp e where e.id=1";

???????? ?

???????? ?

????????

????????List<Emp> emps=session.createQuery(hql).list();

????????for (Emp emp : emps) {

????????????System.out.println(emp.getName());

????????}

????????

????????//这儿没有用上一级缓存

????????List<Emp> emps2=session.createQuery(hql).list();

????????for (Emp emp : emps2) {

????????????System.out.println(emp.getName());

????????}

????????HibernateSessionFactory.closeSession();

????????

????}

????public static void testload(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp e=(Emp) session.load(Emp.class, 2);

????????

????????System.out.println(e.getId());

????????System.out.println(e.getName());

????????e.setName("lllll");

????????HibernateSessionFactory.closeSession();

????}

????//n+1问题

????//当我们使用iterate 进行迭代 又要使用内部的数据,则会发送1+nsql

????//第一条先load拿到id 对象改变9对象则会改变

????

//????再取get每一个的id

????/**

???? *

???? */

????public static void cacheTest4(){

????????Session session=HibernateSessionFactory.getSession();

????????String hql="from Emp";

????????

????????Iterator<Emp> iter=session.createQuery(hql).iterate();

????????while (iter.hasNext()) {

????????????Emp e=iter.next();

????????????System.out.println(e.getName());

????????????

????????}

????????HibernateSessionFactory.closeSession();

????????

????}

????/**

???? * 配置二级缓存最好的方式是在每个类的配置 添加 <cache usage="read-only"/>标记

???? */

????public static void cacheTest5(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????session.evict(emp);//清理一级缓存 //如果二级缓存关闭的话会查询两次

????????Emp emp1=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????}

????public static void cacheTest6(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.get(Emp.class, 1);

????????

????????System.out.println(emp.getName());

????????session.evict(emp);//清理一级缓存 //如果二级缓存关闭的话会查询两次

????????Session session2=HibernateSessionFactory.getSession();

????????Emp emp1=(Emp) session2.get(Emp.class, 1);

????????

????????System.out.println(emp1.getName());

????????HibernateSessionFactory.closeSession();

????}

????/*

???? * 抓取策略

???? * Fetch join的话 就没有lazy 就直接把dept对象都加载了

???? */

????public static Emp fetchTest2(){

????????Session session=HibernateSessionFactory.getSession();

????????Emp emp=(Emp) session.load(Emp.class, 1);

????????Dept d=emp.getDept();

????????

????????

//????????System.out.println(emp.getName());

//????????System.out.println(d.getName());

????????HibernateSessionFactory.closeSession();

????????return emp;

????}

}

?

?

Fecat="join"

fatch 默认只就是select

????join 也将关联的对象一并加载进

来了,并不管是否懒加载

?

错误:No row with the given identifier exists: [com.pcx.model1.Emp#1000]

????at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:386)

说明表中没有本条数据

Hibernate笔记④--一级二级缓存、N+1问题、saveorupdate、实例代码

标签:

原文地址:http://www.cnblogs.com/chengzhipcx/p/4683576.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!