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获得了一块 ...
随机推荐
- 14、ABPZero系列教程之拼多多卖家工具 新建微信公众号模块
说是模块,其实在MVC中就是区域,新建一个区域专门管理整个微信功能. Web项目新建区域 在Web项目Areas目录下新建一个区域,名称为“Weixin",如下图: 接着打开web.conf ...
- MySQL(九)之数据表的查询详解(SELECT语法)一
这一篇是MySQL中的重点也是相对于MySQL中比较难得地方,个人觉得要好好的去归类,并多去练一下题目.MySQL的查询也是在笔试中必有的题目.希望我的这篇博客能帮助到大家! 重感冒下的我,很难受!k ...
- Codechef:Path Triples On Tree
Path Triples On Tree 题意是求树上都不相交或者都相交的路径三元组数量. 发现blog里没什么树形dp题,也没有cc题,所以来丢一道cc上的树形dp题. 比较暴力,比较恶心 #inc ...
- Codeforces Round #408 (Div. 2)(A.水,B,模拟)
A. Buying A House time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...
- Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)
A. Lucky Year time limit per test:1 second memory limit per test:256 megabytes input:standard input ...
- [51nod1709]复杂度分析
给出一棵n个点的树(以1号点为根),定义dep[i]为点i到根路径上点的个数.众所周知,树上最近公共祖先问题可以用倍增算法解决.现在我们需要算出这个算法精确的复杂度.我们定义计算点i和点j最近公共组先 ...
- 重新学习一次javascript;
每次有项目的时候,总觉得自己什么都不会做,然后做的时候又很简单,一会就做完了,啪啪打脸: 每次别人问的时候,我知道怎么做,但是不知道具体原理,觉得瞬间low了: 想要好好的吧基础掌握一下: 这几天空闲 ...
- 启动redis
方法一:默认是前端启动 默认端口:6379 cd /usr/local/redis/bin/redis-server 方法二:后端启动 方法二:后端启动 然后进入 指定配置文件 [roo ...
- 三分钟使用webpack-dev-sever搭建一个服务器
webpack-dev-server是一个小型的Node.js Express服务器,我们可以通过它搭建一个本地服务器,并且实现文件热更新; 1.切换到你的目录下对项目进行初始化 npm init 一 ...
- POJ 3278 Catch That Cow(模板——BFS)
题目链接:http://poj.org/problem?id=3278 Description Farmer John has been informed of the location of a f ...