1、jpa入门

Java持久层api,替代jdbc,Java持久化规范。JPA是Hibernate的一个抽象,是一种ORM规范,是Hibernate功能的一个子集,Hibernate是JPA的一个实现

jpa和jdbc优缺点:

jdbc:

本质:处理Java对象和关系型数据库表之间的转化

优点:性能最高,操作数据库最底层

缺点:

1.使用复杂(重复代码很多),移植数据库很麻烦

​ 2.性能优化需要自己处理,没有提供数据缓存,需要自己实现。

​ 3.面向的是sql语句操作,不是面向对象的。

jpa:

本质:只是对于jdbc再次做了一层封装

优点:

1.程序员操作很简单,代码简单。

​ 2.直接面向持久对象操作

​ 3.提供世界级数据缓存(一级缓存,二级缓存,查询缓存)

​ 4.数据库移植性很强,很少的修改(通过配置方言):把各种数据库抽取了一个方言接口,不同的数据库实现类一个方言接口,需要换数据库,只需要修改方言实现,驱动jar文件,连接数据库信息(4个:驱动,url地址,用户名,密码)

缺点:

1.不能干预sql语句的生成。find方法默认查询表的所有字段

2.一个项目中如果对sql语句的优化比较高,不适用jpa(不过jpa中有对原生sql的支持)

​ 3.如果一个表中有上亿的数据,也不适合用jpa和jdbc(可以使用数据库读写分析,分库分表方案解决)

适用的项目规模:中小型,jpa在性能优化上比较吃力,超大型还是推荐使用MyBatis.

ORM框架:就是把数据保存到可掉电式存储设备中,持久层就是dao层,

ORM是对象关系映射框架,就是通过Java对象映射到数据库表,通过操作Java对象,就可以完成对数据库表的操作,

面向对象概念面向关系概念

类表

对象实体表的行(记录)

属性,对象粒度表的列(字段)

2、JPA基本注解

@Entity:用于实体类声明语句之前,指出该Java类为实体类,将映射到指定的数据库表。

@Table:当实体类与其映射的数据库表名不同名时使用,该标注于@Entity并列使用,置于实体类声明语句之前,可写于单独语句行,也可与声明语句同行。

name用于指明数据库的表名

catalog和schema用于设置表所属的数据库目录或模式,通常为数据库名

uniqueConstraints用于设置约束条件,通常不设置

@Id声明一个实体类的属性映射为数据库的主键列。通常位置声明语句之前或者同行,也可以置于属性的getter方法之前。、

@GeneratedValue用于标注主键的生成策略,通过strategy属性指定。默认情况下,jpa自动选择一个适合底层数据库的主键生成策略:SqlServer对应identity,MySQL对应auto increment。

IDENTITY:采用数据库ID自增长方式来自增主键字段,但是Oracle不支持这种方式

AUTO:JPA自动选择合适的策略,是默认选项:

SEQUENCE:通过序列产生主键,通过@SequenceGenerator注解指定序列名,但是MySql不支持这种方式

TABLE:通过表产生主键,便于数据库的移植

@Basic表示一个简单的属性到数据库表的字段的映射对于没有任何标注的get()方法。默认即为@Basic

fetch:表示该属性的读取策略,有EAGER和LAZY两种,表示主支抓取和延迟加载,默认为true

optional:表示该属性是否允许为null默认为true

Column:当实体属性与其映射的数据库表的类不同名时需要使用

Transient:表示该属性并非到数据库表的字段的映射,ORM框架将忽略该属性。必须标注

Temporal:调整精度

3、JPA的API

Persistence:用于获取EntiryManagerFactory的实例

常用方法:Persistence.createEntityManagerFactory(persistenceUnitName)方法

EntiryManagerFactory

获取EntiryManager

close()方法,关闭自身

EntityManager的常用API

find()方法,在执行find方法时就发送SQL语句(类似于Hibernate中的Session的get()方法)

getReference()方法,若不适用查询的对象则返回一个代理对象,到真正使用的时候才发送SQL语句chax(类似于Hibernate的Session的load()方法)

persistence()方法,类似于 Hibernate 的 save() 方法,与 Hibernate 的 save() 方法不同的是其不能插入一个有 id 属性的对象

remove() 方法,类似于 Hibernate 中 Session 的 delete 方法,但是其不能删除 游离化对象(仅有 id)

merge() 方法,类似于 Hibernate 中 Session 的 saveOrUpdate() 方法

EntityTransaction:JPA中的事务操作

常用API:begin();commit();rollback()

4、JPA中映射关联关系

映射单向多对一的关联关系,many的一方作为关系的维护段,one的一方作为被维护端,one方指定@OneToMany注释并设置mappedBy属性,以指定他是被维护端,many方指定@ManyToOne注解,并使用@JoinColumn指点外键名称

创建Order实体类:标注注解生成数据表,使用@ManyToOne映射多对一的关联关系,使用@JoinColumn来标注外键。

单向多对一的保存:保存多对一是,建议先保存1的一段,这样不会多出额外的update语句

获取操作(find):默认情况下使用左外连接的方式来获取n的一端的对象和其关联的1的一端的对象。可以使用@ManyToOne的fetch属性来修改默认的关联属性的加载策略

删除操作(remove):不能直接删除1的一端,因为有外键约束

修改操作:可以根据n的一端对1的一端镜像修改操作。

映射单项一对多的关联关系Customer:Order 1:n,Customer中有Order的Set稽核属性,Order中没有Customer的属性

在Customer中添加Order的Set集合属性,并映射1-n关联关系,重新生成数据表

保存操作(persist):总会多出UPDATE语句,n的一端在插入式不会同时插入外键列

查询操作(find)默认使用懒加载

删除操作(remove):默认情况下删除1的一端,会先把关联的n的一端的外键置空,然后再删除,可以通过@OneToMany的cascade属性

映射双向多对一的关联关系(注:双向多对一通双向一对多)

实体:Customer中有Order的Set集合属性,Order中有Customer的属性,两个实体映射的外键列必须一致,都为CUSTOMER_ID

保存操作(persist):

映射双向一对一的关联关系

映射双向多对多的关联关系

5、JPA的二级缓存

若JPA实现支持二级缓存,该节点可以配置在当前的持久化单位中是否启用二级换窜,可配置如下值:

ALL:所有实体类都被缓存

NONE:所有实体类都不能被缓存

ENABLE_SELECTIVE:表示@Cacheable(true)注解的实体类将被缓存

DISABLE_SELECTIVE:换窜除表示@Cacheable(false)依赖的所有实体类

UNSPECIFIED:默认值,JPA产品默认值将被使用

6、JPQL

JPQL语言的语句是select语句,update语句或delete语句,他们都通过Query接口封装执行

Query接口封装了执行数据库查询的相关方法。调用 EntityManager的createQuery、createNamedQuery及createNativeQuery方法可以获得查询对象,进而可调用Query接口的相关方法来执行查询操作。

Query接口的主要方法:

int executeUpdate()

用于执行update或delete语句

List getResultList()

用于执行select语句并返回结果集实体列表

Object getSingleResult()

用于执行只返回单个结果实体的select语句。

Query setFirstResult(int startPosition)

用于设置从哪个实体记录开始返回查询结果

Query setMaxResults(int maxResult)

用于设置返回结果实体的最大数。与setFirstResult结合使用可实现分页查询

Query setFlushMode(FlushModeType flushMode)

设置查询对象的Flush模式。参数可以取两个枚举值:FlushModeType.AUTO为自动更新数据库记录,FlushMode Type。COMMIT为直到提交事务时才更新数据库记录

setHint(String hintName, Object value)

设置与查询对象相关的特定供应商参数或提示信息。参数名及其取值需要参考特定 JPA 实现库提供商的文档。如果第二个参数无效将抛出IllegalArgumentException异常。

setParameter(int position, Object value)

为查询语句的指定位置参数赋值。Position 指定参数序号,value 为赋给参数的值。

setParameter(int position, Date d, TemporalType type)

为查询语句的指定位置参数赋 Date 值。Position 指定参数序号,value 为赋给参数的值,temporalType 取 TemporalType 的枚举常量,包括 DATE、TIME 及 TIMESTAMP 三个,,用于将 Java 的 Date 型值临时转换为数据库支持的日期时间类型(java.sql.Date、java.sql.Time及java.sql.Timestamp)

–setParameter(int position, Calendar c, TemporalType type)

为查询语句的指定位置参数赋 Calenda r值。position 指定参数序号,value 为赋给参数的值,temporalType 的含义及取舍同前。

setParameter(String name, Object value)

为查询语句的指定名称参数赋值。

setParameter(String name, Date d, TemporalType type)

为查询语句的指定名称参数赋 Date 值。用法同前

setParameter(String name, Calendar c, TemporalType type)

为查询语句的指定名称参数设置CalendarnameIllegalArgumentException异常。

Select语句:

from是必选子句,如果不想返回重复实体,可以使用关键字distinct来进行修饰

查询所有实体:select o from Order o

调用 EntityManager的createQuery()方法可创建查询对象,接着调用Query接口的getResultList()方法就可获得查询结果集

where子句用于指定查询条件,也支持包含参数的查询,但是参数名前必须冠以冒号。同样也可以使用参数序号

order by子句,可以对查询结果镜像排序,默认为升序,asc(升序)desc(降序)

group by子句与聚合查询,通常的聚合函数:AVG,COUNT,MAX,MIN

having子句用于对group by分组设置约束条件,用法与where子句基本相同,having子句作用于分组,用于选择满足条件的组,其条件表单时中通常会使用聚合函数

关联查询。默认左关联,

子查询:常出现在any,all,exist s表达式中用于集合匹配查询

JPQL函数:字符串处理函数,算术函数和日期函数

UPDATE语句:用于执行数据更新操作,主要用于针对单个实体类的批量更新

DELETE语句:用于执行数据更新操作

7、整合Spring

三种整合方式

LocalEntityManagerFactoryBean:适用于那些仅使用 JPA 进行数据访问的项目,该 FactoryBean 将根据JPA PersistenceProvider 自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息,这种方式最简单,但不能设置Spring 中定义的DataSource,且不支持 Spring管理的全局事务

从JNDI中获取:用于从 Java EE 服务器获取指定的EntityManagerFactory,这种方式在进行 Spring 事务管理时一般要使用 JTA 事务管理

LocalContainerEntityManagerFactoryBean**:适用于所有环境的 FactoryBean,能全面控制 EntityManagerFactory 配置,如指定 Spring 定义的 DataSource 等等。