下面我将详细讲解“Spring Data JPA实现动态查询的两种方法”的完整攻略。
一、介绍
Spring Data JPA是Spring家族中非常流行的项目之一,它使我们能够更方便地使用JPA进行持久层开发。除了基本的CRUD外,Spring Data JPA还提供了许多方便的查询方法。但是,有时候我们需要根据请求参数来动态构建查询条件,这就需要使用Spring Data JPA实现动态查询。本文将介绍两种通过Spring Data JPA实现动态查询的方法。
二、方法一:使用JPA(Criteria API)
JPA Criteria API是一种类型安全、面向对象的查询模式。通过使用它,我们可以在运行时动态创建类型安全查询。下面看下如何使用JPA Criteria API实现动态查询。
1. 实体类
下面给出一个简单的实体类作为演示:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title")
private String title;
@Column(name = "author")
private String author;
// 省略getter/setter
}
2. DAO层
我们定义一个BookRepository接口,继承JpaRepository
,该接口已经提供了非常丰富的方法。我们还需要定义一个实现类BookRepositoryImpl
,该类实现一个名为dynamicQuery
的动态查询方法。
public interface BookRepository extends JpaRepository<Book, Long>, JpaSpecificationExecutor<Book> {}
public class BookRepositoryImpl {
@PersistenceContext
private EntityManager entityManager;
public List<Book> dynamicQuery(String title, String author) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Book> query = cb.createQuery(Book.class);
Root<Book> root = query.from(Book.class);
List<Predicate> predicateList = new ArrayList<>();
if (!StringUtils.isEmpty(title)) {
predicateList.add(cb.equal(root.get("title"), title));
}
if (!StringUtils.isEmpty(author)) {
predicateList.add(cb.equal(root.get("author"), author));
}
Predicate[] predicates = predicateList.toArray(new Predicate[predicateList.size()]);
query.where(predicates);
List<Book> bookList = entityManager.createQuery(query).getResultList();
return bookList;
}
}
3. 控制器
最后一个是控制器,我们在控制器中定义一个响应GET请求的动态查询接口。
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookRepositoryImpl bookRepository;
@GetMapping
public List<Book> dynamicQuery(String title, String author) {
return bookRepository.dynamicQuery(title, author);
}
}
4. 测试
我们使用Postman向http://localhost:8080/books?title=Spring&author=Tom
发送GET请求即可。
三、方法二:使用QueryDSL
QueryDSL是一个流行的查询框架,它主要用于JPA、Hibernate、MongoDB。它基于类型安全的Java语法,使得我们可以轻松地编写复杂的动态查询。下面,我们来看一下如何在Spring Boot应用程序中使用QueryDSL进行动态查询。
1. 添加依赖
在pom.xml文件中添加以下依赖:
<dependencies>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>5.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>5.3.0</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
<version>5.3.0</version>
</dependency>
</dependencies>
2. 实体类
在实体类Book上添加注解@Entity
和@Table
,并添加以下代码:
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title")
private String title;
@Column(name = "author")
private String author;
// 省略getter/setter
}
3. DAO层
首先,定义一个接口BookRepository
,继承JpaSpecificationExecutor
。然后,新建一个接口BookQueryRepository
,它继承QuerydslPredicateExecutor
,该接口可用于动态查询。
public interface BookRepository extends JpaRepository<Book, Long>, JpaSpecificationExecutor<Book> {}
public interface BookQueryRepository extends QuerydslPredicateExecutor<Book> {}
4. 实现类
我们需要一个查询类BookQuery
,它用于获取查询参数,并构建Predicate(谓词)。Predicate由QueryDSL生成,是一个条件谓词,代表查询的条件(类似于JPA Criteria)。
public class BookQuery {
private String title;
private String author;
// 省略getter/setter
}
然后,我们实现一个接口BookQuerydslRepository
。
public interface BookQuerydslRepository {
Page<Book> getBooksWithCriteria(BookQuery bookQuery, Pageable pageable);
}
最后,我们需要实现BookQuerydslRepository
。
public class BookQuerydslRepositoryImpl implements BookQuerydslRepository {
@Autowired
private BookRepository bookRepository;
@Override
public Page<Book> getBooksWithCriteria(BookQuery bookQuery, Pageable pageable) {
QBook qBook = QBook.book;
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(bookQuery.getTitle())) {
builder.and(qBook.title.like("%" + bookQuery.getTitle() + "%"));
}
if (!StringUtils.isEmpty(bookQuery.getAuthor())) {
builder.and(qBook.author.like("%" + bookQuery.getAuthor() + "%"));
}
return bookRepository.findAll(builder, pageable);
}
}
5. 控制器
最后一个是控制器,我们在控制器中定义一个响应GET请求的动态查询接口。
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookQuerydslRepository bookQuerydslRepository;
@GetMapping
public Page<Book> getBooksWithCriteria(BookQuery bookQuery, Pageable pageable) {
return bookQuerydslRepository.getBooksWithCriteria(bookQuery, pageable);
}
}
6. 测试
我们使用Postman向http://localhost:8080/books?title=Spring&author=Tom
发送GET请求即可。
本文介绍了两种使用Spring Data JPA实现动态查询的方法,分别是JPA Criteria API和QueryDSL。它们都是非常好用的动态查询工具。根据不同的需求,可以选择不同的实现方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Data JPA实现动态查询的两种方法 - Python技术站