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 (三)的更多相关文章

  1. 简单理解Hibernate三种状态的概念及互相转化

    本文描述了Hibernate三种状态的概念及互相转化.Java对象的生命周期中有三种状态,而且互相转化.它们分别是临时状态,持久化状态,以及游离状态. AD:WOT2015 互联网运维与开发者大会 热 ...

  2. [转]hibernate三种状态详解

    本文来自 http://blog.sina.com.cn/u/2924525911 hibernate 三种状态详解 (2013-04-15 21:24:23) 转载▼   分类: hibernate ...

  3. hibernate三种状态

    转自:http://www.cnblogs.com/xiaoluo501395377/p/3380270.html 学过hibernate的人都可能都知道hibernate有三种状态,transien ...

  4. hibernate(三) 一对多映射关系

    序言 前面两节讲了hibernate的两个配置文件和hello world!.还有hibernate的一级缓存和三种状态,基本上hibernate就懂一点了,从这章起开始一个很重要的知识点,hiber ...

  5. Hibernate三种状态的转换

    hibernate的状态 hibernate的各种保存方式的区(save,persist,update,saveOrUpdte,merge,flush,lock)及 对象的三种状态 hibernate ...

  6. Hibernate三种状态的区分,以及save,update,saveOrUpdate,merge等的使用 引自http://www.blogjava.net/TiGERTiAN/archive/2008/10/25/236519.html

    Hibernate的对象有3种状态,分别为:瞬时态(Transient). 持久态(Persistent).脱管态(Detached).处于持久态的对象也称为PO(Persistence Object ...

  7. Hibernate(三)——框架中的关系映射

    在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系.而Hibernate时间实体类和数据库中的表进行的映射, ...

  8. hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  9. SSH框架之-hibernate 三种状态的转换

    一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...

  10. Hibernate三种状态,缓存,以及update更新问题

    一. Hibernate中对象的三种状态 1. 瞬时状态(transient) 当我们通过Java的new关键字来生成一个实体对象时,这时这个实体对象就处于自由状态,此时该对象只是通过JVM获得了一块 ...

随机推荐

  1. 2017 年的 人生 hard 模式终于结束了,2018年回归初心(二)

    今天周末, 深圳的天气简直好的不像话.好了,我们继续之前的话题往下聊. >>>猎头 : 关于猎头这个行业,以笔者的感觉来说 一般你工作年限未超过三年的话,你是很难遇到猎头来推送你的简 ...

  2. python 单下划线/双下划线使用总结

    文章转自:http://blog.csdn.net/pfm685757/article/details/45918575

  3. 初入python 用户输入,if,(while 循环)

    python 基础 编译型: 一次性将所有程序编译成二进制文件. 缺点:开发效率低,不能跨平台 优点:运行速度快. :c ,c++语言 等等.... 解释行:当程序执行时,一行一行的解释. 优点:开发 ...

  4. kafka Topic 与 Partition

    Topic在逻辑上可以被认为是一个queue队列,每条消息都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里.为 了使得Kafka的吞吐率可以水平扩展,物理上把topic分 ...

  5. Codefoces 723A The New Year: Meeting Friends

    A. The New Year: Meeting Friends time limit per test:1 second memory limit per test:256 megabytes in ...

  6. hackerrank DFS Edges

    瞬间移动 题意:要求构造一个图,使其dfs树中有t条树边,b条返祖边,f条前向边,c条其他边. 膜了题解才会,好神啊. 考虑所有结点的深度之和,这个值必须介于$[max(b,f+t),C^{2}_{n ...

  7. [51nod1443]路径和树

    给定一幅无向带权连通图G = (V, E) (这里V是点集,E是边集).从点u开始的最短路径树是这样一幅图G1 = (V, E1),其中E1是E的子集,并且在G1中,u到所有其它点的最短路径与他在G中 ...

  8. UESTC1599-wtmsb-优先队列

    wtmsb Time Limit: 1000/100MS (Java/Others) Memory Limit: 131072/131072KB (Java/Others) 这天,AutSky_Jad ...

  9. Codeforces Round #280 (Div. 2)_C. Vanya and Exams

    C. Vanya and Exams time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  10. 二 @ResponseBody用法

    @ResponseBody底层是通过response.getwriter()方法将数据写回前 台 @ResponseBody @RequestMapping (value="/queryLi ...