您的位置:首页 > 其它

JPA ExampleMatcher 类&方法介绍及使用示例

2020-06-28 05:08 1516 查看

前言:

本想在网上找JPA Example的教程文章,发现仅仅只有一些对零散的对模糊查询的一些示例

所以学习了下spring的Example文档,做了以下总结及说明和简单示例,一些方法的使用自己摸索出来的(都有过测试)

肯定有不足之处,望各位大神指出

spring官方文档

Interface ExampleMatcher

示例

嵌套类(内部类)

方法

  • getIgnoredPaths() 返回所有设置忽略匹配 withIgonrePaths(String… ignorePaths) 的字段集合
  • 类型:Set
  • getMatchMode()
      返回匹配模式 ANY
    • ALL
  • 类型:ExampleMatcher.MatchMode
  • getNullHandler()
      获取一个空处理的ExampleMatcher
    • 类型:ExampleMatcher.NullHandler

    以下返回boolean

    • isAllMatching() 判断匹配模式受否为matchingAll()模式
  • isAnyMatching()
      判断匹配模式受否为matchingAny()模式
  • isIgnoreCaseEnabled()
      判断是否开启了忽略大小写模式
  • isIgnoredPath(String path)
      对一个字段判断是否是设置了忽略匹配模式;也就是设置了 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 字段名
    • gennericPropertyMatcher 匹配规则
  • withStringMatcher(ExampleMatcher.StringMatcher defaultStringMatcher)

      如:返回一个匹配开始的字符串的ExampleMatcher

    • ExampleMatcher stringMatcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.STARTING);
  • withTransformer(String propertyPath, ExampleMatcher.PropertyValueTransformer propertyValueTransformer)

      propertyPath:字段名
    • propertyValueTransformer:转换规则
    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() 不忽略大小写
  • ignoreCase()
      忽略大小写
  • contains()
      匹配包含字符串
  • endsWith()
      匹配结尾字符串
  • exact()
      精确匹配字符串
  • reges()
      将字符串作为正则表达式进行匹配
  • startsWith()
      匹配结尾字符串
  • storeDefaultMatching()
      默认匹配模式

    使用和功能都和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
  • static ExampleMatcher.NullHandler values()
      结果 [INCLUDE,IGNORE]

    static class ExampleMatcher.StringMatcher

    方法

    • static ExampleMatcher.StringMatcher valueOf(String name) 根据参数name,返回对应的ExampleMatcher.StringMatcher
  • static ExampleMatcher.StringMatcher values()
      返回ExampleMatcher.StringMatcher[]数组

    枚举

    • CONTAINING 匹配包含的字符串
  • DEFAULT
      默认匹配模式
  • ENGING
      匹配结尾的字符串
  • EXACT
      精确匹配字符串
  • REGEX
      将字符串作为正则表达式匹配
  • STARTING
      匹配开头的字符串

    使用

    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
      )
      ]
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: