Hibernate框架笔记02

目录
0. 结构图

1. 持久化类的编写规则

1.1 持久化和持久化类

  • 持久化:将内存中的一个对象持久化到数据库的过程,Hibernate框架就是用来进行持久化的框架。
  • 持久化类:一个Java对象与数据库的表建立了映射关系,那么这个类在Hibernate中称为持久化类。
    • 持久化 = Java类 + 映射文件

1.2 持久化类的编写规则

finalloadget
2. 主键生成策略

2.1 主键的分类

  1. 自然主键:
    • 主键的本身就是表中的一个字段(实体中的一个具体的属性)。
    • 创建一个人员表,人员都会有一个身份证号(唯一不可重复的),使用了身份证号作为主键,这种主键称为是自然主键。
  2. 代理主键:
    • 主键的本身不是表中必须的一个字段(不是实体中的某个具体的属性)
    • 创建一个人员表,没有使用人员中的身份证号,用来一个与这个表不相关的字段ID。这种主键称为代理主键。
  3. 在实际开发中,尽量使用代理主键
    • 一旦自然主键参与到业务逻辑中,后期有可能需要修改源代码
    • 好的程序设计满足OCP原则,对程序的扩展时open的,对修改原阿门时close的。

2.2 主键生成策略

select max(id) from 表;id +1 
3. 持久化类的三种状态【了解】

3.1 持久化类的三种状态

  • Hibernate时持久层框架,通过持久化类完成ORM操作。Hibernate为了更好的管理持久化类,将持久化类分为三种状态。
  • 持久化类 = Java类 + 映射
    1. 瞬时态:这种对象没有唯一的标识OID,没有被session管理,称为瞬时态对象。
    2. 持久态:这种对象有唯一标识OID,被session管理,称为持久态对象。
      • 持久化类的持久态的对象,可以自动更新数据库
    3. 托管态:这种对象有唯一标识OID,没有被session管理,称为托管态对象。

3.2区分三种持久化状态

@Test
//三种状态的区分
public void demo1() {
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction(); Customer customer = new Customer(); // 瞬时态对象:没有唯一标识OID,没有被session管理
customer.setCust_name("王晓东"); Serializable id = session.save(customer); // 持久态对象:有唯一标识OID,被session管理 tx.commit();
session.close(); System.out.println("客户名称: " + customer.getCust_name()); // 托管态对象:有唯一标识OID,没有被session管理
}

3.3 持久化的三种状态的转换

3.3.1 持久态的三种状态转换图

3.3.2 瞬时态对象

Customer customer = new Customer();save(Obejct obj)、saveOrUpdate(Object obj);customer.setCust_id(1);

3.3.3 持久态

get()、load()、find()、iterate()Customer customer = session.get(Customer.class,1L);delete()close()、clear()、evict(Object obj)

3.3.4 托管态对象

Customer customer = new Customer();customer.setCust_id(1L);update()、 saveOrUpdate()customer.setCust_id(null)

3.3.5 持久态对象的特性

@Test	//	持久态对象自动更新数据库
public void demo2() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 获得持久态对象:
Customer customer = session.get(Customer.class, 1L);
customer.setCust_name("王喇嘛");
//session.update(customer);
// 不写这句话也可以将数据保存到数据库,这是持久态对象的特征,底层是一级缓存 transaction.commit();
session.close();
}
4. Hibernate的一级缓存

4.1 缓存概述

  • 什么是缓存:
    • 缓存时一种优化的方式,将数据存储到内存中,使用的时候直接从缓存中获取,不用通过存储源。

4.2 hibernate的缓存

  • Hibernate框架中提供了很多优化手段,比如缓存、抓取策略。Hibernate中提供了两种缓存机制,一级缓存和二级缓存。
  • Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放互相管理的Java对象,在使用Hibernate查询对象的时候,首先会使用对象属性的OID值在Hibernate的一级缓存中进行查找,如果找到匹配的OID值得对象,就直接将该对象从一级缓存中取出使用,不会再查询数据库;如果没有找到相同得OID值得对象,则会去数据库中查找相应得数据。当从数据中查询到到所需数据时,该数据信息也会放置到一级缓存中。Hibernate得一级缓存的作用就是减少对数据库的访问次数。
  • 再在Session接口的实现中包含了一系列的Java集合,这些Java集合构成了Session缓存。只要Session实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期。所以一级缓存也被称为是Session基本的缓存。
  • Hibernate的二级缓存是SessionFactory级别的缓存,需要配置的缓存。二级缓存已经被Redis取代,实际开发过程不会使用。
  • 一级缓存是自带的不可卸载的

4.3 证明一级缓存的存在

package com.itzhouq.hibernate.demo1;
import java.io.Serializable;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.itzhouq.hibernate.utils.HibernateUtils; public class Demo3 {
// 证明一级缓存的存在
@Test
public void test() {
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// Customer customer1 = session.get(Customer.class, 1L); // 发送SQL语句
// System.out.println(customer1);
//
// Customer customer2 = session.get(Customer.class, 1L); // 不发送SQL语句
// System.out.println(customer2);
Customer customer = new Customer();
customer.setCust_name("凤姐");
Serializable id = session.save(customer); Customer customer2 = session.get(Customer.class, id); // 不发送SQL语句
System.out.println(customer2); transaction.commit();
session.close();
}
}

4.4 一级缓存的结构

  • 一级缓存中的特殊区域:快照区

5. Hibernate事务管理

5.1 什么是事务

  • 事务:事务是指逻辑上的一组操作,这组操作的各个逻辑单元要么全部成功,要么全都失败。

5.2 事务的特性

  • 原子性:代表事务不可分割。
  • 一致性:代表事务执行的前后,数据的完整性保持一致。
  • 隔离性:代表一个事务的执行过程中,不应该受到其他事务的干扰。
  • 持久性:代表事务执行完成后,数据就持久化到数据库中。

5.3 不考虑隔离性,引发安全问题

  • 读问题:
    • 脏读:一个事务读取到另一个事务未提交的数据。
    • 不可重复读:一个事务读取到另一个事务已经提交的update数据,导致在前一个事务多次查询结果不一致。
    • 虚读:一个事务读取到另一个事务已经提交的insert数据,导致在前一个事务多次查询结果不一致。
  • 写问题【了解】
    • 引发两类丢失更新

5.4 读问题的解决

Read uncommittedRead committedRepeatable readSerlializable

5.5 设置事务的隔离级别

<!-- 设置事务的隔离级别 -->
<property name="hibernate.connection.isolation">4</property>

5.6 Hibernate解决Service事务管理

package com.itzhouq.hibernate.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; /*
* Hibernate的工具类
*/
public class HibernateUtils {
public static final Configuration cfg;
public static final SessionFactory sf; static {
cfg = new Configuration().configure();
sf = cfg.buildSessionFactory();
} public static Session openSession() {
return sf.openSession();
} public static Session getCurrentSession() {
return sf.getCurrentSession();
}
}
<!-- 配置当前线程绑定的Session -->
<property name="hibernate.current_session_context_class">thread</property>
package com.itzhouq.hibernate.demo1;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.itzhouq.hibernate.utils.HibernateUtils; /*
* 测试当前线程绑定的Session
*/
public class Demo4 {
@Test
public void test() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
Customer customer = new Customer();
customer.setCust_name("王希");
session.save(customer); transaction.commit();
//session.close();//不需要关闭
}
}
6. HIbernate的其他API

6.1 Query

package com.itzhouq.hibernate.demo1;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test; import com.itzhouq.hibernate.utils.HibernateUtils; /*
* HIbernate的其他API
*/
public class Demo5 { @Test // Query
public void test() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction(); // 通过Session获得Query接口
//简单查询
//String hql = "from Customer";
//条件查询
//String hql = "from Customer wehre cust_name like ?";
//分页查询
String hql = "from Customer";
Query query = session.createQuery(hql);
//设置条件
//query.setParameter(0, "王%");
//设置分页
query.setFirstResult(0);
query.setMaxResults(3); List<Customer> list = query.list();
for (Customer customer : list) {
System.out.println(customer);
} transaction.commit();
}
}

6.2 Criteria

@Test	// Criteria
public void test2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
//通过Session获得Criteria对象
Criteria criteria = session.createCriteria(Customer.class);
//List<Customer> list = criteria.list(); //条件查询
// Criteria add = criteria.add(Restrictions.like("cust_name", "王%"));
// List<Customer> list = criteria.list(); //分页查询
criteria.setFirstResult(0);
criteria.setMaxResults(2);
List<Customer> list = criteria.list(); for (Customer customer : list) {
System.out.println(customer);
} transaction.commit();
}

6.3 SQLQuery【了解】

  • SQLQuery用于接收SQL。特别复杂情况下使用SQL。