Spring Data JPA 是 Spring 提供的一个用于简化数据访问层的框架,基于 Java 持久化 API (JPA) 的规范。它允许开发者通过使用注解和接口声明的方式,轻松地实现对关系型数据库的访问和操作。
它的出现简化了数据访问层的开发,提供了一种更方便的方式来处理数据库交互。通过使用注解和接口声明的方式,开发者可以更专注于业务逻辑而不是繁琐的数据访问层代码。
需要在 pom.xml 中添加 Jpa 的依赖(如果使用 Gradle 的话,则需要添加对应的依赖)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
public interface UserRepository extends JpaRepository<User, Integer> {
}
此类继承自 JpaRepository
,它又继承自 ListCrudRepository
。而 ListCrudRepository
又继承自 CrudRepository
。因此 UserRepository 则拥有了一组基础的 CRUD 方法供我们使用。
public interface JpaRepository<T, ID> extends ListCrudRepository<T, ID>
public interface ListCrudRepository<T, ID> extends CrudRepository<T, ID>
public interface UserRepository extends JpaRepository<User, Integer> {
// 自定义一个通过名字查询用户信息的方法
User findByName(String name);
}
如果,基础的 CRUD 方法无法满足我们的时候,我们就可以自定义查询方法了
创建一个 User 实体类,并使用 @Entity 注解标注它是一个实体,此处使用了 name 属性去重定义了表名为 t_user,如果没有重定义的话,则表名和类名相同
@Entity(name = "t_user")
public class User {
@Id
private Integer id;
private String name;
private Integer age;
}
插入一条
@GetMapping("insertOne")
public String insertOne() {
User user = new User(1, "cheney", 11);
userRepository.save(user);
return "一个用户信息保存成功";
}
此方法,将向数据库中插入一条用户信息
插入多条
@GetMapping("insertMany")
public String insertMany() {
List<User> users = new ArrayList<>();
users.add(new User(2, "aaa", 11));
users.add(new User(3, "bbb", 11));
userRepository.saveAll(users);
return "一组用户信息保存成功";
}
此方法,将向数据库中插入两条用户信息
查询全部
@GetMapping("selectAll")
public String selectAll() {
List<User> users = userRepository.findAll();
StringBuilder sb = new StringBuilder();
for (User user : users) {
sb.append(user).append("</br>");
}
return sb.toString();
}
此方法,将从数据库中查询全部用户信息
更新
@GetMapping("update")
public String update() {
// 修改用户信息
User user = new User(1, "cheney", 22);
userRepository.save(user);
// 查询修改后的结果
return this.getByName();
}
此方法,将更新指定的用户信息
通过自定义方法查询
@GetMapping("getByName")
public String getByName() {
User user = userRepository.findByName("cheney");
return user.toString();
}
此方法,将从数据库中通过名字去查询用户信息
删除
@GetMapping("delete")
public String delete() {
// 删除 用户ID是3的用户信息
userRepository.deleteById(3);
// 查询删除后的结果
return this.selectAll();
}
此方法,将从数据库中删除指定用户信息
启动服务,然后分别调用下面的请求,验证一下我们的执行结果
使用浏览器执行 insertOne 请求
使用浏览器执行 insertMany 请求
%88%98%E3%80%9107%20JPA.assets%2F1703590022774.png&pos_id=img-ERPBOg6B-1703590609987)
使用浏览器执行 selectAll 请求
使用浏览器执行 update 请求
使用浏览器执行 getByName 请求
使用浏览器执行 delete 请求
简化开发
Spring Data JPA 提供了 Repository 接口和方法命名规则,开发者无需手动实现常见的 CRUD 操作,大大简化了数据访问层的开发。
自动化查询生成
Spring Data JPA 根据方法名命名规则自动生成查询语句,减少了手动编写 SQL 或 JPQL 查询语句的工作量。
支持动态查询
提供了 Specification 对象,支持动态查询条件的构建,使得动态查询变得更加灵活。
内置分页和排序
Spring Data JPA 内置了分页和排序的支持,通过 Pageable 对象进行传递,方便进行分页查询。
事务管理
Spring Data JPA 自动为 Repository 方法添加了事务管理,确保数据库操作是原子的,同时与 Spring 的声明式事务管理集成良好。
支持多种数据源
Spring Data JPA 支持多种数据源,包括关系型数据库和 NoSQL 数据库,提供了一致的数据访问抽象。
强大的关联关系支持
支持 JPA 注解,轻松实现实体类之间的关联关系,包括一对一、一对多、多对多等。
集成 Spring 生态
作为 Spring 生态的一部分,与其他 Spring 组件(如 Spring Boot)集成良好,使用方便。
学习曲线
尽管 Spring Data JPA 简化了数据访问层的开发,但对于初学者来说,仍然需要理解 JPA 规范和 Spring Data JPA 的一些特性,学习曲线较陡。
不适合复杂查询
对于一些复杂的查询需求,特别是涉及多表联合查询和复杂逻辑的情况,自动生成的查询语句可能无法满足需求,需要手动编写 JPQL 或者原生 SQL。
不适用于所有数据库
尽管 Spring Data JPA 提供了一致的数据访问抽象,但并不是所有数据库都能完全支持 JPA 规范,某些数据库可能需要特定的配置和调整。
性能考虑
自动生成的查询语句可能不是最优化的,需要开发者关注和优化查询性能。
不支持部分更新
Spring Data JPA 在执行更新操作时通常是整个实体对象更新,不支持部分字段的更新。
强依赖于 JPA 规范
如果需要使用非 JPA 规范的数据库特性,可能需要绕过 Spring Data JPA 直接使用原生的 JDBC 或其他持久化框架。
https://github.com/cheney09/spring-practical-combat/tree/main/07/demo
本文从 Spring Data JPA 出现的原因来出发,通过添加进行依赖并通过几个例子讲解了基础CRUD方法和自定义方法,从而使得可以更加清楚的了解它为我们提供了什么便利。