JPA : 对象关系映射ORM(Hibernate)的规范(持久化)
OMR是什么?? --> 对象关系映射Object Relational Mapping
Hibernate --> ORM框架(实现了ORM规范)加快了操作数据库的速度 -- 其中单表操作没有太多优势。
Hibernate和JPA的关系? --> JPA是持久化规范,而Hibernate是其实现
JPA(Hibernate)和JDBC区别??
JPA(Hibernate)对JDBC的封装,开发效率高,性能低(不好控制),兼容所有数据库,好的缓存机制,直接面向持久对象操作(缺点:不能干涉SQL生成)
JDBC操作数据库最底层,性能最高,使用复杂(重复代码太多),没有提供数据的缓存,需要自己实现,移植数据库很麻烦,改动比较多【主键的生成方式不同(mysql使用自增,oracle使用序列),分页的sql语句也是不同(mysql使用limit,oracle使用ROWNUM)】
建表策略(配置自动生成表) -- hibernate.hbm2ddl.auto配置选型
create-drop --> 先删除表,再创建表,再删除表(必须保存关闭EntityManagerFactory) 【开发一般不用】
create --> 先删除表,再创建表,不会再删除表 【测试的时候使用】
update --> 修改(如果没有表会创建,如果表里面没有属性,映射信息存在,会增加这个列) 【测试和web项目中使用】
validate --> 验证(只验证domain中有的部分) 表不存在,会抛出异常,bean类映射信息少属性,表比映射定义的列要多,不会报错,反之抛出异常 【用在系统已经上线或者客户给定了数据库的情况下】
四大对象
Persistence : 工具类,创建EntityManagerFactory(解析xml)
EntityManagerFactory : 创建EntityManager,( 重:连接池,sql,二级缓存,domain关系等,线程安全)
EntityManager : 实体管理对象 ( 轻:连接,一级缓存,线程不安全,一个请求[线程]一个EntityManager)
一级缓存命中:同一个EntityManagerFactory,同一个EntityManager,同一个OID
OID:对象的全限定名#id的值
Transaction : 事务对象(EntityManager拿到的事务是同一个)
主键生成策略 [ @GeneratedValue ]
identity:自增(类型必需是数字类型,数据库必需支持自增策略) MySQL, SQL Server, DB2, Derby, Sybase, PostgreSQL
sequence:序列(类型必需是数字类型,数据库必需支持序列策略) Oracle、PostgreSQL、DB2
auto:根据方言自动识别是自增还是序列 [@GeneratedValue默认是auto]
table:使用表模拟序列(性能有点差,因为兼容各种数据库)
JPA对象状态
临时状态:new语句刚创建出来的
持久化状态:和EntityManager对象发生关系(在一级缓存中)
游离状态:持久化对象与EntityManager解除关系(从缓存中移除, entityManager.close();之后)
删除状态:JPA特有状态,执行remove方法时(计划删除,事务提交时被真的删除)
脏数据更新:一个持久状态对象在事务管理内,如果改变原来的数据(非主键),此时出现脏数据,在事务提交的时候自动发出update语句去修改[如果是临时对象就需要merge去修改哦]
n-to-n错误(identifier of an instance of com.zhengqing.domain.Teacher was altered from 1 to 2) --> 持久化对象的OID不允许被修改
nosession错误 --> 提前关闭了entityManager,但还是使用它去访问数据库(懒加载对象)
持久化对象(bean层)定义规则:
①类不能定义为final类
②属性必须是包装类型
③有无参构造方法
域对象关系
依赖关系:表现层(controller)依赖业务层(service),业务层依赖持久化层(dao/repository)
关联关系: --> https://blog.csdn.net/qq_38225558/article/details/84109136
多重性:一对一,多对一,一对多,多对多
一对一:共享主键,唯一外键(扩展性更强)
多对一,一对多:外键(外键在哪边,哪边就是多方)
多对多:中间表
导航性:单向与双向(注意:数据库中无法表示导航性)
聚合关系:双向的多对一,一对多
组合关系:强聚合(部分与整体不可分割)
泛化关系:继承
缓存
一级缓存(entityManager):同一个entityManagerFactory,同一个entityManager,同一个oid
二级缓存(entityManagerFactory):同一个entityManagerFactory,不同entityManager,同一个oid
二级缓存
如何使用二级缓存??
①导包 pom.xml中
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.3.8.Final</version>
</dependency>
②配置
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="com.zhengqing.jpa" transaction-type="RESOURCE_LOCAL">
<!-- ALL:所有的实体类都被缓存 -->
<!-- NONE:所有的实体类都不被缓存. -->
<!-- ENABLE_SELECTIVE:标识 @Cacheable(true) 注解的实体类将被缓存 -->
<!-- DISABLE_SELECTIVE:缓存除标识 @Cacheable(false) 以外的所有实体类 -->
<!-- UNSPECIFIED:默认值,JPA 产品默认值将被使用 -->
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
...
...
<!-- 配置二级缓存 -->
<!-- 打开二级缓存 -->
<property name="hibernate.cache.use_second_level_cache" value="true" />
<!-- 打开查询缓存 -->
<property name="hibernate.cache.use_query_cache" value="true" />
<!-- 支持二级缓存的工厂 --> <!-- 这里注意:如果是配置文件中拷贝过来的话要修改!!!-->
<property name=" hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
</properties>
</persistence-unit>
</persistence>
③加注解 @Cacheable
④使用缓存
什么是延时(懒)加载?
使用相应的对象的时候,它才会到数据库中去获取这个值
什么是级联?
级联增删改(ALL) --> orphanRemoval=true
组合关系必须用 --> cascade = CascadeType.ALL, orphanRemoval = true