二级缓存的使用步骤:
* A:启用二级缓存
* 1.在hibernate配置文件(hibernate.cfg.xml文件)中启用二级缓,
* 配置在hibernate.properties文件的480行
true
B:指定二级缓存的实现者
2.指定二级缓存的实现者,配置在hibernate.properties文件的499行
org.hibernate.cache.OSCacheProvider
C:导入二级缓存需要的jar包:
3.导入二级缓存需要的jar包
A:将lib\optional\oscache\oscache-2.1.jar包复制到libs目录下
B:复制commons-logging-1.0.4.jar到libs目录下
并添加到classpath下。
D:复制缓存配置文件
4.复制project\etc\oscache.properties文件到src目录下
E:注意二级缓存不支持主键增长,因此要想使用二级缓存,则必须删除实体中@GenerateValue
@Id
private int id;
F:指定缓存对象的缓存级别
A:使用注解的方式
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
B:使用xml配置的方式
<!-- 采用xml的方式指定二级缓存对象的缓存级别,此配置必须放在mapping配置的下面,否则报错 -->
<class-cache usage="read-write" class="com.hsj.domain.Person"/>
例子:
Person类
@Entity
@Table(name="t_person")
//指定二级缓存对象的使用级别
//**@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)**
public class Person /*extends BaseEntity*/ {
@Id
private int id;
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
/**
* 在生成的表中添加一个in类型的字段,默认值为0,一旦当前对象的属性发生了变化则当前字段的值会自动增加1
*/
@Version
private int version;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age, String sex) {
super();
this.name = name;
this.age = age;
this.sex = sex;
}
public Person(int id,String name, int age, String sex) {
//super(id);
this.id=id;
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person [id="+id+",name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
测试类
public class TestCacheDemo01 {
public static void main(String[] args) {
//add();
secondLevelCache();
}
private static void secondLevelCache() {
Session session1=HibernateUtils.getSession();
/*Transaction transaction=session1.beginTransaction();
Person p=new Person(1,"张三",20,"男");
session1.save(p);
transaction.commit();*/
//如果启用了二级缓存,则在执行session.get()方法查询时,在将对象存入一级缓存的同时也自动存储到了二级缓存中
Person p1=(Person) session1.get(Person.class, 1);
System.out.println(p1);
//所以,再次使用不同的session查询对象时仍然没有发生select语句
Session session2=HibernateUtils.getSession();
Person p2=(Person) session2.get(Person.class, 1);
System.out.println(p2);
}
/**
* 添加数据
* 在执行session.save(),session.update()等都会先将对象存储到缓存中,然后在进行它的本职工作
* session.get(),session.load():先将对象从数据库中查询出来,然后存储到一级缓存中
*
* 对象的三种状态:
* A:瞬时状态
* 特点:
* A:在数据库中没有对应的持久化标识
* B:没有交给session管理
*
* B:持久化状态
* 特点:
* A:在数据库中有对应的持久化标识
* B:交给session管理
*
* C:脱管状态
* 特点:
* A:在数据库中有对应的持久化标识
* B:脱离了session管理
*/
private static void add() {
Session session=HibernateUtils.getSession();
try{
Transaction transaction=session.beginTransaction();
//1
Person p1=new Person("张三",20, "男");
//2 在1和2之间时p1处于瞬时状态
/*
* session.save(p1):这句代码到底干了哪些工作?
* A:将对象p1存储到数据库中
* B:将p1对象存储到session对象内部的缓存中,这个缓存可以简单理解为一个Map对象,
* Map map=new HashMap();
* map.put(p1.getId(),p1);
*/
session.save(p1);//在执行完毕session.save(p1)方法后p1对象已经存储到数据库中了,虽然此时还没有提交事务。
p1.setName("小龙女");
/*
* 数据库中的记录分为:
* A:逻辑记录:对象保存到数据中但是事务还没有提交时的状态
* B:物理记录:事务提交后记录的状态变成了物理状态
*/
// 3 在2和3之间p1处于持久化状态
Person p2=new Person("小丽",20, "女");
/*
* A:将对象p2存储到数据库中
* B:将p2对象存储到session对象内部的缓存中
* map.put(p2.getId(),p2);
*/
session.save(p2);
Person p3=new Person("小龙",18, "男");
session.save(p3);
Person p4=new Person("小静",18, "女");
session.save(p4);
//将p1对象从session的缓存中驱逐出去,map.remove(p1.getId());
//session.evict(p1);
//4 在3和4之间p1对象处于脱管状态
/*
* session.get(cls,主键值):根据主键值从数据库中查询记录作为当前对象
* 查询数据的顺序:
* A:根据主键值从缓存中查询对象,如果查询到了直接返回查询到的对象,不会继续查询数据库了。
* B:如果根据主键值在缓存中没有查询到对象则从数据库中查询对象,如果查询到了则将查询到的对象返回,
* 同时将查询到的对象缓存到session的一级缓存中
* session.get()内部也会自动缓存对象
*
*/
//Person person1=(Person) session.get(Person.class,1);
Person person1=(Person) session.load(Person.class,1);
System.out.println(person1);
System.out.println("================");
//session.evict(person1);
//Person person2=(Person) session.get(Person.class,1);
//session.clear();//将session中缓存清空,即:map.clear()
Person person2=(Person) session.get(Person.class,1);
System.out.println(person2);
transaction.commit();
}finally{
HibernateUtils.close(session);
}
}
}