Hibernate 二级缓存
该文章参考了Hibernate @Cache注解
需要在实体类上加三个注解, 分别是
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "entityCache")
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler", "fieldHandler"})
@Cacheable(Jpa中的注解)
说明当开启二级缓存时, 该实体类是否应该被缓存, 如果需要被缓存, 可以直接添加该注解, 如果不需要可以指定@Cacheable(false)
@Cache(Hibernate中的注解)
定义了缓存策略以及缓存范围
属性
usage 当前缓存策略
read-only 只读缓存
如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读缓存
read-write 读写缓存
如果应用程序需要更新数据,那么使用读/写缓存比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略
nonstrict-read-write 不严格读写缓存
如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。
transactional 事务性缓存
Hibernate 的事务缓存策略提供了全事务的缓存支持,例如对 JBoss TreeCache 的支持。这样的缓存只能用于 JTA 环境中,你必须指定为其hibernate.transaction.manager_lookup_class属性。
region 指定二级缓存的去域名,默认为类或者集合的名字
include 可选参数(all, non-lazy)。all包含所有属性,non-lazy仅包含非延迟加载的属性。
例子
缓存实体
@Table(name = "PROVICE") @Cache(usage =CacheConcurrencyStrategy.READ_ONLY) public class Province() { ... }
缓存集合
@Table(name = "PROVICE") @Cache(usage =CacheConcurrencyStrategy.READ_ONLY) public class Province() {//省份对象 @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "cityId") @Cache(usage = CacheConcrrencyStrategy.READ_ONLY) private Set<City> cities; //省份对应城市 }
此时在访问province.cities时,Hibernate 只缓存了city的OID,因此在实际查询过程中还是需要执行
select * from city where cityid = ?
为了避免该问题,可以为City对象同样配置二级缓存
@Table(name = "CITY") @Cache(usage =CacheConcurrencyStrategy.READ_ONLY) public class City() {//城市对象 ... }
详细了解请查看 Hibernate 二级缓存
@JsonIgnoreProperties (Jackson中的注解)
转Json时设置忽略的属性
属性
ignoreUnknown
设置为true在生成Json时会忽略实体类中不存在的属性
value
指定忽略的属性
allowGetters
只生成具有getter方法的属性
allowSetters
只生成具有setter方法的属性
详解
例子: 部门和员工
员工中有部门的外键, 员工和部门时一对多的关联关系, 那么在员工的实体类是这样的:
@Entity
@Table(name = "Employee")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
//如果有其他外键就会有Handler这个属性
@JsonIgnoreProperties(value={"hibernateLazyInitializer", "handler", "fieldHandler"})
public class Employee {
@Id
@Column(name = "EmployeeId")
private String employeeId;
@Column(name = "EmployeeName")
private String employeeName;
@ManyToOne(fetch = FetchType.LAZY) //开启懒加载
@JoinColumn(name = "DepartmentId")
private Department department;
//省略get set方法
}
而部门的实体类是这样的:
@Entity
@Table(name = "Department")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
//employee是hibernate建立关联关系用的, 所以需要忽略掉
@JsonIgnoreProperties(value={"hibernateLazyInitializer", "fieldHandler", "employees"})
public class Employee {
@Id
@Column(name = "DepartmentId")
private String departmentId;
@Column(name = "DepartmentName")
private String departmentName;
@OneToMany(fetch = FetchType.LAZY) //开启懒加载
@JoinColumn(targetEntity = Employee.class)
private Set<Employee> employees;
//省略get set方法
}