JPA ExampleMatcher 类&方法介绍及使用示例
前言:
本想在网上找JPA Example的教程文章,发现仅仅只有一些对零散的对模糊查询的一些示例
所以学习了下spring的Example文档,做了以下总结及说明和简单示例,一些方法的使用自己摸索出来的(都有过测试)
肯定有不足之处,望各位大神指出
Interface ExampleMatcher
示例
嵌套类(内部类)
- static class ExampleMatcher.GenericPropertyMatcher
- static class ExampleMatcher.GenericPropertyMatchers
- static interface ExampleMatcher.MatcherConfigurer
- static class ExampleMatcher.MatchMode
- static class ExampleMatcher.NoOpPropertyValueTransformer
- static class ExampleMatcher.NullHandler
- static class ExampleMatcher.StringMatcher
方法
- getIgnoredPaths() 返回所有设置忽略匹配 withIgonrePaths(String… ignorePaths) 的字段集合
- 类型:Set
-
返回匹配模式
ANY
-
获取一个空处理的ExampleMatcher
以下返回boolean
- isAllMatching() 判断匹配模式受否为matchingAll()模式
-
判断匹配模式受否为matchingAny()模式
-
判断是否开启了忽略大小写模式
-
对一个字段判断是否是设置了忽略匹配模式;也就是设置了 withIgonrePaths(String… ignorePaths) 的字段
以下都是返回ExampleMatcher对象(链式调用)
-
getDefaultStringMatcher()
返回默认的ExampleMatcher对象
matching()
返回一个匹配所有字段的ExampleMatcher对象;源码调用的是matchingAll()方法
源码
static ExampleMatcher matching() { return matchingAll(); }
示例
ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) .withIgnorePaths("password");Example<User> of = Example.of(user, exampleMatcher); List<User> all = userRepository.findAll(of);
matchingAll()
-
如上:返回一个匹配所有字段的ExampleMatcher对象;
matchingAny()
对任意一个字段进行匹配
示例:使用起来和matching()并无区别
ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) .withIgnorePaths("password"); Example<User> of = Example.of(user, exampleMatcher); List<User> all = userRepository.findAll(of);
withIgnoreCase(boolean defaultIgnoreCase)
返回一个默认的ExampleMatcher
默认是忽略大小写的ExampleMatcher.matching().withIgnoreCase(true);
源码
public ExampleMatcher withIgnoreCase(boolean defaultIgnoreCase) { return new TypedExampleMatcher(nullHandler, defaultStringMatcher, propertySpecifiers, ignoredPaths, defaultIgnoreCase, mode); }
withIgnoreCase(String… propertyPaths)
对一个或多个字段设置忽略大小写
ExampleMatcher.matching().withIgnoreCase("username");
withIgonrePaths(String… ignorePaths)
对一个或多个字段设置,则此字段不受其它匹配影响,也就是说其他任何匹配模式不对这个字段生效
如:不管设置了什么匹配模式,都不会对password字段生效
ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) .withIgnorePaths("password");
withIgnoreNullValues
-
返回一个对被忽略字段 Null空值处理的ExampleMatcher对象
withIncludeNullValues()
-
返回一个对字段 Null空值处理的ExampleMatcher对象
withMatcher(String propertyPath, ExampleMatcher.GenericPropertyMatcher gennericPropertyMatcher)
-
propertyPath 字段名
withStringMatcher(ExampleMatcher.StringMatcher defaultStringMatcher)
如:返回一个匹配开始的字符串的ExampleMatcher
ExampleMatcher stringMatcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.STARTING);
withTransformer(String propertyPath, ExampleMatcher.PropertyValueTransformer propertyValueTransformer)
-
propertyPath:字段名
ExampleMatcher username = ExampleMatcher.matching().withTransformer("username", o -> Optional.of("jpa-1"));
与如下效果一致
ExampleMatcher.GenericPropertyMatcher transform = new ExampleMatcher.GenericPropertyMatcher().transform(o -> Optional.of("jpa-1"));ExampleMatcher.matching().withMatcher("username",transform)
public static class ExampleMatcher.GenericPropertyMatcher
注:返回值都是ExampleMatcher.GenericPropertyMatcher
- contains() 模糊包含匹配;
User user = new User(); user.setUsername("test"); ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withMatcher("username", //对username字段进行包含模式匹配 ExampleMatcher.GenericPropertyMatcher::contains) //不对password字段进行任何处理 .withIgnorePaths("password"); Example<User> of = Example.of(user, exampleMatcher); List<User> all = userRepository.findAll(of); System.out.println(all);
-
endsWith() 后缀模糊匹配
以上都是用::方法引用 - 这次用new 对象的方式来创建ExampleMatcher
//对字段结尾模糊批匹配 ExampleMatcher.GenericPropertyMatcher endsWith = new ExampleMatcher.GenericPropertyMatcher().endsWith(); ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username", endsWith) .withIgnoreCase("username") .withIgnorePaths("password");
以下用法和上面都一样,只是匹配模式不同而已
-
exact() 精确匹配
-
ignoreCase(boolean ignoreCase)
设置忽略大小写为 true;也就是忽略大小写
caseSensitive()
-
设置忽略大小写为 false;也就是不忽略大小写
startsWith()
-
对开头的字符串模糊匹配
storeDefaultMatching()
-
默认匹配模式
regex()
-
将字符串视为正则表达式模式进行匹配
of(ExampleMatcher.StringMatcher stringMatcher)
ExampleMatcher.StringMatcher提供了如下枚举
CONTAINING
匹配包含的字符串DEFAULT
-
默认匹配模式
ENDING
-
匹配结尾的字符串
EXACT
-
匹配精确的字符串
REGEX
-
将字符串视为正则表达式进行匹配
STARTING
-
匹配开始的字符串
示例
ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() //ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING)) .withMatcher("username",ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING)) .withIgnoreCase("username") .withIgnorePaths("password");
ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING)
of(ExampleMatcher.StringMatcher stringMatcher, boolean ignoreCase)
和上一个一样,只是多了一个boolean来指定忽略大小写
ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING,false))
stringMatcher(ExampleMatcher.StringMatcher stringMatcher)
ExampleMatcher.StringMatcher提供了如下枚举
CONTAINING
匹配包含的字符串DEFAULT
-
默认匹配模式
ENDING
-
匹配结尾的字符串
EXACT
-
匹配精确的字符串
REGEX
-
将字符串视为正则表达式进行匹配
STARTING
-
匹配开始的字符串
示例
//通过ExampleMatcher.StringMatcher.XXX定义匹配模式 ExampleMatcher.StringMatcher defaultMode = ExampleMatcher.StringMatcher.DEFAULT; ExampleMatcher stringMatcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.STARTING);ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username",ExampleMatcher.GenericPropertyMatcher::startsWith) //将defaultMode传入 .withMatcher("username",ExampleMatcher.GenericPropertyMatcher.of(defaultMode,true)) .withMatcher("username", endsWith) .withIgnoreCase("username") .withIgnorePaths("password");
transform(ExampleMatcher.PropertyValueTransformer propertyValueTransforme)
在查询之前对属性值进行转换
示例:将传过来的参数test替换为jpa-1
ExampleMatcher.GenericPropertyMatcher().transform(o -> Optional.of("jpa-1"));
User user = new User(); user.setUsername("test"); ExampleMatcher.GenericPropertyMatcher transform = new ExampleMatcher.GenericPropertyMatcher().transform(o -> Optional.of("jpa-1")); ExampleMatcher exampleMatcher = ExampleMatcher.matching() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) .withMatcher("username", transform) .withIgnorePaths("password"); Example<User> of = Example.of(user, exampleMatcher); List<User> all = userRepository.findAll(of); System.out.println(all);
-
打印结果
[User(id=7, username=jpa-1, password=123)]
若没有使用替换
结果为:
[User(id=9, username=test, password=test)]
-
注意:这里Optional.of(“jpa-1”)的jpa-1必须精确完整,且写了transform后 其它模糊匹配失效
static class ExampleMatcher.GenericPropertyMatchers
只定义了如下方法
方法
- caseSensitive() 不忽略大小写
-
忽略大小写
-
匹配包含字符串
-
匹配结尾字符串
-
精确匹配字符串
-
将字符串作为正则表达式进行匹配
-
匹配结尾字符串
-
默认匹配模式
使用和功能都和ExampleMatcher.GenericPropertyMatcher类的方法一样
static interface ExampleMatcher.MatcherConfigurer<T>
-
第一步
写一个类实现ExampleMatcher.MatcherConfigurer<User>这个接口package com.live.model; import org.springframework.data.domain.ExampleMatcher; public class MyMatching implements ExampleMatcher.MatcherConfigurer<User> { @Override public void configureMatcher(User matcher) { matcher.setUsername("jpa"); } }
泛型为要操作的的Entity
即:
package com.live.model; import lombok.Data; import javax.persistence.*; @Entity @Table(name = "jpa_user") @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "jpa_username",length = 40) private String username; @Column(name = "jap_password") private String password; }
-
第二步: 调用MyMatching
User user = new User(); user.setUsername("test"); ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) .withIgnorePaths("password"); //调用我们自己实现MyMatching类的congifureMatcher方法,将user传入 new MyMatching().configureMatcher(user); Example<User> of = Example.of(user,exampleMatcher); List<User> all = userRepository.findAll(of); System.out.println(all);
-
结果
new MyMatching().configureMatcher(user) - 将user的username=“test"
- 设置为了”jpa“
- 所以结果为
[ User(id=8, username=jpa-2, password=234), User(id=7, username=jpa-1, password=123), User(id=6, username=jpa-dead, password=123123123123), User(id=5, username=jpa-result, password=12345) ]
static class ExampleMatcher.MatchMode
方法
-
static ExampleMatcher.MatchMode valueOf(String name)
根据name返回匹配模式
-
如:
ExampleMatcher.MatchMode.valueOf("ANY")
static ExampleMatcher.MatchMode[] values()
返回所有匹配模式
如:
ExampleMatcher.MatchMode[] values = ExampleMatcher.MatchMode.values();
打印结果
[ANY,ALL]
static ExampleMatcher.NoOpPropertyValueTransofrmer
方法
-
static ExampleMatcher.NoOpPropertyValueTransformer valueOf(String name)
返回具有指定名称的此类型的枚举常量
-
如:
ExampleMatcher.NoOpPropertyValueTransformer instance = ExampleMatcher.NoOpPropertyValueTransformer.valueOf("INSTANCE");
static ExampleMatcher.NoOpPropertyValueTrasformer[] values()
返回一个数组,该数组包含这个枚举类型的常量,按声明的顺序排列
ExampleMatcher.NoOpPropertyValueTransformer[] values = ExampleMatcher.NoOpPropertyValueTransformer.values();
打印结果:只有一个
[INSTANCE]
Optional apply(Optional source)
定义Function
public class MyFunction implements Function<Optional<User>, User> { @Override public User apply(Optional<User> user) { User user1 = new User(); user1.setUsername("apply-username"); user1.setPassword("apply-password"); user1.setId(200); return user1; } }
通过ExampleMatcher.NoOpPropertyValueTransformer.valueOf(“INSTANCE”);获取 ExampleMatcher.NoOpPropertyValueTransformer
再调用apply();进行消费
instance.apply(Optional.ofNullable(new MyFunction().apply(Optional.of(user))));
User user = new User(); user.setUsername("test"); ExampleMatcher.NoOpPropertyValueTransformer instance = ExampleMatcher.NoOpPropertyValueTransformer.valueOf("INSTANCE"); Optional<Object> instance = instance.apply(Optional.ofNullable(new MyFunction().apply(Optional.of(user))));//通过get()将instance强转为User User o = (User) instance.get(); System.out.println(o);
打印结果
User(id=200, username=apply-username, password=apply-password)
ExampleMatcher.NullHandler
方法
- static ExampleMatcher.NullHandler valueOf(String name) 根据参数name,返回一个NullHandler
- name可写的有: INCLUDE
- IGNORE
-
结果
[INCLUDE,IGNORE]
static class ExampleMatcher.StringMatcher
方法
- static ExampleMatcher.StringMatcher valueOf(String name) 根据参数name,返回对应的ExampleMatcher.StringMatcher
-
返回ExampleMatcher.StringMatcher[]数组
枚举
- CONTAINING 匹配包含的字符串
-
默认匹配模式
-
匹配结尾的字符串
-
精确匹配字符串
-
将字符串作为正则表达式匹配
-
匹配开头的字符串
使用
ExampleMatcher exampleMatcher = ExampleMatcher.matching() //这个通过ExampleMatcher.GenericPropertyMatcher方法引用startWith来模糊匹配开头的字符串 .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) //这个通过ExampleMatcher.GenericPropertyMatcher.of()方法传入ExampleMatcher.StringMatcher.STARTING来模糊匹配开头的字符串 .withMatcher("username", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING)) .withIgnorePaths("password"); Example<User> example = Example.of(user); List<User> all = userRepository.findAll(example);
示例
Entity
package com.live.model; import lombok.Data; import javax.persistence.*; @Entity @Table(name = "jpa_user") @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "jpa_username",length = 40) private String username; @Column(name = "jap_password") private String password; }
数据库
根据前缀模糊查询
- /findAllStartsWith/jpa
@GetMapping("/findAllStartsWith/{username}") public List<User> findAllByUsername(@PathVariable(value = "username") String username) { User user = new User(); user.setUsername(username); ExampleMatcher matching = ExampleMatcher.matching() //这个通过ExampleMatcher.GenericPropertyMatcher方法引用startWith来模糊匹配开头的字符串 .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::startsWith) //这个通过ExampleMatcher.GenericPropertyMatcher.of()方法传入ExampleMatcher.StringMatcher.STARTING来模糊匹配开头的字符串 //.withMatcher("username", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.STARTING)) //不对password字段处理 .withIgnorePaths("password"); Example<User> example = Example.of(user, matching); return userRepository.findAll(example); }
-
结果
[ User(id=8, username=jpa-2, password=234), User(id=7, username=jpa-1, password=123), User(id=6, username=jpa-dead, password=123123123123), User(id=5, username=jpa-result, password=12345) ]
根据后缀模糊查询
-
/findAllEndswith/dead
@GetMapping("/findAllEndswith/{username}") public List<User> findAllByUsername(@PathVariable(value = "username") String username) { User user = new User(); user.setUsername(username); //也可以将匹配模式单独写出来 ExampleMatcher.GenericPropertyMatcher endsWith = new ExampleMatcher.GenericPropertyMatcher().endsWith(); ExampleMatcher matching = ExampleMatcher.matching() .withMatcher("username", endsWith) //不对password字段处理 .withIgnorePaths("password"); Example<User> example = Example.of(user, matching); return userRepository.findAll(example); }
-
结果
[ User(id=6, username=jpa-dead, password=123123123123) ]
根据包含模式查询
-
/findAllContains/e
@GetMapping("/findAllContains/{username}") public List<User> findAllByUsername(@PathVariable(value = "username") String username) { User user = new User(); user.setUsername(username); ExampleMatcher matching = ExampleMatcher.matching() //这个通过ExampleMatcher.GenericPropertyMatcher方法引用contains来匹配包含的字符串 .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::contains) //这个通过ExampleMatcher.GenericPropertyMatcher.of()方法传入ExampleMatcher.StringMatcher.CONTAINING来匹配保安的字符串 //.withMatcher("username", ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.CONTAINING)) //不对password字段处理 .withIgnorePaths("password"); Example<User> example = Example.of(user, matching); return userRepository.findAll(example); }
-
结果
[ User(id=6, username=jpa-dead, password=123123123123), User(id=5, username=jpa-result, password=12345), User(id=9, username=test, password=test) ]
在查询前更改属性值
-
/findOneTransform/jpa
注意:Optional.of(“jpa-1”)的”jpa-1“必须精确完整,且是更改属性后,模糊查询失效
@GetMapping("/findOneTransform/{username}") public List<User> findAllByUsername(@PathVariable(value = "username") String username) { User user = new User(); user.setUsername(username); ExampleMatcher.GenericPropertyMatcher transform = new ExampleMatcher.GenericPropertyMatcher().transform(o -> Optional.of("jpa-1")); ExampleMatcher stringMatcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.STARTING); ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username", stringMatcher) .withMatcher("username", transform) //对username字段忽略大小写 .withIgnoreCase("username") //不对password字段处理 .withIgnorePaths("password"); new MyMatching().configureMatcher(user); Example<User> of = Example.of(user, exampleMatcher); List<User> all = userRepository.findAll(of); System.out.println(all); }
结果
[ User(id=7, username=jpa-1, password=123) ]
精确查询
-
/findOneExact/jpa-dead
@GetMapping("/findOneExact/{username}") public List<User> findAllByUsername(@PathVariable(value = "username") String username) { User user = new User(); user.setUsername(username); ExampleMatcher exampleMatcher = ExampleMatcher.matchingAny() .withMatcher("username", ExampleMatcher.GenericPropertyMatcher::exact) .withIgnorePaths("password"); Example<User> of = Example.of(user,exampleMatcher); Optional<User> user = userRepository.findOne(of); System.out.println(user); }
-
结果
Optional[ User( id=6, username=jpa-dead, password=123123123123 ) ]
- ExtJS4中的requires使用方法示例介绍
- python中MethodType方法介绍与使用示例
- ExtJS4中的requires使用方法示例介绍
- BackgroundWorker控件的使用方法介绍及示例程序
- JavaScript instanceof 的使用方法示例介绍
- 使用POST方式弹出窗口的两种方法示例介绍
- window.returnValue使用方法示例介绍
- 使用POST方式弹出窗口的两种方法示例介绍
- BackgroundWorker控件的使用方法介绍及示例程序
- window.returnValue使用方法示例介绍
- 递归算法在javascript中使用的小技巧 (javascript的对象封装方法介绍)
- aspjpeg组件高级使用方法介绍
- 递归算法在javascript中使用的小技巧 (javascript的对象封装方法介绍)
- 递归算法在javascript中使用的小技巧 (javascript的对象封装方法介绍)
- LIBSVM的介绍与使用方法
- Data Access Application Block(Enterprise Library 3.1)的下载以及使用方法介绍
- window.scrollTo()方法使用示例
- 递归算法在javascript中使用的小技巧 (javascript的对象封装方法介绍)
- 详细介绍 Hibernate 泛型 DAO 及其使用方法
- 递归算法在javascript中使用的小技巧 (javascript的对象封装方法介绍)