1.课程介绍
1. 主键生成策略;(了解)
2. JPA持久对象的状态;(掌握)
3. 域对象之间的关系(了解)
4. 单向多对一;(掌握)
5. 二级缓存(掌握)
一.主键生成策略
auto策略(默认)
table策略:标的生成策略额外创建一张表来维护主键,兼容性好
sequence策略:序列策略
identity策略:mysql采用这种
二.JPA持久对象的状态
临时(瞬时)transient:刚刚创建出来,没有和jpa发生关系,该对象成为临时对象
持久(托管)persistent:这个实体对象已经和jpa发生关系,该对象已经持久化
游离(托管)detached:脱离entitymanager的管理,已经被持久化,不存在entityManager里面,该对象已经游离。
删除remove:移除entityManager.remove
public void testStatus() throws Exception{
//临时
StatusDomain statusDomain = new StatusDomain();
statusDomain.setName("苏苏");
EntityManager entityManager = JpaUtil.getEntityManager();
entityManager.getTransaction().begin();
//持久
entityManager.persist(statusDomain);
//游离
entityManager.getTransaction().commit();
entityManager.close();
}
脏数据更新
一个持久状态对象在事务管理内,如果改变原来的数据(非主键),此时出现脏数据,在事务提交的时候自动发出update语句去修改。
n-to-n问题
持久层状态下的对象不能随意设置修改主键,不然会报
org.hibernate.HibernateException:
identifier of an instance of
cn.itsource.jpa.state.StateDomain was altered from 1 to 200
域对象(domain对象)之间的关系
Controller表现层依赖于Service业务层,Service依赖于Dao持久层
三单向多对一
就是java中一个类可以获取另一个类
基本配置
@Entity
@Table(name = "product")
public class Product {
@Id
//默认auto
@GeneratedValue
private long id;
private String name;
//多对一
@ManyToOne(fetch = FetchType.LAZY)
//指定外键id
@JoinColumn(name = "dir_id")
private ProductDir dir;
get,set方法
tostring
@Entity
@Table(name = "productDir")
public class ProductDir {
@Id
//默认auto
@GeneratedValue
private long id;
private String name;
get,set方法
有参构造
无参构造
注意细节
注意顺序,先存分类再存产品
不然会增加sql语句
entityManager.persist(dir);
entityManager.persist(p1);
entityManager.persist(p2);
四.JPA抓取策略
@ManyToOne(fetch = FetchType.LAZY ) 表示懒加载 – 需要使用的时候,才发送sql查询
类不要定义成final
@ManyToOne(fetch = FetchType.EAGER) 表示迫切加载 – 不使用都把数据加载出来 发送左外连接查询数据
五.二级缓存
缓存作用:空间换时间
1级缓存:属于EntityManager级别的缓存 ,它是自带的
命中条件:
同一个EntityManagerFactory 同一个EntityManager 同一个OID
2级缓存:属于EntityManagerFactory级别缓存,它不是自带,如果要使用二级缓存,相应配置之后,才能使用二级缓存 — 通过Encache 框架来实现二级缓存
命中条件:
同一个EntityManagerFactory 不同EntityManager 同一个OID
//先查询出来,如果一级缓存有,就命中,
EntityManager entityManager1 = JpaUtil.getEntityManager();
Product product1 = entityManager1.find(Product.class, 1L);
Product product2 = entityManager1.find(Product.class, 1L);
//如果一级缓存没有,就二级找,有就命中
EntityManager entityManager2 = JpaUtil.getEntityManager();
Product product3 = entityManager2.find(Product.class, 1L);
Product product4 = entityManager2.find(Product.class, 1L);
3查询缓存(依赖二级缓存)
命中条件:
同一个EntityManagerFactory 不同EntityManager 相同jpql 和条件相同
EntityManager entityManager1 = JpaUtil.getEntityManager();
String jpql1 ="select o from Product o where o.id=?";
Query query1 = entityManager1.createQuery(jpql1).setParameter(1, 2l);
query1.setHint(QueryHints.HINT_CACHEABLE,true);
System.out.println(query1.getResultList().size());
EntityManager entityManager2 = JpaUtil.getEntityManager();
String jpql2 ="select o from Product o where o.id=? ";
Query query2 = entityManager2.createQuery(jpql1).setParameter(1, 2l);
query2.setHint(QueryHints.HINT_CACHEABLE,true);
System.out.println(query2.getResultList().size());
缓存淘汰策略
LRU:最少使用
LFU:最不经常使用
FIFO:先进先出