Hibernate-学习笔记汇总

Hibernate-学习笔记汇总

一、入门

1.概念:hibernate 是一个数据库持久层框架,解决的是数据库CRUD的问题。
2.需要的jar包

​ 2.1 Hibernate核心jar包

​ 2.2 Hibernate第三方依赖

​ 2.3 数据库驱动jar如 ojdbc6.jar mysql.jar

​ 2.3 maven依赖

 <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!-- 添加Hibernate依赖 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.6.10.Final</version>
        </dependency>

        <!-- 添加Log4J依赖 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-nop</artifactId>
            <version>1.6.4</version>
        </dependency>

        <!-- 添加javassist -->
        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.0.GA</version>
        </dependency>

        <!-- mysql数据库的驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>

    </dependencies>
3.Hibernate配置文件

​ 3.1 hibernate.cfg.xml 核心配置文件

属性说明
dialect方言,告知hibernate连接的是哪种数据库
show_sqltrue/false

​ 3.2xxx.hbm.xml 映射文件,文件名以.hbm.xml结尾

4.Hibernate核心对象

​ 4.1 Configuration,读取 hibernate 相关配置文件

​ 4.2 SessionFactory,创建 session 对象

​ 4.3 Session,内部封装了 Connection,负责对数据做CRUD操作

​ 4.4 Transaction 事务

// hibernate增删改查需要手动控制事务
tx.begin();
tx.commit();
tx.rollback();
5.Query查询,复杂查询,涉及HQL,后续会有篇章描述
6.开发步骤:

​ 6.1 O 实体对象

​ 6.2 R 创建数据库中的表

​ 6.3 M 映射文件

​ 6.4 映射文件注册到 hibernate.cfg.xml 核心配置文件中

​ 6.5 API 测试

7.代码示例
7.1 POJO对象
/**
 * @author jyc
 * @date 2022/9/3 20:41
 */

package com.jyc;

import java.util.Date;

public class Person {
    private Integer id;
    private String name;
    private double salary;
    private Date birthday;
}
7.2 创表语句
CREATE TABLE s_PERSON(
	s_ID int primary key auto_increment,
	s_name varchar(50),
	s_salary double(12,2),
	s_birthday date
)
7.3 Person对象的配置文件 person-hnm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="com.jyc.Person" table="s_person">
        <id name="id" column="s_id" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="name" column="s_name" type="java.lang.String"></property>
        <property name="salary" column="s_salary" type="java.lang.Double"></property>
        <property name="birthday" column="s_birthday" type="java.util.Date"></property>
    </class>

</hibernate-mapping>
7.4 hibernate.cfg.xml 配置文件
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory name="foo">
		<!-- 数据库连接参数 -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=utf-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">1234</property>

		<!--	hibernate相关参数	-->
		<property name="show_sql">true</property>
		<property name="format_sql">false</property>
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 注册映射文件 -->
		<mapping resource="person-hnm.xml"/>

	</session-factory>

</hibernate-configuration>
7.5 注册映射文件到 hibernate-cfg.xml
7.6 API测试

​ 7.6.1 插入

 /**
     * 用于测试插入
     */
    @Test
    public void testInert(){

        Person person = new Person();
        person.setName("JC");
        person.setSalary(999999);
        person.setBirthday(new Date());

        Configuration cfg = new Configuration();
        // 读取配置文件
        cfg.configure();
        // 构建sessionFactory
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        // 构建session
        Session session = sessionFactory.openSession();

        Transaction tx = session.getTransaction();

        tx.begin();
        session.save(person);
        tx.commit();

    }

​ 7.6.2 查询

 /**
     * 用于测试查询
     */
    @Test
    public void testGet(){

        Configuration cfg = new Configuration();
        // 读取配置文件
        cfg.configure();
        // 构建sessionFactory
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        // 构建session
        Session session = sessionFactory.openSession();

        Person dbPerson = (Person)session.get(Person.class, 1);
        System.out.println("dbPerson = " + dbPerson);
    }

​ 7.6.3 更新

  /**
     * 用于测试更新
     */
    @Test
    public void testUpdate(){
        Configuration cfg = new Configuration();
        // 读取配置文件
        cfg.configure();
        // 构建sessionFactory
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        // 构建session
        Session session = sessionFactory.openSession();

        Transaction tx = session.getTransaction();
        tx.begin();

        Person dbPerson = (Person)session.get(Person.class, 1);
        System.out.println("dbPerson = " + dbPerson);

        dbPerson.setSalary(66666);
        dbPerson.setName("jc");

        session.update(dbPerson);

        tx.commit();
    }

​ 7.6.4 删除

  /**
     * 用于测试删除
     */
    @Test
    public void testDelete(){
        Configuration cfg = new Configuration();
        // 读取配置文件
        cfg.configure();
        // 构建sessionFactory
        SessionFactory sessionFactory = cfg.buildSessionFactory();
        // 构建session
        Session session = sessionFactory.openSession();

        Transaction tx = session.getTransaction();
        tx.begin();

        Person person = new Person();
        person.setId(1);
        session.delete(person);

        tx.commit();
    }
8.提示

​ 8.1 hibernate方言位置

在这里插入图片描述

​ 8.2 为什么不需要输入 hibernate.cfg.xml 的文件路径?

在这里插入图片描述

二、封装HibernateUtil

1.HibernateUtil 的工具类
/**
 * @author 贾宇超
 * @date 2022/9/3 23:57
 */

package com.jyc;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
    private static SessionFactory sessionFactory = null;
    static {
        Configuration cfg = new Configuration();
        // 读取配置文件
        cfg.configure();
        // 构建sessionFactory
        sessionFactory = cfg.buildSessionFactory();
    }

    public static Session getCurrentSession(){
        return sessionFactory.getCurrentSession();
    }
}
2.SessionFactory.getCurrentSession()
方法说明
SessionFactory.openSession()每一次调用都会创建新的session
SessionFactory.getCurrentSession()会把创建好的session放到ThreadLoacl中,保证一个线程用同一个session

getCurrentSession()注意事项:

​ 2.1 必须在hibernate.cfg.xml中配置

​ 2.2 必须运行在事务中,查询也不例外。

​ 2.3 事务结束后会自动关闭

3.getCurrentSession()hibernate.cfg.xml中的配置
<!--	getCurrentSession在 hibernate.cfg.xml 的配置	-->
<property name="current_session_context_class">thread</property>

三、应用注解(Annotation)替换 映射文件

1.创建实体对象
/**
 * @author jyc
 * @date 2022/9/3 20:41
 */

package com.jyc;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "t_user")
public class Student {
    @Id
    @GenericGenerator(name="student_id",strategy = "increment")
    @GeneratedValue(generator = "student_id")
    @Column(name = "t_id")
    private Integer id;
    @Column(name = "t_name")
    private String name;
    @Column(name = "t_age")
    private Integer age;
    @Column(name = "t_bir")
    private Date bir;
}
2.创建表
CREATE TABLE t_user(
	t_ID int primary key auto_increment,
	t_name varchar(50),
	t_age int(3),
	t_bir date
)
3.注册类文件到 hibernate.cfg.xml
<mapping class="com.jyc.Student"/>

四、hibernate 关联关系映射

1.一对一
1.1 实体对象

​ 1.1.1 存有外键的主体

​ 核心注解

@OneToOne

@JoinColumn(name="department_id")

@Cascade(CascadeType.ALL)

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GenericGenerator(name="employee_pk",strategy = "increment")
    @GeneratedValue(generator = "employee_pk" )
    @Column(name = "id")
    private Integer id;
    @Column
    private String username;
    @Column
    private Double salary ;
    @Column
    private Integer age;

    @OneToOne   // 关系属性注解
    @JoinColumn(name="department_id")
    // 关于外键注解
    @Cascade(CascadeType.ALL)
    private  Department department;
1.1.1 另一个 一

​ 核心注解 @OneToOne(mappedBy = "department")

​ 注意:department 依赖于 Persion 对象中 的 department 属性

@Entity
@Table(name = "department")
public class Department {
    @Id
    @GenericGenerator(name="department_pk",strategy = "increment")
    @GeneratedValue(generator = "department_pk" )
    @Column(name = "id")
    private Integer id;
    @Column
    private String department_name;
    @Column
    private Integer department_id ;
    @Column
    private String note;

    @OneToOne(mappedBy = "department")
    private Employee employee;
1.2 表
CREATE TABLE department(
	ID int(6) primary key auto_increment,
	DEPARTMENT_NAME varchar(50),
	DEPARTMENT_ID int(6),
	NOTE varchar(100) 
);
INSERT INTO `department` VALUES (101, '研发部', 100, NULL);
INSERT INTO `department` VALUES (102, '公关部', 110, NULL);
INSERT INTO `department` VALUES (103, '宣策部', 120, NULL);
INSERT INTO `department` VALUES (104, '礼仪部', 130, NULL);


CREATE TABLE employee(
	ID int(6) primary key auto_increment,
	USERNAME varchar(50),
	SALARY double(8, 2),
	AGE int(3),
	DEPARTMENT_ID int(6)
);

INSERT INTO `employee` VALUES (110, 'John111', 8200.00, 50, 101);
INSERT INTO `employee` VALUES (111, 'Ismael', 7700.00, 40, 103);
INSERT INTO `employee` VALUES (112, 'Jose Manuel', 7800.00, 30,102);
INSERT INTO `employee` VALUES (113, 'Luis111', 6900.00, 20, 103);
INSERT INTO `employee` VALUES (114, 'Den', 11000.00, 18, 101);
INSERT INTO `employee` VALUES (115, 'Alexander11', 3100.00, 15, 101);
INSERT INTO `employee` VALUES (116, 'Shelli', 2900.00, 24, 104);
1.3 注册实体类到 hibernate.cfg.xml
<mapping class="com.jyc.Department"/>
<mapping class="com.jyc.Employee"/>
1.4 api测试
1.5 注意

​ toString()方法,两个依赖对象不要互相调用,不然会报错:栈溢出,stackOverFlow

2. 一对多

​ 注意:如果关系属性为集合,则必须声明为集合的接口类型,并进行初始化,记得提供get() set() 方法

2.1 实体

​ 2.1.1 单向关系a 一个部门中的所有员工

​ 2.1.1.1 一,部门

​ 核心注解 @OneToMany

@Entity
@Table(name = "department")
public class Department {
    @Id
    @GenericGenerator(name="department_pk",strategy = "increment")
    @GeneratedValue(generator = "department_pk" )
    @Column(name = "d_id")
    private Integer id;
    @Column
    private String department_name;
    @Column
    private Integer department_id ;
    @Column
    private String note;

    @OneToMany
    @JoinColumn(name = "d_id")
    @Cascade(CascadeType.ALL)
    private Set<Employee> employee;

​ 2.1.1.2 多,员工

​ 新增日期注解 @Temporal(TemporalType.DATE)

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GenericGenerator(name="employee_pk",strategy = "increment")
    @GeneratedValue(generator = "employee_pk" )
    @Column(name = "id")
    private Integer id;
    @Column
    private String username;
    @Column
    private Double salary ;
    @Column
    private Integer age;
    @Temporal(TemporalType.DATE)
    private Date bir;

2.1.2 单向关系b 显示员工及部门信息

​ 2.1.2.1 部门

  @Id
    @GenericGenerator(name="department_pk",strategy = "increment")
    @GeneratedValue(generator = "department_pk" )
    @Column(name = "d_id")
    private Integer id;
    @Column
    private String department_name;
    @Column
    private Integer department_id ;
    @Column
    private String note;

​ 2.1.2.1 员工

​ 核心注解

@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GenericGenerator(name="employee_pk",strategy = "increment")
    @GeneratedValue(generator = "employee_pk" )
    @Column(name = "id")
    private Integer id;
    @Column
    private String username;
    @Column
    private Double salary ;
    @Column
    private Integer age;
    @Temporal(TemporalType.DATE)
    private Date bir;

    @ManyToOne
    @JoinColumn(name="d_id")
    @Cascade(CascadeType.ALL)
    private Department department;

2.1.3 双向关系b 既想看员工属于哪个部门,又想看哪个部门有多少员工

​ 2.1.2.1 部门

​ 核心注解 @OneToMany(mappedBy = "department")


@Entity
@Table(name = "department")
public class Department {
    @Id
    @GenericGenerator(name="department_pk",strategy = "increment")
    @GeneratedValue(generator = "department_pk" )
    @Column(name = "d_id")
    private Integer id;
    @Column
    private String department_name;
    @Column
    private Integer department_id ;
    @Column
    private String note;

    @OneToMany(mappedBy = "department")
    @Cascade(CascadeType.ALL)
    private Set<Employee> employees = new HashSet<>();

​ 2.1.2.1 员工

​ 核心注解


@Entity
@Table(name = "employee")
public class Employee {
    @Id
    @GenericGenerator(name="employee_pk",strategy = "increment")
    @GeneratedValue(generator = "employee_pk" )
    @Column(name = "id")
    private Integer id;
    @Column
    private String username;
    @Column
    private Double salary ;
    @Column
    private Integer age;
    @Temporal(TemporalType.DATE)
    private Date bir;

    @ManyToOne
    @JoinColumn(name="d_id")
    @Cascade(CascadeType.ALL)
    private Department department;
1.2 表 (与第一套表的区别是:新增了Date属性bir) 修改了字段名d_id
CREATE TABLE department(
	d_ID int(6) primary key auto_increment,
	DEPARTMENT_NAME varchar(50),
	DEPARTMENT_ID int(6),
	NOTE varchar(100) 
);
INSERT INTO `department` VALUES (100, '研发部', 100, NULL);
INSERT INTO `department` VALUES (101, '公关部', 110, NULL);
INSERT INTO `department` VALUES (102, '宣策部', 120, NULL);
INSERT INTO `department` VALUES (103, '礼仪部', 130, NULL);

CREATE TABLE employee(
	ID int(6) primary key auto_increment,
	USERNAME varchar(50),
	SALARY double(8, 2),
	AGE int(3),
	d_id int(6),
	BIR date
);

INSERT INTO `employee` VALUES (110, 'John111', 8200.00, 50, 101,SYSDATE());
INSERT INTO `employee` VALUES (111, 'Ismael', 7700.00, 40, 103,SYSDATE());
INSERT INTO `employee` VALUES (112, 'Jose Manuel', 7800.00, 30,102,SYSDATE());
INSERT INTO `employee` VALUES (113, 'Luis111', 6900.00, 20, 103,SYSDATE());
INSERT INTO `employee` VALUES (114, 'Den', 11000.00, 18, 101,SYSDATE());
INSERT INTO `employee` VALUES (115, 'Alexander11', 3100.00, 15, 101,SYSDATE());
INSERT INTO `employee` VALUES (116, 'Shelli', 2900.00, 24, 104,SYSDATE());

1.3 注册
<mapping class="com.jyc.Department"/>
<mapping class="com.jyc.Employee"/>
3.多对多
3.0 注意:双向关系的注解位置可以互换。
3.1 实体

​ 3.1.1 学生

​ 核心注解:@ManyToMany @JoinTable

@Entity
@Table(name = "student")
public class Student {
    @Id
    @GenericGenerator(name="student_id",strategy = "increment")
    @GeneratedValue(generator = "student_id")
    @Column
    private Integer id;
    @Column
    private String name;
    @Column
    private Integer age;

    @ManyToMany
    @JoinTable(name="t_s_c",
               joinColumns = {@JoinColumn(name = "s_id")},
               inverseJoinColumns = {@JoinColumn(name = "c_id")})
    @Cascade(CascadeType.ALL)
    private Set<Course> courses = new HashSet<>();

}

​ 3.1.2 课程


@Entity
@Table(name = "course")
public class Course {

    @Id
    @GenericGenerator(name="course_pk",strategy = "increment")
    @GeneratedValue(generator = "course_pk")
    private Integer id;

    @Column
    private String name;
    @Column
    private Integer score;

    @ManyToMany(mappedBy = "courses")
    @Cascade(CascadeType.ALL)
    private Set<Student> students = new HashSet<>();
}
3.2 表
CREATE TABLE Student(
	ID int primary key auto_increment,
	name varchar(50),
	age int(3)
)
insert into student values(1,'张三',19);
insert into student values(2,'李四',18);
insert into student values(3,'王五',21);

CREATE TABLE course(
	ID int primary key auto_increment,
	name varchar(50),
	score int(2)
)

insert into  course values(1,'spring',6);
insert into  course values(2,'struts2',3);
insert into  course values(3,'springmvc',4);
insert into  course values(4,'hibernate',2);

CREATE TABLE t_s_c(
	ID int primary key auto_increment,
	c_id int,
	s_id int
)

insert into  t_s_c values(1,1,1);
insert into  t_s_c values(2,1,2);
insert into  t_s_c values(3,1,3);

insert into  t_s_c values(4,2,1);
insert into  t_s_c values(5,3,1);
insert into  t_s_c values(6,4,1);
3.3 注册
<mapping class="com.jyc.Student"/>
<mapping class="com.jyc.Course"/>
3.4 API测试

​ 3.4.1 一个课程被多个学生选择

 /**
     * 用于测试 多对多 课程被多个学生选择
     */
    @Test
    public void testManyAndManyByCourse(){
        org.hibernate.Session currentSession = HibernateUtils.getCurrentSession();
        Transaction transaction = currentSession.getTransaction();

        transaction.begin();

        Course course = (Course)currentSession.get(Course.class, 1);

        Set<Student> students = course.getStudents();
        students.forEach( student -> {
            System.out.println("student = " + student);
        });

        System.out.println("course = " + course);

        transaction.commit();

    }

​ 3.4.1 一个学生选择多个课程


    /**
     * 用于测试 多对多 学生选择了多少课程
     */
    @Test
    public void testManyAndManyByStudent(){
        org.hibernate.Session currentSession = HibernateUtils.getCurrentSession();
        Transaction transaction = currentSession.getTransaction();

        transaction.begin();

        Student student = (Student)currentSession.get(Student.class, 1);

        Set<Course> courses = student.getCourses();
        courses.forEach(course -> {
            System.out.println("course = " + course);
        });

        System.out.println("student = " + student);


        transaction.commit();

    }

​ 3.4.1 多个学生选择多个课程

 /**
     * 用于测试 多对多 学生选择了多少课程
     */
    @Test
    public void testManyAndManyByStudentByList(){
        org.hibernate.Session currentSession = HibernateUtils.getCurrentSession();
        Transaction transaction = currentSession.getTransaction();

        transaction.begin();

        Query query = currentSession.createQuery(" from Student ");
        List<Student> students = query.list();


        students.forEach( student -> {
            System.out.println("student = " + student);
            Set<Course> courses = student.getCourses();
            courses.forEach(course -> {
                System.out.println("course = " + course);
            });

            System.out.println("");
        } );


        transaction.commit();
    }

五、主键生成器 Generator

前提:主键生成器的注解必须应用在ID属性之上,也就是自然主键(唯一且无业务含义)。

使用

@GenericGenerator(name="course_pk",strategy = "increment")

@GeneratedValue(generator = "course_pk")

类型特点注意
increment查询当前表ID的最大值+1作为新纪录的主键多线程访问,或者分布式系统,未添加分布式锁解决方案,会产生主键冲突问题
sequence调用数据库的sequence需要数据库支持,如Oracle、DB2、Postgre
strategy=“sequence” 默认调用 hibernate_sequence
注解:strategy = “sequence”,parameters = {@Parameter(name=“sequence”,value=“course_seq”)}
identity支持主键自增长的数据库MySQL、SQLServer
uuid全球唯一的字符串主键无法利用主键索引
assigned手工分配主键生成器

六、JPA 规范与 Hibernate 的关系

1.JAVA Persistence APi 是从JAVAEE5 诞生的一组接口,Hibernate是JPA实现的技术。
2.非JPA注解:

@GenericGenerator

@Cascade

3.JPA提供的替代注解

​ Sequence

​ Identity

七、HQL(Hibernate Query Language)

1.查询所有数据
currentSession.createQuery(" from Student ");
List<Student> students = query.list();
2.查询数据,使用占位符增加查询条件
Query query = currentSession.createQuery(" from Student as s where s.id = ? ");
query.setString(0,"1");
List<Student> students = query.list();
3.查询苏剧,新增查询条件,返回单条记录
Query query = currentSession.createQuery(" from Student as s where s.id = ? ");
query.setString(0,"1");
Student student= (Student)query.uniqueResult();
4.注意:
4.1 HQL类似于SQL语句
4.2 from 后加入类名
4.3 没有 select 子句,封装对象时 select 每一行会封装成一个OBject()
4.4 如果使用列,需要通过 as 定义表别名,通过别名.属性的方式表达
5.HQL多表操作
5.1 隐式多表连接

通过关系属性完成多表操作,看似是一张表的操作,实质是多张表的处理。

存在问题:HQL翻译的SQL语句,执行效率低,特殊的表操作不支持

5.2 显示多表连接

​ 5.1 join关键字

​ 5.2 inner join

​ 5.3 迫切内连接(fetch)

​ 5.3.1 把每一行的查询结果进行封装

​ 5.3.2 SQL:

selecte e.*,d.* from t_employee e  inner join t_department d on e.d_id = d.id

​ 5.3.3 HQL(用的是类和属性):

from Employee as e  inner join fetch e.department

​ 5.4 left join

​ 5.5 out join 右外连接不能加入fetch

​ 5.6 full join 不能书写HQL

八、Hibernate 缓存 Cache

1. Session缓存

同一个session中的同一个查询,只会与数据库交互一次,获取到的内容会存放如session的map对象中作为缓存使用,Map对象的key = pk + 类型 ,value = 对象。

注意:

​ 1.1 必须明确以主键为条件的查询,才可以利用Session缓存

​ 1.2 session.get()方法才可以利用session缓存,HQL不可以

​ 1.3 除了查询(get()、query())外,session的save()、update()、delete()方法操作的实体同样可以保存到session的缓存中。

​ 1.4 清空 session缓存的方式

session.close(); //等价于事务结束
session.clear();
session.evict(entity);
2. Hibernate 的缓存体系

​ 2.1 一级缓存:sesion的缓存,事务级别缓存

​ 2.2 二级缓存:sessionFactory缓存,应用级缓存

3.二级缓存

​ 3.1 二级缓存默认是被hibernate关闭的

​ 3.2 Hibernate 借用第三方缓存框架完成二级缓存的实现。

​ ehcache、oscache、jbosscache、memcache、redis

4.二级缓存的使用步骤

​ 4.1 引入外部二级缓存jar、配置文件

​ 4.2 启动hibernate二级缓存,在 hibernate-cfg.xml中配置

<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

​ 4.3 在需要放置二级缓存的实体上面加入注解,表示它需要放入二级缓存中

​ 4.4 @Cache

​ READ_ONLY 只读策略

​ READ_WRITE 可读可写

注意:

查询缓存的key与HQL,查询参数以及分布参数有关,而且一旦查询涉及到的任何一张表的数据发生了变化,缓存就失效了,所以在生产环境中命中率较低。查询缓存保存的是结果集的id列表,而不是结果集本身 ,命中缓存的时候,会根据id一个一个地先从二级缓存查找 ,找不到再查询数据库。

查询缓存通常是和二级缓存联合使用的。

5.Query_Cache 查询缓存

一级缓存,二级缓存,必须明确地使用主键进行查询

查询缓存 没有必须使用主键的约束,所以主要应用在Quey操作中

<property name="cache.use_query_cache">true</property>
// 查询缓存要想应用成功,必须HQL完全一致。
query.setCacheable(true);
九、Hibernate 对象状态
状态特点
临时(transinet)数据没有存储到数据库
持久化 (persistent)实体的数据存储在了数据库,并且实体纳入了session的缓存
游离状态实体的数据存储在了数据库,并且实体没有纳入session的缓存
十、Hibernate 延迟加载(懒加载 lazy)
类型说明
加载把数据库中的数据,查询到内存中
立即加载调用了对应的查询方法后,hibernate 不管用户需不需要这个数据,
都立即发送sql查询。get()|queyr()
延迟加载当调用了对应的查询方法后,hibernate不会立即发送sql查询语句,只有当用户需要使用数据时,才会查询。
1.一般属性的延迟加载

​ 当调用了session.load()方法后,hibernate 不会立即发送 sql 查询数据,只有当用户第一次使用属性数据时,才会查询。

2.关系属性的延迟加载

调用了查询方法后,hibernate不会立即发送sql查询关系属性数据,只有当用户第一次使用关系属性数据时,才会查询。Hibernate引入延迟加载是为了减少内存的占用。

延迟加载的异常:

org.hibernate.LazyInitializationException: 当延迟加载时,发现 session 已经关闭(等价于事务结束)

解决延迟加载:

#  1.扩大事务边界,把延迟加载的代码,放置在事务的内部。
		​可以把事务扩大到过滤器中
		Spring解决了这个问题OpenSessionInView--->Filter--Spring

# 2.改变延迟加载的默认策略
		关系属性 @OneToMany( fetch=FetchType.EARGE )

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
hibernate-jpa-2.1-api 1.0.2是一个Java持久化规范的实现库。它是基于JPA(Java Persistence API)2.1规范的Hibernate实现。Hibernate是一个流行的ORM(对象关系映射)框架,用于在Java应用程序和关系数据库之间进行数据持久化。 该版本的hibernate-jpa-2.1-api是对JPA 2.1规范的实现,并且是Hibernate团队为了确保应用程序与Java EE 7兼容性而发布的一个版本。 JPA是一种使用对象模型操作数据库的标准规范,它提供了一组API,使开发人员可以使用面向对象的方式访问和操作数据库。Hibernate作为一个JPA的实现,提供了许多附加的功能和特性,使得开发人员可以更加简化和灵活地进行数据库操作。 通过使用hibernate-jpa-2.1-api,开发人员可以使用JPA的标准API,以及Hibernate提供的独有特性,来实现应用程序的数据持久化需求。它提供了实体管理器,用于管理实体对象的生命周期,以及CRUD操作。此外,它还提供了用于查询和各种持久化注解的支持。 通常情况下,使用hibernate-jpa-2.1-api需要将其添加到项目的依赖中,并与其他必需的Hibernate库一起使用。开发人员需要熟悉JPA的基本概念和API,并且理解Hibernate特有的扩展和配置选项。 总的来说,hibernate-jpa-2.1-api 1.0.2提供了开发人员在使用JPA进行数据持久化时的基本工具和功能。它是Hibernate团队为了支持JPA 2.1规范而发布的一个版本,开发人员可以使用它来简化和灵活地操作数据库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值