Spring Data JPA
jpa操作的操作步骤
基础配置
-
在配置自动创建数据库表时:
- create 程序运行时创建数据库表(如果有表则删除在创建,没有则创建)
- update 程序运行时出创建表(有表不会在创建)
- none 不创建
常用注解说明
-
@Entity(声明实体类)
-
@Table(配置实体类和表的映射关系)
-
@Id(声明主键)
-
@GeneratedValue(配置主键的生成策略)
- strategy(属性)=GenerationType.IDENTITY 自增 注:数据库支持自增
- GenerationType.SEQUENCE 序列 注:支持序列oracle数据库使用
- GenerationType.TABLE 注:jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增
- GenerationType.AUTO 注:由程序自动的帮助我们选择主键生成策略
-
@GenericGenerator注解----自定义主键生成策略
-
@Column(配置属性和字段的映射的关系)
查询
1、Dao层
-
继承JpaRepository<操作的实体类类型,实体类中主键属性的类型>
- 封装了基本的CRUD操作
-
继承JpaSpecificationExecutor<操作的实体类类型>
- 封装了复杂的查询(分页)
-
基本查询
2、InvocationHandler 动态代理的方式
- 调用SimpleJpaRepository里面的方法,后在对base-package包下的dao接口进行动态代理增强。
注:通过JdkDynamicAopProxy的invoke方法创建了一个动态代理对象
SimpleJpaRepository当中封装了jpa的操作,借助jpa 的api完成数据库的curd
通过hibernate完成数据库的操作,底层封装的jdbc
3、复杂查询
-
Transactional事务
-
@Rollback:@Rollback(value=false/true)设置是否自动回滚
-
findOne与getOne的区别:
- findOne:立即加载
- getOne:延迟加载,需要加入事务注解,什么时候用什么时候查询
-
-
jpql查询方式(特点:语法或关键字和sql语句类似,查询的是类和类中的属性)
-
需要将jpql语句配置到接口方法上:
-
特有的查询:需要在dao接口上配置方法
-
在新添加的方法上,使用注解的形式配置jpql查询语句
-
注解:@Query (value=“ ”)
对多个占位符参数:赋值的时候,默认情况下,占位符的位置需要和方法的参数中的位置保持一致。
可以指定占位符的参数位置:?索引的方式,指定次占位的取值来源
-
-
-
sql语句的查询
-
特有的查询:需要dao接口上的配置方法
-
在新添加的方法上,使用注解的形式配置sql查询语句
-
注解:@Query
- value::jpql语句 | sql语句
- nativeQuery:false(使用jpql查询)| true(使用本地查询:sql查询)是否使用本地查询
-
-
方法名称规则查询
-
是对jpql查询,更加深入的一层封装
-
需要安装springdatajpa提供的方法名称规则定义方法,不需要在配置jpql语句,完成查询findBy开头:代表查询
-
对象中属性的名称(首字母大写)
-
含义:根据属性名进行查询
-
-
多表查询
1、Specifications动态查询
-
动态查询完成多条件拼接
-
模糊匹配查询列表
-
排序
-
分页
2、多表之间的关系和操作多表的操作步骤
表关系:
-
一对一
-
一对多
- 一的一方:主表
- 多的一方:从表
- 外键:需要在从表上新建一列作为外键,他的取值来源于主表的主键
-
多对多
- 中间表:中间表中最少应该由两个字段组成,这两个字段作为外键只想两张表的主键,又组成联合主键
实体类中的关系
- 包含关系:可以通过实体类中的包含关系描述表关系
- 继承关系
分析步骤
- 明确表关系
- 确定表关系(描述、外键|中间表)
- 编写实体类,在实体类中描述表关系(包含关系)
- 配置映射关系
3、完成多表操作
-
在实体类中配置一对多关系
-
例:描述关系:
-
配置关系:使用注解形式配置
-
声明关系:@OneToMany(配置一对多)
@JionColumn配置外键(中间表)
-
-
@OneToMany(targetEntity = 对方对象的字节码对象)
@JionColumn(name ="外键字段名称",referencedCoulumnName ="参照的主表的主键字段名称" )
private Set<linkman> l = new HashSet<>();
- 在一的一方放弃维护全关系
@OneToMany(mappedBy = "customer")
//mappedBy:对方配置关系的属性名称
private Set<linkman> l = new HashSet<>();
-
配置实体类中的多对一关系
-
配置关系:使用注解形式配置
-
声明关系:@OneToMany(配置一对多)
@JionColumn配置外键(中间表)
-
-
@OneToMany(targetEntity = 对方对象的字节码对象)
@JionColumn(name ="外键字段名称",referencedCoulumnName ="参照的主表的主键字段名称" )
private Customer customer;
- 添加
在impl中操作时需要加入配置关系:一对多
customer.getLinkman().add(linkman)
多对一
linkman.setCustomer(customer)
- 删除
-
级联
配置级联关系
@OneToMany(mappedBy = "customer",cascade = "CascadeType.All")
//mappedBy:对方配置关系的属性名称
//cascade:配置级联关系
private Set<linkman> l = new HashSet<>();
多对多操作
-
明确表关系:多对多关系
-
确定表关系(描述、外键|中间表):中间表
-
编写实体类,在实体类中描述表关系(包含关系)
用户:包含角色的集合
角色:包含用户的集合
-
配置映射关系
角色到用户的多对多关系
用户到角色的多对多关系
多对多的关系中,被动方放弃维护权
对象导航查询
- 一的一方查询多的一方
默认使用的是延迟加载的形式查询,调用get方法并不会立即发送查询,而是在使用关联对象的时候才会查询
如果不想用延迟加载:修改配置,将延迟加载改为立即加载,fetch 需要配置到多表映射的注解上
例:对象导航查询,此客户下的所有联系人
Set<Linkman> l = customer.getLinkmans();
-
多的一方查询一的一方
默认立即加载,fetch = FetchType.LZAY
查询机制:
超类
-
@MappedSuperclass(用在父类上面的,用来标识父类)
-
用法:在项目开发中使用JPA的@MappedSuperclass注解将实体类的多个属性分别封装到不同的非实体类中。通过这个注解,我们可以将该实体类当成基类实体,它不会隐射到数据库表,但继承它的子类实体在隐射时会自动扫描该基类实体的隐射属性,添加到子类实体的对应数据库表中。例如,数据库表中都需要id来表示编号,id是这些映射实体类的通用的属性,交给jpa统一生成主键id编号,那么使用一个父类来封装这些通用属性,并用@MappedSuperclas标识。
-
注意:
- 标注为@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。
- 标注为@MappedSupclass的类不能在标注@Entity或@Table注解,也不需要
-