Hibernate
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)
Hibernate CriteriaQuery where - ManyToOne 字段
Hibernate + MySQL:如何为数据库和表设置编码 utf-8
hibernate在使用getCurrentSession时提示no session found for current thread