文章目录
- 1. 定义
- 2. 出现原因
- 3. 添加依赖
- 4. 使用
- 1)创建 Repository 接口
- 2)自定义查询方法(非必须)
- 3)创建实体类
- 4)调用方法
- 5. 验证
- 6. 优点
- 7. 缺点
- 8. 详细代码
- 总结
1. 定义
Spring Data JPA 是 Spring 提供的一个用于简化数据访问层的框架,基于 Java 持久化 API (JPA) 的规范。它允许开发者通过使用注解和接口声明的方式,轻松地实现对关系型数据库的访问和操作。
2. 出现原因
它的出现简化了数据访问层的开发,提供了一种更方便的方式来处理数据库交互。通过使用注解和接口声明的方式,开发者可以更专注于业务逻辑而不是繁琐的数据访问层代码。
3. 添加依赖
需要在 pom.xml 中添加 Jpa 的依赖(如果使用 Gradle 的话,则需要添加对应的依赖)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
4. 使用
1)创建 Repository 接口
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>
2)自定义查询方法(非必须)
public interface UserRepository extends JpaRepository<User, Integer> {
// 自定义一个通过名字查询用户信息的方法
User findByName(String name);
}
如果,基础的 CRUD 方法无法满足我们的时候,我们就可以自定义查询方法了
3)创建实体类
创建一个 User 实体类,并使用 @Entity 注解标注它是一个实体,此处使用了 name 属性去重定义了表名为 t_user,如果没有重定义的话,则表名和类名相同
@Entity(name = "t_user")
public class User {
@Id
private Integer id;
private String name;
private Integer age;
}
4)调用方法
-
插入一条
@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(); }
此方法,将从数据库中删除指定用户信息
5. 验证
启动服务,然后分别调用下面的请求,验证一下我们的执行结果
-
使用浏览器执行 insertOne 请求
-
使用浏览器执行 insertMany 请求
%88%98%E3%80%9107%20JPA.assets%2F1703590022774.png&pos_id=img-ERPBOg6B-1703590609987) -
使用浏览器执行 selectAll 请求
-
使用浏览器执行 update 请求
-
使用浏览器执行 getByName 请求
-
使用浏览器执行 delete 请求
6. 优点
-
简化开发
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)集成良好,使用方便。
7. 缺点
-
学习曲线
尽管 Spring Data JPA 简化了数据访问层的开发,但对于初学者来说,仍然需要理解 JPA 规范和 Spring Data JPA 的一些特性,学习曲线较陡。
-
不适合复杂查询
对于一些复杂的查询需求,特别是涉及多表联合查询和复杂逻辑的情况,自动生成的查询语句可能无法满足需求,需要手动编写 JPQL 或者原生 SQL。
-
不适用于所有数据库
尽管 Spring Data JPA 提供了一致的数据访问抽象,但并不是所有数据库都能完全支持 JPA 规范,某些数据库可能需要特定的配置和调整。
-
性能考虑
自动生成的查询语句可能不是最优化的,需要开发者关注和优化查询性能。
-
不支持部分更新
Spring Data JPA 在执行更新操作时通常是整个实体对象更新,不支持部分字段的更新。
-
强依赖于 JPA 规范
如果需要使用非 JPA 规范的数据库特性,可能需要绕过 Spring Data JPA 直接使用原生的 JDBC 或其他持久化框架。
8. 详细代码
https://github.com/cheney09/spring-practical-combat/tree/main/07/demo
总结
本文从 Spring Data JPA 出现的原因来出发,通过添加进行依赖并通过几个例子讲解了基础CRUD方法和自定义方法,从而使得可以更加清楚的了解它为我们提供了什么便利。