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);
}
}