菜单
本页目录

Spring Data JPA(基于 spring-boot-starter-data-jpa

在对数据库操作上我选择mybatis,所以这个一块就不过多深入学习

优点

  • ORM框架:Spring Data JPA 是标准的 ORM 框架,通过对象和关系映射,使得开发者可以直接操作 Java 对象而不需要编写复杂的 SQL。
  • 事务管理:Spring Data JPA 自动管理事务,并通过 @Transactional 注解简化了事务处理。
  • 简化 CRUD 操作:使用 JPA 的 JpaRepository 接口,基本的 CRUD 操作已经被封装,开发者无需重复编写类似的 SQL 语句。
  • 缓存支持:JPA 内置了一级缓存,支持实体的缓存管理,减少不必要的数据库访问,提高性能。
  • 数据库无关性:JPA 可以适配多种数据库类型,通过使用 Hibernate 等 JPA 实现,能够屏蔽不同数据库之间的差异。

缺点

  • 性能问题:由于其高度的抽象层次,对于复杂查询、批量操作或关联表操作,可能带来性能问题。例如,懒加载与预加载的配置不当可能导致 N+1 查询问题。
  • 复杂查询难度:虽然 JPA 提供了 JPQL,但对于复杂的 SQL 查询(例如多表连接查询或窗口函数),开发者需要编写复杂的 JPQL,或者需要回退到原生 SQL。
  • 学习成本高:JPA 的学习曲线较陡,尤其是理解 Hibernate 的实体生命周期、缓存机制、延迟加载等需要投入较多精力。

Spring Data JPA 是一个基于 JPA 规范的框架,简化了数据库操作。其核心功能包括自动生成 CRUD 操作、查询方法定义和事务管理。以下是 Spring Data JPA 的基本语法和使用方法。

基础语法

1. 实体类(Entity)

实体类是与数据库表对应的类,使用 JPA 注解来映射数据库表字段。

import javax.persistence.*;

@Entity  // 表示这是一个实体类
@Table(name = "books")  // 指定对应的数据库表名
public class Book {

    @Id  // 表示主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)  // 自动生成主键值
    private Long id;

    @Column(name = "title", nullable = false)  // 对应数据库中的列
    private String title;

    @Column(name = "author", nullable = false)
    private String author;

    // Getter 和 Setter 方法
}

2. Repository 接口

Spring Data JPA 提供了 JpaRepository 接口,它封装了常见的 CRUD 操作。开发者只需要定义一个接口,继承 JpaRepository 即可使用。

import org.springframework.data.jpa.repository.JpaRepository;
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
    // 可以在这里定义自定义查询方法
}
  • JpaRepository<Book, Long>:泛型参数表示操作的实体类类型 Book 和主键类型 Long

3. 自动生成 CRUD 操作

继承 JpaRepository 后,Spring Data JPA 自动生成了一些常用的 CRUD 操作,常见的方法包括:

  • save(S entity):保存或更新一个实体。
  • findById(ID id):根据 ID 查找实体。
  • findAll():查询所有实体。
  • deleteById(ID id):根据 ID 删除实体。
  • delete(S entity):删除一个实体。

例如:

@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private BookRepository bookRepository;

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        return bookRepository.save(book);
    }

    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return bookRepository.findById(id).orElse(null);
    }

    @GetMapping
    public List<Book> getAllBooks() {
        return bookRepository.findAll();
    }

    @DeleteMapping("/{id}")
    public void deleteBook(@PathVariable Long id) {
        bookRepository.deleteById(id);
    }
}