我們在開發中經常出現動態查詢,例如淘寶的商品查詢,這類查詢動態條件,如果用原生的sql語句,很難處理,但是jpa爲我們提供的動態查詢接口:public interface JpaSpecificationExecutor<T>,這幾接口有如下方法:
public interface JpaSpecificationExecutor<T> {
/**
* Returns a single entity matching the given {@link Specification}.
*
* @param spec
* @return
*/
T findOne(Specification<T> spec);
/**
* Returns all entities matching the given {@link Specification}.
*
* @param spec
* @return
*/
List<T> findAll(Specification<T> spec);
/**
* Returns a {@link Page} of entities matching the given {@link Specification}.
*
* @param spec
* @param pageable
* @return
*/
Page<T> findAll(Specification<T> spec, Pageable pageable);
/**
* Returns all entities matching the given {@link Specification} and {@link Sort}.
*
* @param spec
* @param sort
* @return
*/
List<T> findAll(Specification<T> spec, Sort sort);
/**
* Returns the number of instances that the given {@link Specification} will return.
*
* @param spec the {@link Specification} to count instances for
* @return the number of instances
*/
long count(Specification<T> spec);
}
代碼實現:
1.先在dao層繼承這個接口
public interface UserRepository extends JpaRepository<User, Long> ,JpaSpecificationExecutor<User>{}
2.然後在新建一個Criteria 文件,UserCriteria,代碼如下:
public class UserCriteria implements Serializable {
private static final long serialVersionUID = 1L;
private LongFilter id;
private IntegerFilter name;
private IntegerFilter pwd;
//get ...
//set ...
//toSting
}
這裏需要注意時間類型不支持Date,其他的都用包裝類型
3.service層
@Service
@Transactional
public class UserService {
private final Logger log = LoggerFactory.getLogger(UserService1.class);
@Autowired
private UserRepository userRepository;
public Page<User> findAll(UserCriteria userCriteria,Pageable pageable){
final Specifications<User> specification = createSpecification(userCriteria);
return userRepository.findAll(specification, pageable);
}
public Specifications<User> createSpecification(UserCriteria criteria) {
Specifications<User> specification = Specifications.where(null);
if (criteria != null) {
if (criteria.getId() != null) {
specification = specification.and(buildRangeSpecification(criteria.getId(), User_.id));
}
if (criteria.getName() != null) {
specification = specification.and(buildRangeSpecification(criteria.getName(), User_.name));
}
if (criteria.getPwd() != null) {
specification = specification.and(buildRangeSpecification(criteria.getPwd(), User_.pwd));
}
}
return specification;
}
}
4.web層
@RestController
@RequestMapping("/api")
public class AccountResource {
private final Logger log = LoggerFactory.getLogger(AccountResource.class);
@Autowired
private UserRepository userRepository;
public Object findAll(
UserCriteria criteria,
Pageable pageable
){
return userRepository.findAll(criteria,pageable)
}
}
這樣就基本可以了
這裏面傳值也比較奇葩,傳值方式大概有如下: