Hibernate第六课--1+N问题和缓存
来源:互联网 发布:数据统计问题有哪些 编辑:程序博客网 时间:2024/06/11 01:30
@ManyToOne(fetch=FetchType.LAZY)
@OneToMany(fetch=FetchType.LAZY)
@BatchSize(size=100)
public class Category
@ManyToOne
@BatchSize(size=5)
public Category getCategory() {
return category;
}
List<Topic> lists = (List<Topic>)session.createQuery("from Topic t left join t.category").list();
//Criteria默认使用外连接
//List<Topic> lists = (List<Topic>)session
//.createCriteria(Topic.class)
//.list();
/**
* 首先将查询的主键获取
* Hibernate:
select
topic0_.id as col_0_0_
from
Topic topic0_
* @return @void
*/
@Test
public void testItrator()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
Iterator<Topic> topics = q1.iterate();
q1.setCacheable(true);
session.getTransaction().commit();
}
/**
* Iterator
* 每次查询后将结果放入session,
* 在同一生命周期的session,iterate查询 如果session有将不会再到数据库查找,直接返回值
* @return @void
*/
@Test
public void testIterator1()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
Iterator<Topic> ts = q1.iterate();
while(ts.hasNext())
{
Topic t = ts.next();
System.out.println("Topic :"+t.getTitle());
}
Query q2 = session.createQuery("from Topic t");
Iterator<Topic> ts2 = q2.iterate();
while(ts2.hasNext())
{
Topic t = ts.next();
System.out.println("Topic :"+t.getTitle());
}
session.getTransaction().commit();
}
/**
* List每次默认发出sql查询
* @return @void
*/
@Test
public void testList1()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
List<Topic> list1 = q1.list();
for(Topic t :list1)
{
log.debug("Topic :"+t);
}
Query q2 = session.createQuery("from Topic t");
List<Topic> list2 = q2.list();
for(Topic t :list2)
{
log.debug("Topic :"+t);
}
session.getTransaction().commit();
}
● load,
● iterate
● ehcache.xml
● hibernate.cfg.xml
<!--注意三者区别-->
<!-- hibernte3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>-->
<!-- hibernte4.2
<property name="cache.region.factory_class">
org.hibernate.cache。ehcache.EhCacheRegionFactory
</property>-->
<!-- hibernte4.3.10-->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
● entity类
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
publicclassCategory
● 注意4.3.10版本放弃了evict,改用getCache()统一管理查询缓存查询缓存 key值是hql,value值是实体主键,主要作用是缓存普通属性查询。当前关联的表发生修改,那么查询缓存生命周期结束
<!-- 打开查询缓存 -->
<propertyname="cache.use_query_cache">true</property>
●iterator不起作用无
/**
* 控制台输出:
* Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
* @return @void
*/
@Test
public void testGet()
{
session.beginTransaction();
Category c1 = (Category) session.get(Category.class, 1);
Category c2 = (Category) session.get(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
session.getTransaction().commit();
}
/**
* 控制台输出:
* Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
* @return @void
*/
@Test
public void testLoad()
{
session.beginTransaction();
Category c1 = (Category) session.load(Category.class, 1);
Category c2 = (Category) session.load(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
session.getTransaction().commit();
}
/**
* Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.id=1
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.id=1
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@1bbbafc[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@1bbbafc[id=1,name=c0]
* @return @void
*/
@Test
public void testIterate()
{
session.beginTransaction();
Iterator c1 = (Iterator) session.createQuery("from Category where id = 1").iterate();
Iterator c2 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c1.hasNext())
{
Category c = (Category) c1.next();
System.out.println("Category :"+c);
}
while(c2.hasNext())
{
Category c = (Category) c2.next();
System.out.println("Category :"+c);
}
session.getTransaction().commit();
}
@Test
public void testClear()
{
session.beginTransaction();
Iterator c1 = (Iterator) session.createQuery("from Category where id = 1").iterate();
Iterator c2 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c1.hasNext())
{
Category c = (Category) c1.next();
System.out.println("Category :"+c);
}
while(c2.hasNext())
{
Category c = (Category) c2.next();
System.out.println("Category :"+c);
}
//清除session
session.clear();
Iterator c3 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c3.hasNext())
{
Category c = (Category) c3.next();
System.out.println("Category :"+c);
}
session.getTransaction().commit();
}
@Test
public void testEvict()
{
session.beginTransaction();
Category c1 = (Category) session.load(Category.class, 1);
Category c2 = (Category) session.load(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
//清除的是放入session的对象 不能是Query,Iterator
session.evict(c1);
session.evict(c2);
Category c3 = (Category) session.load(Category.class, 1);
System.out.println("Category3 :"+c3);
session.getTransaction().commit();
}
create or replace procadure UserUpdate(u_age in number) as
begin
update users set age=age+1 where age>u_age;
end;
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn=session.connection();
String str="{call UserUpdate(?)}";
CallableStatement cstmt= conn.prepareCall(str);
cstmt.setInt(1,0);
cstmt.executeUpdate();
tx.commit();
sessionFactory.evict(Customer.class, new Integer(1));
sessionFactory.evict(Customer.class);
sessionFactory.evictCollection("Customer.orders");
Cache cache = sfactory.getCache();
//清除所有
cache.evictAllRegions();
//cache.evictEntityRegion(Category.class);//清除指定类
//cache.evictEntity(Category.class,1);//清除指定类的指定数据
/*清除集合
cache.evictCollectionRegions();
cache.evictCollectionRegion(arg0);
cache.evictCollection(arg0, arg1);
*/
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--如果缓存中的对象存储超过指定的缓存数量的对象存储的磁盘地址-->
<diskStore path="D:/ehcache"/>
<!-- 默认cache:如果没有对应的特定区域的缓存,就使用默认缓存 -->
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"/>
<!-- 指定区域cache:通过name指定,name对应到Hibernate中的区域名即可-->
<cache name="cn.javass.h3test.model.UserModel"
eternal="false"
maxElementsInMemory="100"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200"
overflowToDisk="false">
</cache>
</ehcache>
Cache
Provider class
Type
Cluster Safe
Query Cache Supported
Hashtable (not intended for production use)
org.hibernate.cache.HashtableCacheProvider
memory
yes
EHCache
org.hibernate.cache.EhCacheProvider
memory, disk
yes
OSCache
org.hibernate.cache.OSCacheProvider
memory, disk
yes
SwarmCache
org.hibernate.cache.SwarmCacheProvider
clustered (ip multicast)
yes (clustered invalidation)
JBoss TreeCache
org.hibernate.cache.TreeCacheProvider
clustered (ip multicast), transactional
yes (replication)
yes (clock sync req.)
<!-- 二级缓存默认打开,这里只是显示打开一下 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 注意3和4者区别 -->
<!-- hibernte 3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>-->
<!-- hibernte 4.3.10 -->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Category {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
//set get...
}
//确保数据库中有标识符为1的FarmModel
FarmModel farm = (FarmModel) session.get(FarmModel.class, 1);
//如果修改将报错,只读缓存不允许修改
//farm.setName("aaa");
@Cache(usage =CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet<Ticket> getTickets(){
return tickets;
}
@Test
public void testload()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Category c1 = (Category) session.load(Category.class,1);
System.out.println("Category :"+c1);
session.close();
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class,1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
@Test
public void testiterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
Iterator<?> iterator = q1.iterate();
while(iterator.hasNext())
{
Category c = (Category) iterator.next();
System.out.println("Category :"+c);
}
session.close();
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Query q2 = (Query) session2.createQuery("from Category where name='c0'");
Iterator<?> iterator2 = q2.iterate();
while(iterator2.hasNext())
{
Category c = (Category) iterator2.next();
System.out.println("Category :"+c);
}
session2.close();
sfactory.close();
}
@Test
public void testiterate_load() {
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
Iterator<?> iterator = q1.iterate();
while (iterator.hasNext()) {
Category c = (Category) iterator.next();
System.out.println("Category :" + c);
}
session.close();
// 第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :" + c2);
session2.close();
sfactory.close();
}
/**
*
* list 只存不取
* @return @void
*/
@SuppressWarnings("unchecked")
@Test
public void testlist_load() {
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
for (Category c : (List<Category>)q1.list()) {
System.out.println("Category :" + c);
}
session.close();
// 第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :" + c2);
session2.close();
sfactory.close();
}
@Test
public void testEvict()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Category c1 = (Category) session.load(Category.class,1);
System.out.println("Category :"+c1);
session.close();
//4.3中evict过时,使用getCache
//sfactory.evict(Category.class);
Cache cache = sfactory.getCache();
//清除所有
cache.evictAllRegions();
//cache.evictEntityRegion(Category.class);//清除指定类
//cache.evictEntity(Category.class,1);//清除指定类的指定数据
/*清除集合
cache.evictCollectionRegions();
cache.evictCollectionRegion(arg0);
cache.evictCollection(arg0, arg1);
*/
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class,1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
CacheMode参数用于控制具体的Session如何与二级缓存进行交互。
CacheMode.NORMAL - 从二级缓存中读、写数据。
CacheMode.IGNORE- session不会与二级缓存交互。
CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。
CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过hibernate.cache.use_minimal_puts(是否优化二级缓存操作,最小化缓存写入操作(适用与集群缓存))的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。
如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。
Map cacheEntries = sessionFactory.getStatistics()
.getSecondLevelCacheStatistics(regionName)
.getEntries();
此时,你必须手工打开统计选项。可选的,你可以让Hibernate更人工可读的方式维护缓存内容。
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true
/**
* 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
* @return @void
*/
@Test
public void testMutual_GET()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.GET);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//不能取 所有两条sql
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* 仅向二级缓存写数据,但不从二级缓存中读数据。
* @return @void
*/
@Test
public void testMutual_PUT()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.PUT);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//一条sql 二级缓存有 且能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* 仅向二级缓存写数据,但不从二级缓存中读数据。
* 通过hibernate.cache.use_minimal_puts
* (是否优化二级缓存操作,最小化缓存写入操作(适用与集群缓存))的设置,
* 强制二级缓存从数据库中读取数据,刷新缓存内容。
* @return @void
*/
@Test
public void testMutual_REFRESH()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
session2.setCacheMode(CacheMode.REFRESH);
//两条sql 二级缓存有 但不能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* session与二级缓存之间没有交互
* @return @void
*/
@Test
public void testMutual_IGONORE()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.IGNORE);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//两条sql 二级缓存有 但不能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
<!-- 打开查询缓存 -->
<property name="cache.use_query_cache">true</property>
<!-- 二级缓存默认打开,这里只是显示打开一下 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 注意3和4区别 -->
<!-- hibernte 3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>
-->
<!-- hibernte 4.3.10 -->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Category
Query q = session.createQuery("from Category where name = 'c0'");
//手动打开查询缓存
q.setCacheable(true);
public void testquerylist(SessionFactory sfactory)
{
Session session = sfactory.openSession();
session.beginTransaction();
Query q = session.createQuery("from Category where name = 'c0'");
q.setCacheable(true);
List<Category> list = (List<Category>)q.list();
for(Category c : list)
{
System.out.println("Category : "+c);
}
session.getTransaction().commit();
session.close();
}
public void testqueryiterator(SessionFactory sfactory)
{
Session session = sfactory.openSession();
session.beginTransaction();
Query q = session.createQuery("from Category where name = 'c0'");
q.setCacheable(true);
Iterator iterate = q.iterate();
while(iterate.hasNext())
{
Category c = (Category) iterate.next();
System.out.println("Category : "+c);
}
session.getTransaction().commit();
session.close();
}
/**
* 第一次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@17b2b2[id=1,name=c0]
第二次list 查询
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@43da1b[id=1,name=c0]
* 第一次会将发出sql,然后将满足条件的实体主键放入查询缓存中,
* 查询缓存中key是hql,value是查询到的实体主键
* 第二次发出sql时,list先到查询缓存中查询,获取满足条件的id然后到数据库获取实体属性,
* 如果没有直接到数据库查询
* @return @void
*/
@Test
public void testQuerylist_list()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次list 查询");
testquerylist(sfactory);
System.out.println("第一次list 查询");
testquerylist(sfactory);
}
/**
* 第一次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@1c4a5ec[id=1,name=c0]
第二次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@21447f[id=1,name=c0]
iterator每次都是查询满足条件的实体主键,
然后到数据库中获取对应主键的实体属性
* @return @void
*/
@Test
public void testQueryiterate_iterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
}
/**
* 第一次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@17b2b2[id=1,name=c0]
第二次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@37165f[id=1,name=c0]
list 将查询到的实体主键放入查询缓存中,
literator对查询缓存的策略是不存,不取
* @return @void
*/
@Test
public void testQuerylist_iterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次list 查询");
testquerylist(sfactory);
System.out.println("第二次iterator 查询");
testqueryiterator(sfactory);
}
/**
* 第一次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@1c4a5ec[id=1,name=c0]
第二次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@1a1ff9[id=1,name=c0]
* @return @void
*/
@Test
public void testQueryiterate_list()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
System.out.println("第二次list 查询");
testquerylist(sfactory);
}
@ManyToOne(fetch=FetchType.LAZY)
@OneToMany(fetch=FetchType.LAZY)
@BatchSize(size=100)
public class Category
@ManyToOne
@BatchSize(size=5)
public Category getCategory() {
return category;
}
List<Topic> lists = (List<Topic>)session.createQuery("from Topic t left join t.category").list();
//Criteria默认使用外连接
//List<Topic> lists = (List<Topic>)session
//.createCriteria(Topic.class)
//.list();
/**
* 首先将查询的主键获取
* Hibernate:
select
topic0_.id as col_0_0_
from
Topic topic0_
* @return @void
*/
@Test
public void testItrator()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
Iterator<Topic> topics = q1.iterate();
q1.setCacheable(true);
session.getTransaction().commit();
}
/**
* Iterator
* 每次查询后将结果放入session,
* 在同一生命周期的session,iterate查询 如果session有将不会再到数据库查找,直接返回值
* @return @void
*/
@Test
public void testIterator1()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
Iterator<Topic> ts = q1.iterate();
while(ts.hasNext())
{
Topic t = ts.next();
System.out.println("Topic :"+t.getTitle());
}
Query q2 = session.createQuery("from Topic t");
Iterator<Topic> ts2 = q2.iterate();
while(ts2.hasNext())
{
Topic t = ts.next();
System.out.println("Topic :"+t.getTitle());
}
session.getTransaction().commit();
}
/**
* List每次默认发出sql查询
* @return @void
*/
@Test
public void testList1()
{
session.beginTransaction();
Query q1 = session.createQuery("from Topic t");
List<Topic> list1 = q1.list();
for(Topic t :list1)
{
log.debug("Topic :"+t);
}
Query q2 = session.createQuery("from Topic t");
List<Topic> list2 = q2.list();
for(Topic t :list2)
{
log.debug("Topic :"+t);
}
session.getTransaction().commit();
}
● load,
● iterate
● ehcache.xml
● hibernate.cfg.xml
<!--注意三者区别-->
<!-- hibernte3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>-->
<!-- hibernte4.2
<property name="cache.region.factory_class">
org.hibernate.cache。ehcache.EhCacheRegionFactory
</property>-->
<!-- hibernte4.3.10-->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
● entity类
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
publicclassCategory
● 注意4.3.10版本放弃了evict,改用getCache()统一管理查询缓存查询缓存 key值是hql,value值是实体主键,主要作用是缓存普通属性查询。当前关联的表发生修改,那么查询缓存生命周期结束
<!-- 打开查询缓存 -->
<propertyname="cache.use_query_cache">true</property>
●iterator不起作用无
/**
* 控制台输出:
* Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
* @return @void
*/
@Test
public void testGet()
{
session.beginTransaction();
Category c1 = (Category) session.get(Category.class, 1);
Category c2 = (Category) session.get(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
session.getTransaction().commit();
}
/**
* 控制台输出:
* Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@98bbf6[id=1,name=c0]
* @return @void
*/
@Test
public void testLoad()
{
session.beginTransaction();
Category c1 = (Category) session.load(Category.class, 1);
Category c2 = (Category) session.load(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
session.getTransaction().commit();
}
/**
* Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.id=1
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.id=1
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category :com.liuhao.hibernate4.demo.query2.Category@1bbbafc[id=1,name=c0]
Category :com.liuhao.hibernate4.demo.query2.Category@1bbbafc[id=1,name=c0]
* @return @void
*/
@Test
public void testIterate()
{
session.beginTransaction();
Iterator c1 = (Iterator) session.createQuery("from Category where id = 1").iterate();
Iterator c2 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c1.hasNext())
{
Category c = (Category) c1.next();
System.out.println("Category :"+c);
}
while(c2.hasNext())
{
Category c = (Category) c2.next();
System.out.println("Category :"+c);
}
session.getTransaction().commit();
}
@Test
public void testClear()
{
session.beginTransaction();
Iterator c1 = (Iterator) session.createQuery("from Category where id = 1").iterate();
Iterator c2 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c1.hasNext())
{
Category c = (Category) c1.next();
System.out.println("Category :"+c);
}
while(c2.hasNext())
{
Category c = (Category) c2.next();
System.out.println("Category :"+c);
}
//清除session
session.clear();
Iterator c3 = (Iterator) session.createQuery("from Category where id = 1").iterate();
while(c3.hasNext())
{
Category c = (Category) c3.next();
System.out.println("Category :"+c);
}
session.getTransaction().commit();
}
@Test
public void testEvict()
{
session.beginTransaction();
Category c1 = (Category) session.load(Category.class, 1);
Category c2 = (Category) session.load(Category.class, 1);
System.out.println("Category :"+c1);
System.out.println("Category :"+c2);
//清除的是放入session的对象 不能是Query,Iterator
session.evict(c1);
session.evict(c2);
Category c3 = (Category) session.load(Category.class, 1);
System.out.println("Category3 :"+c3);
session.getTransaction().commit();
}
create or replace procadure UserUpdate(u_age in number) as
begin
update users set age=age+1 where age>u_age;
end;
Session session =SessionFactory.openSession();
Transaction tx =session.beginTransaction();
Connection conn=session.connection();
String str="{call UserUpdate(?)}";
CallableStatement cstmt= conn.prepareCall(str);
cstmt.setInt(1,0);
cstmt.executeUpdate();
tx.commit();
sessionFactory.evict(Customer.class, new Integer(1));
sessionFactory.evict(Customer.class);
sessionFactory.evictCollection("Customer.orders");
Cache cache = sfactory.getCache();
//清除所有
cache.evictAllRegions();
//cache.evictEntityRegion(Category.class);//清除指定类
//cache.evictEntity(Category.class,1);//清除指定类的指定数据
/*清除集合
cache.evictCollectionRegions();
cache.evictCollectionRegion(arg0);
cache.evictCollection(arg0, arg1);
*/
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!--如果缓存中的对象存储超过指定的缓存数量的对象存储的磁盘地址-->
<diskStore path="D:/ehcache"/>
<!-- 默认cache:如果没有对应的特定区域的缓存,就使用默认缓存 -->
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="false"/>
<!-- 指定区域cache:通过name指定,name对应到Hibernate中的区域名即可-->
<cache name="cn.javass.h3test.model.UserModel"
eternal="false"
maxElementsInMemory="100"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200"
overflowToDisk="false">
</cache>
</ehcache>
Cache
Provider class
Type
Cluster Safe
Query Cache Supported
Hashtable (not intended for production use)
org.hibernate.cache.HashtableCacheProvider
memory
yes
EHCache
org.hibernate.cache.EhCacheProvider
memory, disk
yes
OSCache
org.hibernate.cache.OSCacheProvider
memory, disk
yes
SwarmCache
org.hibernate.cache.SwarmCacheProvider
clustered (ip multicast)
yes (clustered invalidation)
JBoss TreeCache
org.hibernate.cache.TreeCacheProvider
clustered (ip multicast), transactional
yes (replication)
yes (clock sync req.)
<!-- 二级缓存默认打开,这里只是显示打开一下 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 注意3和4者区别 -->
<!-- hibernte 3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>-->
<!-- hibernte 4.3.10 -->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Category {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
//set get...
}
//确保数据库中有标识符为1的FarmModel
FarmModel farm = (FarmModel) session.get(FarmModel.class, 1);
//如果修改将报错,只读缓存不允许修改
//farm.setName("aaa");
@Cache(usage =CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet<Ticket> getTickets(){
return tickets;
}
@Test
public void testload()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Category c1 = (Category) session.load(Category.class,1);
System.out.println("Category :"+c1);
session.close();
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class,1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
@Test
public void testiterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
Iterator<?> iterator = q1.iterate();
while(iterator.hasNext())
{
Category c = (Category) iterator.next();
System.out.println("Category :"+c);
}
session.close();
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Query q2 = (Query) session2.createQuery("from Category where name='c0'");
Iterator<?> iterator2 = q2.iterate();
while(iterator2.hasNext())
{
Category c = (Category) iterator2.next();
System.out.println("Category :"+c);
}
session2.close();
sfactory.close();
}
@Test
public void testiterate_load() {
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
Iterator<?> iterator = q1.iterate();
while (iterator.hasNext()) {
Category c = (Category) iterator.next();
System.out.println("Category :" + c);
}
session.close();
// 第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :" + c2);
session2.close();
sfactory.close();
}
/**
*
* list 只存不取
* @return @void
*/
@SuppressWarnings("unchecked")
@Test
public void testlist_load() {
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Query q1 = (Query) session.createQuery("from Category where name='c0'");
for (Category c : (List<Category>)q1.list()) {
System.out.println("Category :" + c);
}
session.close();
// 第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :" + c2);
session2.close();
sfactory.close();
}
@Test
public void testEvict()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session = sfactory.openSession();
session.beginTransaction();
Category c1 = (Category) session.load(Category.class,1);
System.out.println("Category :"+c1);
session.close();
//4.3中evict过时,使用getCache
//sfactory.evict(Category.class);
Cache cache = sfactory.getCache();
//清除所有
cache.evictAllRegions();
//cache.evictEntityRegion(Category.class);//清除指定类
//cache.evictEntity(Category.class,1);//清除指定类的指定数据
/*清除集合
cache.evictCollectionRegions();
cache.evictCollectionRegion(arg0);
cache.evictCollection(arg0, arg1);
*/
//第二个session但是SessionFactory没有关闭
Session session2 = sfactory.openSession();
Category c2 = (Category) session2.load(Category.class,1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
CacheMode参数用于控制具体的Session如何与二级缓存进行交互。
CacheMode.NORMAL - 从二级缓存中读、写数据。
CacheMode.IGNORE- session不会与二级缓存交互。
CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。
CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过hibernate.cache.use_minimal_puts(是否优化二级缓存操作,最小化缓存写入操作(适用与集群缓存))的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。
如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。
Map cacheEntries = sessionFactory.getStatistics()
.getSecondLevelCacheStatistics(regionName)
.getEntries();
此时,你必须手工打开统计选项。可选的,你可以让Hibernate更人工可读的方式维护缓存内容。
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true
/**
* 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
* @return @void
*/
@Test
public void testMutual_GET()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.GET);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//不能取 所有两条sql
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* 仅向二级缓存写数据,但不从二级缓存中读数据。
* @return @void
*/
@Test
public void testMutual_PUT()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.PUT);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//一条sql 二级缓存有 且能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* 仅向二级缓存写数据,但不从二级缓存中读数据。
* 通过hibernate.cache.use_minimal_puts
* (是否优化二级缓存操作,最小化缓存写入操作(适用与集群缓存))的设置,
* 强制二级缓存从数据库中读取数据,刷新缓存内容。
* @return @void
*/
@Test
public void testMutual_REFRESH()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
session2.setCacheMode(CacheMode.REFRESH);
//两条sql 二级缓存有 但不能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
/**
* session与二级缓存之间没有交互
* @return @void
*/
@Test
public void testMutual_IGONORE()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
Session session1 = sfactory.openSession();
session1.setCacheMode(CacheMode.IGNORE);
Category c1 = (Category) session1.load(Category.class, 1);
System.out.println("Category :"+c1);
session1.close();
System.out.println("-----------------------");
long count = sfactory.getStatistics()
.getSecondLevelCachePutCount();
System.out.println("Cache : "+count);
Session session2 = sfactory.openSession();
//两条sql 二级缓存有 但不能取
Category c2 = (Category) session2.load(Category.class, 1);
System.out.println("Category :"+c2);
session2.close();
sfactory.close();
}
<!-- 打开查询缓存 -->
<property name="cache.use_query_cache">true</property>
<!-- 二级缓存默认打开,这里只是显示打开一下 -->
<property name="cache.use_second_level_cache">true</property>
<!-- 注意3和4区别 -->
<!-- hibernte 3
<property name="cache.provider_class">
org.hibernate.cache.EhCacheRegionFactory
</property>
-->
<!-- hibernte 4.3.10 -->
<property name="cache.region.factory_class">
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
@Entity
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Category
Query q = session.createQuery("from Category where name = 'c0'");
//手动打开查询缓存
q.setCacheable(true);
public void testquerylist(SessionFactory sfactory)
{
Session session = sfactory.openSession();
session.beginTransaction();
Query q = session.createQuery("from Category where name = 'c0'");
q.setCacheable(true);
List<Category> list = (List<Category>)q.list();
for(Category c : list)
{
System.out.println("Category : "+c);
}
session.getTransaction().commit();
session.close();
}
public void testqueryiterator(SessionFactory sfactory)
{
Session session = sfactory.openSession();
session.beginTransaction();
Query q = session.createQuery("from Category where name = 'c0'");
q.setCacheable(true);
Iterator iterate = q.iterate();
while(iterate.hasNext())
{
Category c = (Category) iterate.next();
System.out.println("Category : "+c);
}
session.getTransaction().commit();
session.close();
}
/**
* 第一次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@17b2b2[id=1,name=c0]
第二次list 查询
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@43da1b[id=1,name=c0]
* 第一次会将发出sql,然后将满足条件的实体主键放入查询缓存中,
* 查询缓存中key是hql,value是查询到的实体主键
* 第二次发出sql时,list先到查询缓存中查询,获取满足条件的id然后到数据库获取实体属性,
* 如果没有直接到数据库查询
* @return @void
*/
@Test
public void testQuerylist_list()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次list 查询");
testquerylist(sfactory);
System.out.println("第一次list 查询");
testquerylist(sfactory);
}
/**
* 第一次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@1c4a5ec[id=1,name=c0]
第二次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@21447f[id=1,name=c0]
iterator每次都是查询满足条件的实体主键,
然后到数据库中获取对应主键的实体属性
* @return @void
*/
@Test
public void testQueryiterate_iterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
}
/**
* 第一次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@17b2b2[id=1,name=c0]
第二次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@37165f[id=1,name=c0]
list 将查询到的实体主键放入查询缓存中,
literator对查询缓存的策略是不存,不取
* @return @void
*/
@Test
public void testQuerylist_iterate()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次list 查询");
testquerylist(sfactory);
System.out.println("第二次iterator 查询");
testqueryiterator(sfactory);
}
/**
* 第一次iterator 查询
Hibernate:
select
category0_.id as col_0_0_
from
Category category0_
where
category0_.name='c0'
Hibernate:
select
category0_.id as id1_0_0_,
category0_.name as name2_0_0_
from
Category category0_
where
category0_.id=?
Category : com.liuhao.hibernate4.demo.query2.Category@1c4a5ec[id=1,name=c0]
第二次list 查询
Hibernate:
select
category0_.id as id1_0_,
category0_.name as name2_0_
from
Category category0_
where
category0_.name='c0'
Category : com.liuhao.hibernate4.demo.query2.Category@1a1ff9[id=1,name=c0]
* @return @void
*/
@Test
public void testQueryiterate_list()
{
SessionFactory sfactory = HibernateUtil.getSessionFactory();
System.out.println("第一次iterator 查询");
testqueryiterator(sfactory);
System.out.println("第二次list 查询");
testquerylist(sfactory);
}
- Hibernate第六课--1+N问题和缓存
- 深入剖析hibernate的N+1问题和缓存问题
- 补充:1+N问题和缓存算法
- 补充:1+N问题和缓存算法
- 深入剖析hibernate的N+1问题和缓存问题帖子1
- hibernate(实体bean和缓存的问题)
- Hibernate查询和缓存
- hibernate的session和缓存
- Hibernate 性能优化策略和缓存详解
- 理解Hibernate的Session和缓存机制
- showModalDialog的一些用法和缓存问题
- hibernate缓存:Hibernate获取数据方式和缓存Cache使用
- Hibernate——脏检查和缓存清理机制
- Hibernate——脏检查和缓存清理机制
- 第16章 Hibernate事务处理和缓存管理
- Hibernate脏数据检查和缓存清理策略
- Hibernate中的三种数据持久状态和缓存机制
- 有关hibernate相关的延迟加载和缓存机制
- Hibernate第四课--HIbernate三大状态转换
- Linux常用命令
- Hibernate第五课--查询
- 初学java的String类的compareTo方法
- MVG读书笔记——几何变换
- Hibernate第六课--1+N问题和缓存
- 170722 逆向-DLL基础
- Hibernate第七课--事务,悲观锁,乐观锁
- 也谈测试用例的设计
- sysctl命令详解
- 模拟实现String类
- Linux之进程管理
- Java虚拟机内存分区域与内存溢出异常
- Hibernate删除,添加问题