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