一级缓存及二级缓存
一级缓存也是Session 缓存
????一个链接用户的多次查询使用缓存
????跨用户 则无缓存
????hibernate自带的
get和load都会填充并利用一级缓存
二级缓存(需要我们自己配置)
????SessionFactory 缓存
????可以跨用户的
?
list 方法会使用一级缓存 ,但是不会填充一级缓存
iterator会填充过一级缓存 耗时的
?
N+1问题
当我们使用iterate 进行迭代
又要使用内部的数据,则会发送1+n条sql
第一条先load 拿到id 对象改变对象则会改变
再取get每一个的id
?
?
Saveor update
/* ???? * 如果一个对先查找出来的,则会调用update语句 ???? * 如果没有查 ???? */ ????public ????????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 ????public ????????Emp e=fetchTest2(); ????????System.out.println(e.getDept()); ????} ????// ????public ????????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(); ???????? ????} ????//get和load都是會填充一级缓存的 ????public ????????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 ????????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 ????????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 进行迭代 ????//第一条先load拿到id 对象改变9对象则会改变 ???? //????再取get每一个的id ????/** ???? * ???? */ ????public ????????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(); ???????? ????} ????/** ???? * 配置二级缓存最好的方式是在每个类的配置 ???? */ ????public ????????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 ????????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的话 ???? */ ????public ????????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)
说明表中没有本条数据