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