Spring data之jpa
2022-12-14 17:36:32 0 举报
AI智能生成
登录查看完整内容
Spring data之jpa
作者其他创作
大纲/内容
不同数据库进行了统一,提升开发效率,不同场景提供不同的模板,快速开发
为什么要用Spring Data
模板制作
对象/数据存储映射
Repository支持
Spring Data 主要特性
spring Data简介
都根据数据库操作有关,JPA是JDBC的升华,升级版
JDBC和JPA都是一组规范接口
都是由SUN官方推出的
相同处
JDBC是由各个关系型数据库实现的,JPA是由ORM框架实现
JDBC使用SQL语句和数据库通信。JPA用面向对象方式,通过ORM框架来生成SQL,进行曹操。
JPA在JDBC之上的,JPA也要依赖JDBC才能操作数据库。
不同处
什么只JPA?于JDBC的区别
需要面向SQL语句来操作数据库
数据库的移至性不高,不同数据库的SQL语句无法通用。
java对象和数据库类型的映射麻烦
JDBC存在的问题
JPA全称Java Persistence API,是Sun官方提出的一种ORM规范。O:Object R:Relational M:Mapping
Spring data jpa是spring提供的一套简化JPA开发的框架,按照约定好的规则进行【方法命名】去写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。
JPA简介
简化持久化操作的开发工作:让开发者从繁琐的JDBC和SQL代码中解脱出来,直接面向对象持久化操作。
Sun希望持久化技术能够统一,JPA进行持久化可以随意切换数据库
作用
ORM映射元数据:JPA支持XML和注解两种元数据的形式,元数据扫描对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;如:@Entity、@Table、@Id与@Column等注解。Table:映射表,写在实体类上面,告诉某个实体类映射那一张表id:映射当前属性为主键idColumn:映射当前属性列名
JPA的API:用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。如:entityManager.merge(T t);
JPQL查询语言:通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。如果:from Student s where s.name = ?
规范:
关系图
JPA采用一种规范进行ORM映射,当java调用数据库操作的时候,JPA通过HIBERNATE的实现在结合ORM的一个映射生成SQL语句,在结合JDBC进行一个数据的操作
JPA与HIBERNATE的关系
小巧、方便、高效、简单、直接、半自动半自动的ORM框架小巧:mybatis就是jdbc封装场景:在业务比较复杂系统进行使用
mybatis
强大、方便、高效、(简单)复杂、绕弯子、全自动全自动的ORM框架强大:根据ORM映射生成不同SQL场景:在业务相对简单的系统进行使用
hibernate
mybatis与hibernate的区别
Spring Data JPA简介
刚创建出来,没有与entityManager发生关系,没有被持久化,不处于entityManager中的对象
临时状态:
与entityManager发生关系,已经被持久化,可以把持久化状态当做数据库记录
持久状态:
执行remove方法,事物提交之前
删除状态:
游离装态就是提交到数据库之后,事务commit后实体的状态,因为事务已经提交了,此时实体的属性任你如何改变,也不会同步到数据库,因为游离不在持久化上下文中
游离状态:
public void persist(Object entity) persist方法可以将实例转换为managed(托管)状态。在调用flush()方法或提交事物后,实例将会被插入到数据库中。 对不同状态下的实例A,persist会产生以下操作: 1. 如果A是一个new状态的实体,它将会转为managed状态; 2. 如果A是一个managed状态的实体,它的状态不会发生任何改变。但是系统仍会在数据库执行INSERT操作; 3. 如果A是一个removed(删除)状态的实体,它将会转换为受控状态; 4. 如果A是一个detached(分离)状态的实体,该方法会抛出IllegalArgumentException异常,具体异常根据不同的 JPA实现有关。
persist插入操作
public void merge(Object entity) merge方法的主要作用是将用户对一个detached状态实体的修改进行归档,归档后将产生一个新的managed状态对象。对不同状态下的实例A,merge会产生以下操作: 1. 如果A是一个detached状态的实体,该方法会将A的修改提交到数据库,并返回一个新的managed状态的实例A2; 2. 如果A是一个new状态的实体,该方法会产生一个根据A产生的managed状态实体A2; 3. 如果A是一个managed状态的实体,它的状态不会发生任何改变。但是系统仍会在数据库执行UPDATE操作; 4. 如果A是一个removed状态的实体,该方法会抛出IllegalArgumentException异常。
merge修改操作
public void refresh(Object entity) refresh方法可以保证当前的实例与数据库中的实例的内容一致。 对不同状态下的实例A,refresh会产生以下操作: 1. 如果A是一个new状态的实例,不会发生任何操作,但有可能会抛出异常,具体情况根据不同JPA实现有关; 2. 如果A是一个managed状态的实例,它的属性将会和数据库中的数据同步; 3. 如果A是一个removed状态的实例,该方法将会抛出异常: Entity not managed 4. 如果A是一个detached状态的实体,该方法将会抛出异常。
refresh查询操作
public void remove(Object entity) remove方法可以将实体转换为removed状态,并且在调用flush()方法或提交事物后删除数据库中的数据。 对不同状态下的实例A,remove会产生以下操作: 1. 如果A是一个new状态的实例,A的状态不会发生任何改变,但系统仍会在数据库中执行DELETE语句; 2. 如果A是一个managed状态的实例,它的状态会转换为removed; 3. 如果A是一个removed状态的实例,不会发生任何操作; 4. 如果A是一个detached状态的实体,该方法将会抛出异常。
remove删除操作
四种状态之间的操作
jpa的四种状态
依赖
实体
配置文件
测试类
导入hibernate和数据库依赖
写实体类,类上使用@Entity和@Table注解属性上使用@Column和@Id注解@Table对应的是数据的表名@Column对应的是数据库字段名
编写hibernate配置文件,driver,url,username,password
// Session工厂 configure为配置文件StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure(\"/hibernate.cfg.xml\").build();
//根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的session工程sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();
//创建Session对象Session session = sf.openSession()
//通过session对象开启事务Transaction transaction = session.beginTransaction();
//创建实体类对象,给属性设置值,调用save方法进行添加Customer customer = new Customer();customer.setCustName(\"xxx\");session.save(customer);
添加
查询
Customer customer = new Customer();customer.setCustId(1L);customer.setCustName(\"东西不会用,证明你还不够卷\");//save只更新不创建//session.save(customer);//当值存在就更新,不存在就创建 session.saveOrUpdate(customer);
更新
//创建实体类对象后设置id只,然后调用delete方法Customer customer = new Customer();customer.setCustId(2L);//删除 session.delete(customer);
删除
//调用createQuery方法传入hql语句和实体类,填充hql语句中的值,最后调用getResultList进行查询String hql=\"FROM Customer where custId=:id\
hql查询方式
CRUD操作
//调用commit方法进行提交事务transaction.commit();
关闭session
测试crud
步骤:
引入hibernate和数据库的依赖
创建实体类
编辑配置文件
//1.加载配置文件,创建entityManagerFactory new Configuration.buildSessionFactory();factory= Persistence.createEntityManagerFactory(\"hibernateJPA\");
//2.获取entityManager对象 sessionFactory.openSession();EntityManager entityManager = factory.createEntityManager();//3.创建事务EntityTransaction transaction = entityManager.getTransaction();transaction.begin();//开启事务
获取EntityManager对象
//调用persist进行插入操作Customer customer = new Customer();customer.setCustName(\"只要卷不死就往死里卷\");entityManager.persist(customer);//持久化
C
R
//调用merge进行修改,传入的对象中有id且在数据库中存在就进行修改//否则就是添加操作Customer customer = new Customer(); // customer.setCustId(1L); customer.setCustName(\"加油\"); /** * 如果指定了主键: * 更新:1。先查询 看是否有变化 * 如果有变化 更新 如果没有变化就不更新 * 如果没有指定主键: * 插入 */ entityManager.merge(customer);
String jpql=\"UPDATE Customer set custName=:name where custId=:id \"; entityManager.createQuery(jpql) .setParameter(\"name\
jpql语句修改
String sql=\"UPDATE tb_customer set cust_name=:name where cust_id=:id \"; entityManager.createNativeQuery(sql) .setParameter(\"name\
sql语句修改
U
D
//提交事务transaction.commit();
CRUD
hibernateJPA
//find为立即查询Customer customer = entityManager.font color=\"#f44336\
//getRefernce为延迟查询,只有用到的时候就查询Customer customer = entityManager.font color=\"#f44336\
openJpa
代码
JPA的四种状态
JPA
hibernate与JPA基本使用代码
代码示例文件
hibernate与JPA基本使用
在父项目中添加springdata管理子项目jpa版本的依赖
子项目中添加依赖
添加一个实体类
创建Spring.xml配置文件
持久层创建一个类继承CrudRepository<实体类,id类型>
测试类添加@ContextConfiguration(\"配置文件路径\")并注入持久层类,CRUD直接调用持久层中的方法
xml配置文件方式
创建一个配置类,类上面加@Configuration,@EnableJpaRepositories(basePackages = \"持久层包位置\")和事务注解
测试类添加@ContextConfiguration(classes = 配置类.class)并注入持久层类,CRUD直接调用持久层中的方法
配置类方式
Spring Data repository抽象的目标是显示着减少为各种持久性存储实现数据访问层所需要的样板代码量。
//用来插入和修改 有主键就是修改 没有就是新增//获得插入后自增id,获得返回值<S extends T> S save(S entity);
//通过集合保存多个实体<S extends T> Iterable<S> saveAll(Iterable<S> entities);
//通过主键查询实体Optional<T> findById(ID id);
//通过主键查询是否存在 返回booleanboolean existsById(ID id)
//查询所有Iterable<T> findAll()
//通过集合的主键 查询多个实体 返回集合Iterable<T> findAllById(Iterable<ID> ids);
//查询总数量long count();
//根据id进行删除void deleteById(ID id);
//根据实体进行删除void delete(T entity);
//删除多个void deleteAllById(Iterable<? extends ID> ids);
//删除多个传入集合实体void deleteAll(Iterable<? extends T> entities);
//删除所有void deleteAll();
CrudRepository
//分页查询Page<Customer> all = repository.findAll(font color=\"#f44336\
//排序,降序//字符串硬编码,缺点,类型名换了,它也得换Sort sort = Sort.by(\"custId\").descending();Iterable<Customer> all = repository.findAll(sort);System.out.println(all);
//根据类型字段排序Sort.TypedSort<Customer> sortType = Sort.sort(Customer.class);Sort sort = sortType.by(Customer::getCustId).descending();//有多个条件可以加andIterable<Customer> all = repository.findAll(sort);System.out.println(all);
//分页排序Sort.TypedSort<Customer> sortType = Sort.sort(Customer.class);Sort sort = sortType.by(Customer::getCustId).descending();//有多个条件可以加andPage<Customer> all = repository.findAll(font color=\"#f44336\
继承CrudRepository的子接口PagingAndSortingRepository
Spring Data Repositories的使用和方法介绍
02springdata-jpa的使用示例
Spring Data JPA的使用方式
查询如果返回单个实体 就用pojo接收,如果是多个需要通过集合
?数字
索引:
:参数名 结合@Param注解指定参数名字
具名:
参数数据设置方式
要加上事务的支持
如果是插入方法:一定只能在hibernate下才支持(Insert into ...select)先从数据库中查出来在插入
//通常会放在业务逻辑层上面去声明@Transactional
//通知springdatajpa是增删改的操作@Modifying
加上两个注解
增删改
@Query
JPQL
SQL
测试代码
jpql与原生SQL
主题关键字表
谓词关键字表
修饰符关键字表
JPA规范命名方式表
以命名规范进行命名并传入相应的参数
需要使用到持久层的地方直接调用方法传入参数即可
列如: //根据名称查询 List<Customer> findByCustName(String custName); //判断名称是否存在 boolean existsByCustName(String custName); //根据id删除 @Transactional @Modifying int deleteByCustId(Long custName); //模糊查询 List<Customer> findByCustNameLike(String custName);
持久层
使用方式
代码示例
规定方法名
持久层继承PagingAndSortingRepository接口和QueryByExampleExecutor接口
创建查询条件
通过Example构建查询条件
调用findAll方法传入查询条件
//通过匹配器 对条件行为进行设置 ExampleMatcher matcher = ExampleMatcher.matching() .withIgnorePaths(\"custAddress\")//设置忽略的属性 //使用withMatcher时该设置无效// .withIgnoreCase(\"custAddress\")//设置忽略大小写// .withStringMatcher(ExampleMatcher.StringMatcher.ENDING)//对所有条件按照结尾匹配// .withMatcher(\"custAddress\
通过匹配器进行条件限制
代码示例:
通过匹配器对条件行为进行设置时,withIgnoreCase忽略大小写和withMatcher针对单个条件进行限制,同时使用时withlgnoreCase忽略大小写该设置会实现,此时需要在withMatcher针对单个条件进行限制后加上ignoreCase忽略大小写设置
注意:
Query by Example
导入querydsl-jpa和querydsl-apt依赖
导入maven插件
maven编译
去设置文件夹类型
弹出框后
如queries文件夹的颜色为黄色就需要改变一下文件夹类型
编译好后的文件
点击idea:maven -》compile
测试类注入持久层的接口
构建添加,QCustomer customer = QCustomer.customer;直接通过Q类.customer获取Q类对象,通过对象名点属性名进行操作
调用持久层的方法把条件进行传入
使用方式:
代码:
通过Querydsl
测试类调用findAll方法传入Specification<实体类>匿名类,重写方法方法上有三个参数:root:获取列,query:条件进行组合,criteriaBuilder:相当于where设置各种条件
设置单个条件
设置多个条件
动态条件查询
动态条件+分组分页查询
通过Specifications
自定义Jpa示例
代码示例文件:
JPA自定义操作
创建两个实体类,一个实体类里面属性为另一个实体的对象
在对象上添加@OneToOne注解和@JoinColumn注解
@JoinColumn注解中设置name属性为另一个实体的id设置外键
cascade 设置关联操作 ALL 所有持久化操作 PERSIST 只有插入才会执行关联操作 MERGE 只有修改才会执行关联操作 REMOVE 只有删除才会执行关联操作fetch 配置查询的加载方式 FetchType.LAZY 为懒加载(直到用到对象才会进行查询,因为不是所有的关联对象 都需要用到) FetchType.EAGER 立即加载(默认方式)orphanRemoval 关联移除(通常在修改的时候会用到) 一旦把关联的数据设置null,或者修改为其他的关联数据,如果想删除关联数据,就可以设置truetargetEntity 指定关联的属性是哪个一个,默认关联,一般不需要设置optional 限制关联的对象是否可以为空 true 可以为空(默认) false 不能为空
@OneToOne可以设置cascade:设置关联操作,fetch:查询加载方式,orphanRemvoal:删除未被关联的数据
直接调用Repository层方法进行增删改查
Repository层
Customer
Account
pojo类
单向一对一双向一对一
创建两个实体,在A实体里面定义B实体对象的集合,在上面添加@OneToMany注解
设置@OneToMany注解里面的属性cascade,一对多默认是懒加载
测试类,CRUD使用方式一致
Message
一对多
创建B实体的Repository层
B实体创建A实体对象并加上@ManyToOne注解和@JoinColumn注解
多对一
创建两个实体
创建两个实体的Repository层
测试类注入两个持久层
CustomerRepository
RoleRepository
Repository
Role
单向多对多
多表关联
在并发情况下对共享数据进行读写,造成数据错乱问题
乐观锁
在实体类里加:private @Version Long version;
使用步骤:
hibernate中的乐观锁
每次操作数据库的时候有些字段的数据需要进行更改,如:更新时间,更新人
概述:
添加spring-aspects依赖
首先声明实体类,在类上加上注解@EntityListeners(AuditingEntityListener.class)
在启动类上加注解@EnableJpaAuditing
在需要的字段上加上@CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy等注解
在配置类中添加AuditorAware<用户字段类型>的Bean
依赖:
配置类:
实体:
测试类:
审计
Repository原理
Spring整合Jpa原理
Jpa底层原理
springdata.zip
进度
Spring Data之JPA
0 条评论
回复 删除
下一页