Hibernate (三)
1 一对多的单向
- 示例:一个已经存在的学生,新建一个班级,然后将该学生加入到该班级之下
- 设置inverse="false"
<?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 一对多的双向
- Student.java
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;
}
}
- Student.hbm.xml
<?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>
- Classes.hbm.xml
<?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多对多的环境
- hibernate.cfg.xml
<?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>
- Student.java
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;
}
}
- Student.hbm.xml
<?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>
- Course.java
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;
}
}
- Course.hbm.xml
<?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和所有学生的关系
//解除课程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
/**
* 将学生从课程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 环境的搭建
- hiberante.cfg.xml
<?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>
- Person.java
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;
}
}
- Person.hbm.xml
<?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>
- Identification.java
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;
}
}
- Identification.hbm.xml
<?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内部没有实现二级缓存,使用的是第三方缓存,所以需要配置
- 环境:班级和学生
- hibernate.cfg.xml
<?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>
- Classes.java
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;
}
}
- Classes.hbm.xml
<?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>
- Student.java
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;
}
}
- Student.hbm.xml
<?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>
- 开启集合级别的二级缓存
- 在<set>元素下配置
- 开启集合级别的二级缓存
<?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 将二级缓存保存到磁盘上
- 在src下配置ehcache.xml
<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>
Hibernate (三)的更多相关文章
- 简单理解Hibernate三种状态的概念及互相转化
本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...
- [转]hibernate三种状态详解
本文来自 http://blog.sina.com.cn/u/2924525911 hibernate 三种状态详解 (2013-04-15 21:24:23) 转载▼ 分类: hibernate ...
- hibernate三种状态
转自:http://www.cnblogs.com/xiaoluo501395377/p/3380270.html 学过hibernate的人都可能都知道hibernate有三种状态,transien ...
- hibernate(三) 一对多映射关系
序言 前面两节讲了hibernate的两个配置文件和hello world!.还有hibernate的一级缓存和三种状态,基本上hibernate就懂一点了,从这章起开始一个很重要的知识点,hiber ...
- Hibernate三种状态的转换
hibernate的状态 hibernate的各种保存方式的区(save,persist,update,saveOrUpdte,merge,flush,lock)及 对象的三种状态 hibernate ...
- Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用 引自http://www.blogjava.net/TiGERTiAN/archive/2008/10/25/236519.html
Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...
- Hibernate(三)——框架中的关系映射
在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...
- hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- SSH框架之-hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- Hibernate三种状态,缓存,以及update更新问题
一. Hibernate中对象的三种状态 1. 瞬时状态(transient) 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象就处于自由状态,此时该对象只是通过JVM获得了一块 ...
随机推荐
- vs2008中xlslib与libxls库的编译及使用
C++用来操作Excel的方法很多,但是涉及到跨平台,同时又要对Excel的读写操作兼顾,而且免费的库,那应该是要用xlslib和libxls了.由于技术比较菜,折腾这个折腾了一个星期了.最开始是使用 ...
- win10 uwp 横向 AppBarButton
一般看到的 AppBarButton 都是图片在上面,文字在下面,是否可以更改让文字在和图片相同的位置?本文告诉大家如何做出横向的 AppBarButton 把图标和文本放在一起. 如果需要添加 Ap ...
- C# Split 字符文本中的字符太多
问题: ] { '<h1>', '</h1>' }); 原因: Split()里面是用char类型不是string字符串类型,所以只能用一个字符,必须先把多个字符替换成一个字符 ...
- 线程池的使用及ThreadPoolExecutor的分析(一)
说明:本作者是文章的原创作者,转载请注明出处:本文地址:http://www.cnblogs.com/qm-article/p/7821602.html 一.线程池的介绍 在开发中,频繁的创建和销毁一 ...
- OI回忆录——一个过气OIer的智障历程
初中 初一参加学校信息学选修课,一周一节课,学pascal. 初一寒假(大约是)入选(其实是钦定吧)当时加上我只有3人的校队(我当然是最弱的一个. 当时甚至有幸得到叉姐授课(现在才知道这是多么难得的机 ...
- HDU 2503 a/b + c/d(最大公约数与最小公倍数,板子题)
话不多说,日常一水题,水水更健康!┗|`O′|┛ 嗷~~ a/b + c/d Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768 ...
- NowCoder牛客练习赛7-A.骰子的游戏 B.购物-优先队列
A.骰⼦的游戏 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K64bit IO Format: %lld 题目描述 在Alice和Bob面前的是两个骰 ...
- 互联网App应用程序测试流程及测试总结
互联网App应用程序测试流程及测试总结 1. APP测试基本流程 1.1流程图 仍然为测试环境 Pass 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日 ...
- 如何初始化grunt
为什么使用任务运行工具Grunt -- 官方解释 简而言之,自动化.当你处理诸如代码最小化, 代码编译, 单元测试, 代码规范校验等等重复任务时, 你必须要做的工作越少,你的工作就变得越简单.在你完成 ...
- Web前端:如何实现选择select下拉框选中跳转其他页面
<select onchange="window.location=this.value;"><option value="a.html"&g ...