使用JPA中的生成表,还有很多细节,比如主键,JPA对象的四大对象,脏数据更新,域对象关系等等。上一篇我只是写了一些基本的使用JPA。今天在这里再详细 的介绍下JPA的一些细节。
1.主键
1.1.自然主键:使用带有业务功能的字段作为主键
一般说来我们是不建议使用自然主键,打个比方,在银行的系统中,如果一个人只有一个身份证号,所以有一些程序员就使用生份证号作为主键,但是我们一个人可以有多个银行卡,这样就会出问题,所以不建议使用自然主键。
1.2.代理主键:就是使用没有任何业务功能的字段作为主键。
我们可以在表中建立一列,比如id,它只是作为我们的主键。
1.3.主键生成的四种策略
- identity:自增 :MySQL, SQL Server, DB2,
- Sequence:序列:Oracle、PostgreSQL、DB2
- Table:兼容所有数据库:当我们要使用多个数据库的时候 他使用一张表来模拟序列(性能低)
- auto:根据方言自动识别是自增还是序列
2.JPA对象的四大状态
1.临时:对象刚被创建出来
2.持久化:和EntityManager对象发生关系(一级缓存)
3.游离:持久化对象与EntityManager接触关系(从缓存中移除)
4.删除:JPA特有的,执行remove方法时(并不是真正的删除,只是将状态转换为计划删除)
3.脏数据更新
一个持久状态对象在事务管理内,如果改变原来的数据(非主键),此时出现脏数据,在事务提交的时候自动发出update语句去修改。
4.域对象关系
4.1.依赖关系
表现层(controller)依赖业务层(service),业务层依赖持久化(dao)
4.2.关联关系
- 多重性
一对一:
- 共享主键:一般不用
- 唯一主键:拓展性更强
多对一,一对多:使用外键(外键在哪,那一边就是多的一方)
多对多:使用中间表
- 导向性(数据库没有导向性)
单向,多向
- 聚合关系:双向的多对一,一对多
- 组合关系:强聚合(部分与整体不可分割)
- 泛化:就是继承
4.3多对一的代码实现
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "manager_id")
private Employee employee;
- ManyToOne:表示表关系
- Fetch:加载策略
- FetchType.LAZY:延时(懒)加载:就是使用的时候才到数据查询
- FetchType.EAGER:及时加载:不管用不用,先的查出来
- JoinColumn:外键的名字
5.二级缓存
其实我们一般不使用JPA的二级缓存,一般使用的Spring的二级缓存,所以在这里我只是简单的介绍下
5.1使用场景:
- 读取大于修改:就是查询的多,但是一般不会去修改,比如一个公司的部门
- 对数据有独享控制:不会被第三方修改
- 允许无效数据:记住财务系统不要使用缓存
- 数据大小不超过内存:超过就会钝化:将数据存到硬盘中
5.2.如何使用
- 导包:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>4.3.8.Final</version>
</dependency>
- 配置:
<persistence-unit name="cn.itsource.jpa" transaction-type="RESOURCE_LOCAL">
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
<properties>
....
<!-- 配置二级缓存 -->
<!-- 打开二级缓存 -->
<property name="hibernate.cache.use_second_level_cache" value="true" />
<!-- 支持二级缓存的工厂 -->
<property name=" hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
</properties>
</persistence-unit>
- 注解
@Cacheable