JAVA学习笔记:JPA进阶&二级缓存

it2022-05-09  16

1.JPA主键生成策略

1.1 概念

主键是关系型数据库中的一个基本概念,它用来保证记录的唯一性。同一个表中,不允许存在多条相同主键的记录。简单的说就是具有自增、非空且唯一的特性。

1.2 JPA标准主键生成策略

auto:自动根据方言来选择表主键生成(默认)table:表的生成策略,会另外创建一张表来维护主键,兼容性比较好 性能麻烦(一般不用)sequence:序列策略identity:自增策略

1.3 主键的分类

自然主键:具有实际业务意义的列作为为主键,比如身份证号码 代理主键:没有实际意义的列作为主键,比如 id(推荐)

2. JPA持久对象的状态

2.1 JPA的状态

新建状态、临时状态、瞬时状态:刚刚创建出来的对象,还没有和EntityManager发生关系; 持久状态、托管状态:和EntityManager发生关系、比如调用persist merge等方法; 游离状态、脱管状态:脱离EntityManager管理,比如clear,close,commit提交之后 删除状态:计划要准备删除的时候,remove之后

2.2 脏数据更新及n-to-n问题

如果一个持久化状态的数据,改变非主键的值,在提交的时候,自动发送sql语句更新 如果一个持久化状态的数据,改变主键的之后,报错 n-to-n的错误 org.hibernate.HibernateException: identifier of an instance of xxx was altered from 1 to 200 如果一个非持久化状态的数据 ,就可以改变

2.3 持久对象(domain层)定义规则

类不能定义为final类 因为domain类需要被继承的,否则延迟加载会受到影响所有属性的类型都必须是包装类型 不能是8个基本类型(int,byte,short,long,char,boolean,float,double) 因为JPA内部代码很多判断都是基于是否等于null必须有默认无参构造方法 因为find方法获取的时候会在内存实例化domain对象 否则报org.hibernate.InstantiationException: No default constructor for entity异常

3. 域对象之间关系

3.1 依赖关系

JavaBean之间的依赖关系,比如controller层依赖service层,service层依赖dao层

3.2 关联关系

类与类之间存在关联,比如员工类和部门类, 分为:1对1,1对多,多对1,多对多 按导航性来分:单向和双向

3.3 聚合关系

整体和部分可以分开,单独存在

3.4 组合关系

也叫强聚合关系,整体和部分不可分开

4. 单向多对一

多方类的配置(员工)

@Entity public class Employee { @Id @GeneratedValue private Long id; private String name; @ManyToOne @JoinColumn(name="dept_id") private Department dept; }

一方配置(部门)

@Entity public class Department { @Id @GeneratedValue private Long id; private String name; }

保存: 必须先保存一方,再保存多方,这样可以少发送sql语句

5. JPA抓取策略

告诉程序用哪种策略去获取数据

懒加载,需要的时候才去发sql语句获取数据 @ManyToOne(fetch = FetchType.LAZY )迫切加载,先把数据通过左外链接获取出来 @ManyToOne(fetch = FetchType.EAGER)

6. 二级缓存

6.1 什么时候使用二级缓存

读取大于修改,因为修改数据的时候,缓存同步变化对数据要有独享控制,数据不会被第三方修改;如果修改数据,缓存也需要改变缓存里面数据 可以容忍无效数据(日志信息等对实时性要求不高数据)如果数据量比较大,也不适合放入缓存(钝化encache 支持内存 磁盘存储)

6.2 二级缓存的使用

导入jar包 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>4.3.8.Final</version> </dependency> 添加persistence.xml配置信息 <!-- 启用二级缓存 --> <property name="hibernate.cache.use_second_level_cache" value="true" /> <!-- 二级缓存的实现类,文档里面的包名有错的 --> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" /> <!-- 启用查询缓存 --> <property name="hibernate.cache.use_query_cache" value="true" /> 添加配置二级缓存扫描的策略(在上面) 扫描策略: ALL:所有的实体类都被缓存 NONE:所有的实体类都不被缓存 ENABLE_SELECTIVE:标识 @Cacheable(true) 注解的实体类将被缓存 DISABLE_SELECTIVE:缓存除标识 @Cacheable(false) 以外的所有实体类 UNSPECIFIED:默认值,JPA 产品默认值将被使用 <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

6.3 缓存淘汰策略

LRU(Least Recently Used):最近最少使用 LFU(Least Frequently Uesd):最不经常使用 FIFO(First in First Out):先进先出

6.4 缓存命中条件

一级缓存:同一个EntityManagerFactory,同一个EntityManager,同一个OID 二级缓存:同一个EntityManagerFactory,不同EntityManager,同一个OID,需要在domain类上面配置@Cacheable(true) 查询缓存:同一个EntityManagerFactory,不同EntityManager,相同jpql和条件的相同


最新回复(0)