目录
七、JPA的多对多映射(涉及级联,常用改,增删不用且避免使用)
一、JPA相关概念
全称是:Java Persistence API(Java持久化规范)。是SUN公司推出的一套基于ORM的规范。hibernate框架实现了JPA的规范。
①、JPA是一套ORM规范(算是一个接口),hibernate实现了JPA规范(算是一个实现类)。
②、hibernate中有自己的独立ORM操作数据库方式,也有JPA规范实现的操作数据库方式。使用JPA补充hibernate-entitymanager-5.0.7.Final.jar。
③、hibernate框架是通过XML的方式来描述对象-关系表的映射关系;JPA是通过注解形式来描述对象-关系表的映射关系的。
④、JPA出现的原因:有了hibernate框架之后,许多公司发现好处,纷纷像其学习也创造了属于自己的框架,由此,orm框架越来越多,越来越不利于开发的使用。于是,制定了这一套规范,所有的orm框架都必须实现这套规范以规范开发。约定JPA采用注解的形式。简单来说,就是JPA其实就是为了统一多个厂家的ORM框架而提出的一套规范。这套规范是注解形式的配置。而ORM框架大多数xml形式的配置。
二、JPA环境的搭建
1、hibernate框架如果要实现JPA规范,需要额外导入jar包:hibernate-entitymanager-5.0.7.Final.jar
../hibernate-release-5.0.7.Final\lib\jpa/hibernate-entitymanager-5.0.7.Final.jar
2、创建核心配置文件
要求:在src下面创建META-INF文件夹,且文件夹下面创建一个名称为persistence.xml的文件
内容如下:-- xsd约束可在hibernate-entitymanager-5.0.7.Final.jar》org.hibernate.jpa》下的约束文件中找到。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!-- 要求至少得有一个持久化单元(至少得有一个数据库的连接信息) -->
<!-- name :用于定义持久化单元的名字 (name必选,空值也合法);
transaction-type :指定事务类型(可选)
取值: JTA:默认值 transaction-type="JTA"
RESOURCE_LOCAL transaction-type="RESOURCE_LOCAL"
-->
<persistence-unit name="oracle"> <!-- name可以随便取 -->
<!-- oracle的数据库连接信息 -->
<properties>
<property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver"/>
<property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="hibernate.connection.username" value="ly1"/>
<property name="hibernate.connection.password" value="ly1"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<persistence-unit name="mysql"> <!-- name可以随便取 -->
<!-- mysql的数据库连接信息 -->
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpa"/>
<property name="hibernate.connection.username" value="root"/>
<property name="hibernate.connection.password" value="1234"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<property name="hibernate.connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<!-- <persistence-unit name="db2">
db2的数据库连接信息
</persistence-unit> -->
</persistence>
3、编写工具类,用于获取JPA的操作数据库对象
4、编写实体类并使用注解配置
三、JPA常用注解说明
1、@Entity
作用:指定当前类是实体类。用于在创建SessionFactory/EntityManager时,加载映射配置。
2、@Table
作用:指定实体类和表之间的对应关系。
属性:
name:指定数据库表的名称
3、@Id
作用:指定当前字段是主键。
4、@GeneratedValue
作用:指定主键的生成方式。JPA的主键生成方式详解见4小节的说明。
属性:
strategy :指定主键生成策略。JPA支持四种生成策略,具体介绍看4小节。
5、@SequenceGenerator
作用:根据底层数据库的序列来生成主键,条件是数据库支持序列。详解见4小节的说明。
6、@Column
作用:指定实体类属性和数据库表之间的对应关系
属性:
name:指定数据库表的列名称。
unique:是否唯一
nullable:是否可以为空
inserttable:是否可以插入
updateable:是否可以更新
columnDefinition: 定义建表时创建此列的DDL
secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字。
一对多关系:
1、@OneToMany:
作用:建立一对多的关系映射
属性:
targetEntityClass:指定多的字节码文件类型
mappedBy:多里面一对象的属性名,mappedBy出现,意味着这里放弃维护外键
cascade:级联操作:在操作自己的时候 ,把自己关联的数据也同样操作了。操作谁 ,在谁的类上进行注解配置
fetch:指定是否采用延迟加载
orphanRemoval:是否使用彻底删除与cascade连用(还没用过)
2、@ManyToOne
作用:建立多对一的关系映射
属性:
targetEntityClass:指定一的字节码文件类型
cascade:级联操作:在操作自己的时候 ,把自己关联的数据也同样操作了。操作谁 ,在谁的类上进行注解配置
fetch:指定是否采用延迟加载
optional:关联是否可选。如果设置为false,则必须始终存在非空关系。
3、@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段名
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
多对多关系:
1、@ManyToMany
作用:用于映射多对多关系
属性:
cascade:级联操作:在操作自己的时候 ,把自己关联的数据也同样操作了。操作谁 ,在谁的类上进行注解配置。
fetch:配置是否采用延迟加载。
targetEntity:对方的字节码文件类型。映射多对多的时候不用写。
2、@JoinTable
作用:维护多对多映射的中间表
属性:
name:配置中间表的名称
joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn:中间表的外键字段关联对方表的主键字段
3、@JoinColumn
作用:用于定义主键字段和外键字段的对应关系。
属性:
name:指定外键字段的名称
referencedColumnName:指定引用主表的主键字段名称
unique:是否唯一。默认值不唯一
nullable:是否允许为空。默认值允许。
insertable:是否允许插入。默认值允许。
updatable:是否允许更新。默认值允许。
columnDefinition:列的定义信息。
四、JPA支持的主键生成策略
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO
4.1 IDENTITY:主键由数据库自动生成(主要是自动增长型)
@GeneratedValue(strategy=GenerationType.IDENTITY)
4.2 SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="linkman_seq")
@SequenceGenerator(name="linkman_seq",sequenceName="SEQ_T_LINKMAN_ID",allocationSize=1)
name:表示该表主键生成策略的名称,它被引用在@GeneratedValue中设置的“generator”值中。
sequenceName:属性表示生成策略用到的数据库序列名称。
initialValue:表示主键初识值,默认为0。
allocationSize:表示每次主键值增加的大小,例如设置1,则表示每次插入新记录后自动加1,默认为50。
测试中发现JPA的一个问题:Hibernate配置Oracle的主键生成策略值为负数
4.3 主键由程序控制
@GeneratedValue(strategy=GenerationType.AUTO)
五、JPA的CRUD操作
![](https://img-blog.csdnimg.cn/20200331144958256.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzU4MTQz,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200331145041462.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzU4MTQz,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200331145144345.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzU4MTQz,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200331145230806.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzU4MTQz,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20200331150120656.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM3MzU4MTQz,size_16,color_FFFFFF,t_70)
具体参见代码
六、JPA的一对多映射(涉及级联,常用增删)
仍旧以Customer和Linkman为例:
1、编写实体类并使用注解配置
2、一对多关系的增删改操作
七、JPA的多对多映射(涉及级联,常用改,增删不用且避免使用)
仍旧以User和Role为例:
1、编写实体类并使用注解配置
2、多对多关系的增删改操作
八、JPA和hibernate中操作数据的方法对照
操作 | Hibernate中的方法 | JPA中的方法 | 说明 |
保存操作 | save(Object entity) | persist(Object entity) | 共同点:都是把临时态对象转成了持久态。 区别: 提供者不一样: save方法是hibernate提供的。 persist方法是JPA规范提供的。 在没有事务的情况下: save会去数据库中保存,hibernate提供了一个内置的事务来执行。 persist什么都不会做。 |
更新操作 | update (Object entity) | merge (Object entity) | Hibernate和jpa都可以利用快照机制,不调用任何方法去更新。 Update方法在更新时,如果遇到一级缓存已经包含了一个相同OID的对象会报错。merge则可以执行成功。 |
删除操作 | delete (Object entity) | remove (Object entity) | 都是删除一个实体 |
查询一个操作 | get (Class clazz,Serializable id) load(Class clazz,Serializable id) | find(Class clazz,Object id) getReerence(Class clazz,Object id) | get和find都是立即加载。load和getReference一样都是延迟加载。 |
查询所有操作 | Query:使用HQL语句查询 | Query:使用JPQL查询 | JPQL查询类似Query查询,个别方法不同而已。 |
查询返回唯一结果操作 | uniqueResult() | getSingleResult() | 查询都是返回一个唯一的结果。 |