之前写过一篇博客
Spring Data JPA 使用JpaSpecificationExecutor实现多条件查询(分页查询和非分页查询)
然后发现还有其他两种写法,会更简便一些。
1、使用JPA自带的findByXxx接口
这种方法其实还比较方便,除了如果字段多的话findByXxx这个方法的名字会很长很长很长…
Containing的用法与like一致.
示例:
顺便说明一下default方法:
在java8以后,接口中可以添加使用default或者static修饰的方法,在这里我们只讨论default方法,default修饰方法只能在接口中使用,在接口中被default标记的方法为普通方法,可以直接写方法体。
实现类会继承接口中的default方法。
@Repository
public interface UserRepository extends JpaRepository<UserDO,Long> {
Page<UserDO> findByUsernameContainingAndUserPasswordContaining(String username, String password, Pageable pageable);
default Page<UserDO> searchUserByCondition(String username, String password, Pageable pageable){
if(username == null){
username = "";
}
if(password == null){
password = "";
}
return findByUsernameContainingAndUserPasswordContaining(username, password, pageable);
}
}
写个类测试一下:
注意要加上注解@RunWith(SpringRunner.class),有了这个注解@Autowired注入的类才能实例化到spring容器中,自动注入才能生效,如果不加这一行会报错NullPointerExecption.
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserTest {
@Autowired
private UserRepository userRepository;
@Test
public void Test1(){
UserDO userDO = new UserDO();
userDO.setUsername("yogi");
userDO.setUserPassword("123456");
userRepository.saveAndFlush(userDO);
List<UserDO> userDOList = userRepository.searchUserByCondition("yog",null, PageRequest.of(0,10)).getContent();
System.out.println(userDOList.size());
}
}
2、使用ExampleMatcher
@Repository
public interface UserRepository extends JpaRepository<UserDO,Long> {
default Page<UserDO> searchUserByCondition2(UserDO userDO, Pageable pageable){
if (StringUtils.isEmpty(userDO.getUserPassword())) {
// 对于数据库中允许为空的字段,需要设置null值,否则传入双引号会被判断成有值
userDO.setUserPassword(null);
}
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withIgnoreCase(false)
.withMatcher("username", ExampleMatcher.GenericPropertyMatchers.contains())
.withMatcher("userPassword", ExampleMatcher.GenericPropertyMatchers.contains())
.withIgnorePaths("userId", "userPhone");//忽略属性
Example<UserDO> userDOExample = Example.of(userDO, matcher);
return this.findAll(userDOExample,pageable);
}
}
方法如下:
| 方法 | 含义 |
|---|---|
| caseSensitive() | 大小写敏感 |
| ignoreCase() | 忽略大小写 |
| contains() | 模糊匹配,%{str}% |
| startsWith() | 匹配起始字符串,{str}% |
| endsWith() | 匹配结尾字符串,%{str} |
| exact() | 精确匹配字符串 |
| reges() | 将字符串作为正则表达式进行匹配 |
注意一下当使用完全匹配.exact()时,参数为String类型时,传参时如果传""(空字符串),并不是不进行筛选,而是会筛选"",结果极有可能查询结果为空。
要解决这个问题,也可以在之前对需要完全匹配的属性做出如下设置:
if (StringUtils.isEmpty(userDO.getXxx())) {
userDO.setXxx(null);
}
此时该属性需要完全匹配,并当传入""时会不进行筛选,而是查出全部。
版权声明:本文为yogima原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。