JPA仅仅只是一个规范,而不是产品;使用JPA本身是不能做到持久化的。所以,JPA只是一系列定义好的持久化操作的接口,在系统中使用时,需要真正的实现者,在这里,我们使用Hibernate作为实现者。
JPA规范中定义了很多的缓存类型:一级缓存,二级缓存,对象缓存,数据缓存
hibernate实现中只有三种缓存类型: 一级缓存,二级缓存和查询缓存。 在hibernate的实现概念里,他把什么集合缓存之类的统一放到二级缓存里去了。
1. 一级缓存
不需要有特殊配置。同一个session就行
2. 二级缓存
开启步骤
1:实体类直接打上 javax.persistence.Cacheable 标记。 (@Cacheable )
如
@Entity
@Table(name ="tablename")
@Cacheable
public class XxxEntity{}
2:加@cache
如
@Entity
@Table(name ="tablename")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class XxxEntity{}
另一种方法
1:实体类加@Cacheable
2:配置文件修改,在 jpaProperties 下添加,用ehcache来实现二级缓存
如:
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop>
其他说明
<!--将hibernate的统计打开来看看到底是不是被缓存了。 -->
<prop key="hibernate.generate_statistics">true</prop>
hibernate的 hibernate.cache.use_second_level_cache这个属性,只要有@cache标记,自动开启。
javax.persistence.sharedCache.mode的其他配置如下:
The javax.persistence.sharedCache.mode property can be set to one of the following values:
ENABLE_SELECTIVE (Default and recommended value): entities are not cached unless explicitly marked as cacheable.
DISABLE_SELECTIVE: entities are cached unless explicitly marked as not cacheable.
NONE: no entity are cached even if marked as cacheable. This option can make sense to disable second-level cache altogether.
ALL: all entities are always cached even if marked as non cacheable.
如果用all的话,连实体上的@cacheable都不用打,直接默认全部开启二级缓存
3查询缓存
一,二级缓存都是根据对象id来查找,如果需要加载一个List的时候,就需要用到查询缓存。
开启步骤
1.配置文件
<prop key="hibernate.cache.use_query_cache">true</prop>
2.要在方法内打上@QueryHint来实现查询缓存
如
@Query("from XxxEntity")
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value ="true") })
List<XxxEntity> findAllCached();
注意: 这样查询缓存是不会生效的,也就是spring-data-jpa默认实现的findAll()方法无法保存到查询缓存
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value ="true") })
List<XxxEntity> findAll();
4.集合缓存:就是二级缓存的一种
网上例子
`@Entity
@Table(name =”parent”)
@Cacheable
public class Parent extends IdEntity {
private static final long serialVersionUID = 1L;
private String name;
private List<Children> clist;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OneToMany(fetch = FetchType.EAGER,mappedBy = "parent")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public List<Children> getClist() {
return clist;
}
public void setClist(List<Children> clist) {
this.clist = clist;
}
}
@Entity
@Table(name =”children”)
@Cacheable
public class Children extends IdEntity{
private static final long serialVersionUID = 1L;
private String name;
private Parent parent;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} `