1 一对多的单向
- 示例:一个已经存在的学生,新建一个班级,然后将该学生加入到该班级之下
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Classes">
<id name="cid">
<generator class="native"></generator>
</id>
<property name="name"/>
<property name="description"/>
<!--
set元素描述了集合
name就是属性的名称
cascade:save-update保存或更新的时候对Student进行操作
inverse 是否维护关系:Classes是否维护和Student之间的关系
true 不维护关系
false 维护关系
default=false
-->
<set name="students" cascade="save-update" >
<!--
key代表外键
-->
<key>
<column name="cid"/>
</key>
<!--
建立了对象和对象之间的关联
-->
<one-to-many class="com.xuweiwei.vo.Student"/>
</set>
</class>
</hibernate-mapping>
/**
* 已经存在一个学生,新建一个班级,把该学生加入到该班级
*/
@Test
public void testSaveClasses_Build(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Student student = (Student) session.get(Student.class,1L);
Classes c = new Classes();
c.setName("Linux");
c.setDescription("Linux厉害");
c.getStudents().add(student);
session.save(c);
tx.commit();
}
- 示例:已经存在一个学生,已经存在一个班级,将该学生加入到该班级
/**
* 已经存在一个学生,已经存在一个班级,将该学生加入到该班级
* 将sid为2的学生,加入到cid=1的班级
*/
@Test
public void testExistStudentAndClassesBuildRealationship(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Student student = (Student) session.get(Student.class,2L);
Classes classes = (Classes) session.get(Classes.class,1L);
classes.getStudents().add(student);
tx.commit();
}
- 示例:将一个学生(存在)从一个班级(存在)转移到另一个班级(存在)
/**
* 将一个学生从一个班级转移到另一个班级
*/
@Test
public void testTransferClasses(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Student student1 = (Student) session.get(Student.class,1L);
Classes classes1 = (Classes) session.get(Classes.class,1L);
Classes classes2 = (Classes) session.get(Classes.class,2L);
classes1.getStudents().remove(student1);
classes2.getStudents().add(student1);
tx.commit();
}
/**
* 将一个学生从一个班级转移到另一个班级
*/
@Test
public void testTransferClasses(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Student student1 = (Student) session.get(Student.class,1L);
Classes classes2 = (Classes) session.get(Classes.class,2L);
classes2.getStudents().add(student1);
tx.commit();
}
/**
* 解除一个班级和所有学生之间的关系
*/
@Test
public void testClassesRemoveAll(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Classes classes = (Classes) session.get(Classes.class,1L);
classes.setStudents(null);
tx.commit();
}
- 示例:解除一个班级和其下所有学生的关系,然后建立这个班级和其它学生的关系
/**
* 解除一个班级的和所有学生的关系,重新建立班级和其它学生的关系
*
*/
@Test
public void testRebuild(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Classes classes = (Classes) session.get(Classes.class,1L);
List<Student> studentList = (List<Student>) session.createSQLQuery("select * from student where cid != 1 ").addEntity(Student.class).list();
classes.setStudents(new HashSet<>(studentList));
tx.commit();
}
- 示例:先设置学生的外键为null,然后删除指定的班级信息
/**
* 将cid为1的班级
*/
@Test
public void testCascadeDelete(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Classes classes = (Classes) session.get(Classes.class,1L);
session.delete(classes);
tx.commit();
}
<!--
set元素描述了集合
name就是属性的名称
cascade:save-update保存或更新的时候对Student进行操作
inverse 是否维护关系:Classes是否维护和Student之间的关系
true 不维护关系
false 维护关系
default=false
-->
<set name="students" cascade="all-delete-orphan" >
<!--
key代表外键
-->
<key>
<column name="cid"/>
</key>
<!--
建立了对象和对象之间的关联
-->
<one-to-many class="com.xuweiwei.vo.Student"/>
</set>
/**
* 删除班级和其下的所有学生
*/
@Test
public void testCascadeDeleteAll(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Classes classes = (Classes) session.get(Classes.class,2L);
session.delete(classes);
tx.commit();
}
2 一对多的双向
package com.xuweiwei.vo;
import java.io.Serializable;
/**
* 学生
*/
public class Student implements Serializable{
private Long sid;//学生的ib
private String name;//学生的名称
private String description;//学生的描述
private Classes classes ;//一个学生属于一个班级
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.xuweiwei.vo.Student">
<id name="sid">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="description"/>
<!--
column表示外键
-->
<many-to-one name="classes" class="com.xuweiwei.vo.Classes" column="cid" cascade="save-update"/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Classes">
<id name="cid">
<generator class="increment"></generator>
</id>
<property name="name"/>
<property name="description"/>
<!--
set元素描述了集合
name就是属性的名称
cascade:save-update保存或更新的时候对Student进行操作
inverse 是否维护关系:Classes是否维护和Student之间的关系
true 不维护关系
false 维护关系
default=false
-->
<set name="students" cascade="all-delete-orphan" >
<!--
key代表外键
-->
<key>
<column name="cid"/>
</key>
<!--
建立了对象和对象之间的关联
-->
<one-to-many class="com.xuweiwei.vo.Student"/>
</set>
</class>
</hibernate-mapping>
3 多对多操作
3.1 配置hibernate多对多的环境
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个sessionFactory就代表一个数据库的描述
-->
<session-factory>
<!-- 链接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 链接数据库的密码 -->
<property name="connection.password">root</property>
<!-- 链接数据库的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 链接数据库的url -->
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate
</property>
<!--
方言
告诉hibernate用什么样的数据库,将来会生成什么样的sql语句
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
hibernate对表的策略
validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表
create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表
create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表
update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示sql语句
-->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="current_session_context_class">thread</property>
<mapping resource="com/xuweiwei/vo/Student.hbm.xml"/>
<mapping resource="com/xuweiwei/vo/Course.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.xuweiwei.vo;
import java.io.Serializable;
import java.util.Set;
public class Student implements Serializable {
private Long sid;
private String name;
private String description;
private Set<Course> courses;
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Course> getCourses() {
return courses;
}
public void setCourses(Set<Course> courses) {
this.courses = courses;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Student">
<id name="sid" length="5">
<generator class="native"/>
</id>
<property name="name" length="20"/>
<property name="description" length="50"/>
<!--
table表示中间表
-->
<set name="courses" table="student_course" cascade="save-update">
<!--
表示student在第三方表所对应外键
-->
<key>
<column name="sid"></column>
</key>
<many-to-many class="com.xuweiwei.vo.Course" column="cid"> </many-to-many>
</set>
</class>
</hibernate-mapping>
package com.xuweiwei.vo;
import java.io.Serializable;
import java.util.Set;
public class Course implements Serializable {
private Long cid;
private String name;
private String description;
private Set<Student> students ;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Course">
<id name="cid" length="5">
<generator class="native"/>
</id>
<property name="name" length="20"/>
<property name="description" length="50"/>
<set name="students" table="student_course">
<key>
<column name="cid"></column>
</key>
<many-to-many class="com.xuweiwei.vo.Student" column="sid"> </many-to-many>
</set>
</class>
</hibernate-mapping>
package com.xuweiwei.test;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class TestManyToMany {
@Test
public void testCreateTable(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
tx.commit();
}
}
3.2 多对多的操作
/**
* 保存学生的同时保存课程
*/
@Test
public void testCreateStudentAndCourse(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Student student = new Student();
student.setName("许威威");
student.setDescription("java开发");
Course course1 = new Course();
course1.setName("Linux");
course1.setDescription("Linux如此之牛逼");
Course course2 = new Course();
course2.setName("java");
course2.setDescription("java就是如此之牛逼");
Set<Course> courses = new HashSet<>();
courses.add(course1);
courses.add(course2);
student.setCourses(courses);
session.save(student);
tx.commit();
}
//解除课程1和所有学生的关系
@Test
public void testRealseAll(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Course course = (Course) session.get(Course.class,1L);
course.setStudents(null);
tx.commit();
}
/**
* 将学生从课程2转到课程1
*/
@Test
public void testStudentFromCourse2ToCourse1(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
//获取学生
Student student = (Student) session.get(Student.class,1L);
//获取课程1和课程2
Course course1 = (Course) session.get(Course.class,1L);
Course course2 = (Course) session.get(Course.class,2L);
//从学生中解除课程2的关系
student.getCourses().remove(course2);
//将学生转到课程1
student.getCourses().add(course1);
tx.commit();
}
/**
* 删除学生(并解除和课程的关系)
*/
@Test
public void testDeleteStudent(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
//获取学生
Student student = (Student) session.get(Student.class,1L);
session.delete(student);
tx.commit();
}
4 一对一操作
4.1 环境的搭建
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个sessionFactory就代表一个数据库的描述
-->
<session-factory>
<!-- 链接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 链接数据库的密码 -->
<property name="connection.password">root</property>
<!-- 链接数据库的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 链接数据库的url -->
<property name="connection.url">
jdbc:mysql://47.93.11.136:3306/hibernate
</property>
<!--
方言
告诉hibernate用什么样的数据库,将来会生成什么样的sql语句
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
hibernate对表的策略
validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表
create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表
create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表
update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示sql语句
-->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="current_session_context_class">thread</property>
<mapping resource="com/xuweiwei/vo/Person.hbm.xml"/>
<mapping resource="com/xuweiwei/vo/Identification.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.xuweiwei.vo;
import java.io.Serializable;
import java.util.Set;
/**
* 人
*/
public class Person implements Serializable {
private Long pid;
private String name;
private String sex;
private Set<Identification> identifications;
public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Set<Identification> getIdentifications() {
return identifications;
}
public void setIdentifications(Set<Identification> identifications) {
this.identifications = identifications;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Person">
<id name="pid">
<generator class="native"/>
</id>
<property name="name"/>
<property name="sex"/>
<set name="identifications" cascade="save-update">
<key column="pid"/>
<one-to-many class="com.xuweiwei.vo.Identification"/>
</set>
</class>
</hibernate-mapping>
package com.xuweiwei.vo;
/**
* 身份证
*/
public class Identification {
private Long iid;
private String name;
private Person person;
public Long getIid() {
return iid;
}
public void setIid(Long iid) {
this.iid = iid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Identification">
<id name="iid">
<generator class="native"/>
</id>
<property name="name"/>
<!--
unique外键唯一约束
-->
<many-to-one name="person" class="com.xuweiwei.vo.Person" unique="true" column="pid"/>
</class>
</hibernate-mapping>
4.2 一对一的操作
@Test
public void savePersonAndIdentification(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Person p = new Person();
p.setName("许威威");
p.setSex("男");
Identification identification = new Identification();
identification.setName("许威威的身份证");
Set<Identification> identifications = new HashSet<>();
identifications.add(identification);
p.setIdentifications(identifications);
session.save(p);
tx.commit();
}
5 二级缓存
5.1 二级缓存的数据特点
- 公共的数据
- 不经常修改的数据
- 私密性不是很高的数据
5.2 二级缓存的生命周期
- 二级缓存的生命周期和SessionFactory紧密关联,当Hibernate容器启动的时候,二级缓存开始启动,当Hiberante容器卸载的时候,二级缓存停止。
5.3 二级缓存的分类(根据位置区分)
5.4 Hibernate开启二级缓存的步骤
- Hibernate内部没有实现二级缓存,使用的是第三方缓存,所以需要配置
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!--
一个sessionFactory就代表一个数据库的描述
-->
<session-factory>
<!-- 链接数据库的用户名 -->
<property name="connection.username">root</property>
<!-- 链接数据库的密码 -->
<property name="connection.password">root</property>
<!-- 链接数据库的驱动 -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 链接数据库的url -->
<property name="connection.url">
jdbc:mysql://47.93.11.136:3306/hibernate
</property>
<!--
方言
告诉hibernate用什么样的数据库,将来会生成什么样的sql语句
-->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<!--
hibernate对表的策略
validate 在hibernate容器启动的时候,根据映射文件和持久化类校验表
create 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表
create-drop 每次当hibernate启动的时候,都会根据持久化类和映射文件创建表,销毁的时候删除表
update 检查,如果和映射文件不一致,则更新表的结构,如果没有表,则会创建表
-->
<property name="hbm2ddl.auto">update</property>
<!--
显示sql语句
-->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="current_session_context_class">thread</property>
<mapping resource="com/xuweiwei/vo/Classes.hbm.xml"/>
<mapping resource="com/xuweiwei/vo/Student.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package com.xuweiwei.vo;
import java.io.Serializable;
import java.util.Set;
/**
* 班级
*/
public class Classes implements Serializable{
private Long cid;
private String name;
private String description;
private Set<Student> students ;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Classes">
<id name="cid">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="description"/>
<set name="students">
<key>
<column name="cid"/>
</key>
<one-to-many class="com.xuweiwei.vo.Student"></one-to-many>
</set>
</class>
</hibernate-mapping>
package com.xuweiwei.vo;
import java.io.Serializable;
/**
* 学生
*/
public class Student implements Serializable{
private Long sid;
private String name;
private String description;
private Classes classes;
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Classes getClasses() {
return classes;
}
public void setClasses(Classes classes) {
this.classes = classes;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Student">
<id name="sid">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="description"/>
<many-to-one name="classes" column="cid" class="com.xuweiwei.vo.Classes"/>
</class>
</hibernate-mapping>
- 步骤:
- ①在hibernate.cfg.xml中配置二级缓存的供应商
<!--
提供二级缓存的供应商
-->
<property name="cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
- ②在hibernate.cfg.xml中开启二级缓存
<!--
开启二级缓存
-->
<property name="cache.use_second_level_cache">true</property>
- ③
- 开启类级别的二级缓存
- 在hibernate.cfg.xml中配置(不推荐)
<!--
开启类级别的二级缓存
usage,开启二级缓存的策略
read-only 只读,把一个对象放入到二级缓存中不可以修改
read-write 读写 把一个对象放入到二级缓存中可以修改
class:类的全名
-->
<class-cache class="com.xuweiwei.vo.Classes" usage="read-only"/>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Classes">
<cache usage="read-only"/>
<id name="cid">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="description"/>
<set name="students">
<key>
<column name="cid"/>
</key>
<one-to-many class="com.xuweiwei.vo.Student"></one-to-many>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xuweiwei.vo.Classes">
<id name="cid">
<generator class="increment"/>
</id>
<property name="name"/>
<property name="description"/>
<set name="students" cascade="save-update">
<cache usage="read-only"/>
<key>
<column name="cid"/>
</key>
<one-to-many class="com.xuweiwei.vo.Student"></one-to-many>
</set>
</class>
</hibernate-mapping>
/**
* 先从一级缓存中查找数据,再从二级缓存中查找数据,最后从数据库中查找数据,然后将数据放入到一级缓存和二级缓存
*/
@Test
public void testGet(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Classes classes1 = (Classes) session.get(Classes.class,1L);
session.close();//一级缓存的数据没有了
session = sessionFactory.openSession();
Classes classes2 = (Classes) session.get(Classes.class,1L);//没有发出SQL语句
session.close();
}
- 在二级缓存的缓存策略是read-only的情况下,如果你修改数据,会报错
@Test
public void testGet(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Classes classes1 = (Classes) session.get(Classes.class,1L);
classes1.setDescription("aa");
tx.commit();
session.close();
}
@Test
public void testCollection(){
Configuration configuration = new Configuration().configure();
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Classes classes1 = (Classes) session.get(Classes.class,1L);
Set<Student> students = classes1.getStudents();
for(Student s:students){
System.out.println(s.getName()+":"+s.getDescription());
}
System.out.println(sessionFactory.getStatistics().getCollectionLoadCount());
tx.commit();
session.close();
}
5.5 将二级缓存保存到磁盘上
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="e:\\TEMP1"/>
<defaultCache
maxElementsInMemory="12"
eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200"
overflowToDisk="false"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<Cache
name="com.xuweiwei.vo.Classes"
maxElementsInMemory="3"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
</ehcache>