上一篇博文讲了如何在Spring Boot项目中使用JPA做持久层交互,jpa预定义了一些简单的查询。代码中可以直接使用。一些复杂的查询可以在@Query注解里写SQL语句,还有一些聚合查询可以使用聚合查询语句。
- 使用@Query注解自定义简单sql语句做查询大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使 用自定义的SQL来查询,JPA也是完美支持的;在SQL的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying。也可以根据需要添加@Transactional对事务的支持,查询超时的设置等.
@Query("select u from User u where u.phoneNumber in ?1") List<User> findByPhoneNumbers(List<String> phoneNumbers);
- 继承JpaSpecificationExecutor接口,完成动态查询。
JPA极大的帮助了我们更方便的操作数据库,但是,在实际场景中,往往会碰到复杂查询的场景,前端会动态传一些参数请求接口,这时候就需要使用到动态查询了。
首先需要在继承一个接口JpaSpecificationExecutor,需要传入一个泛型,填写你的具体实体对象即可,接下来在repository层实现一个动态的查询方法。
package com.deepflow.travel.tourist.repository; import java.util.ArrayList; import java.util.List; import javax.persistence.criteria.Predicate; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import com.deepflow.travel.tourist.entity.User; /** * Spring Data JPA repository for the User entity. */ public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { User findByPhoneNumber(String phoneNumber); User findByName(String name); @Query("select u from User u where u.phoneNumber in ?1") List<User> findByPhoneNumbers(List<String> phoneNumbers); default Page<User> search(String search, Pageable pageable) { Specification<User> specification = (root, query, criteriaBuilder) -> { List<Predicate> predicates = new ArrayList<>(); predicates.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + search + "%")); return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); }; return findAll(specification, pageable); } }