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和条件的相同