SpingData JPA之ExampleMatcher实例查询

ExampleMatcher是SpingData-JPA中好玩的一个东西

ExampleMatcher实例查询三要素
实体对象:在ORM框架中与Table对应的域对象,一个对象代表数据库表中的一条记录,如上例中User对象,对应user表。在构建查询条件时,一个实体对象代表的是查询条件中的“数值”部分。如:要查询姓“X”的客户,实体对象只需要存储条件值“X”。

匹配器:ExampleMatcher对象,它是匹配“实体对象”的,表示了如何使用“实体对象”中的“值”进行查询,它代表的是“查询方式”,解释了如何去查的问题。如:要查询姓“X”的客户,即姓名以“X”开头的客户,该对象就表示了“以某某开头的”这个查询方式,如上例中:withMatcher(“userName”, GenericPropertyMatchers.startsWith())

实例:即Example对象,代表的是完整的查询条件。由实体对象(查询条件值)和匹配器(查询方式)共同创建。最终根据实例来findAll即可。

使用

创建实体映射:

@Entity
@Table(name="t_user")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name="username")
    private String username;

    @Column(name="password")
    private String password;

    @Column(name="email")
    private String email;

    @Column(name="phone")
    private String phone;

    @Column(name="address")
    private String address;
}

测试查询:

@Test
public void contextLoads() {
    User user = new User();
    user.setUsername("admin");
    Example example = Example.of(user);
    List list = userRepository.findAll(example);
    System.out.println(list);
}

打印的sql语句如下:

Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.address as address2_0_,
        user0_.email as email3_0_,
        user0_.password as password4_0_,
        user0_.phone as phone5_0_,
        user0_.username as username6_0_ 
    from
        t_user user0_ 
    where
        user0_.username=?

在上面的测试之中,我们只是只是定义了Probe而没有ExampleMatcher,是因为默认会不传时会使用默认的匹配器。点进方法可以看到下面的代码:

static  Example of(T probe) {
    return new TypedExample(probe, ExampleMatcher.matching());
}

static ExampleMatcher matching() {
    return matchingAll();
}

static ExampleMatcher matchingAll() {
    return (new TypedExampleMatcher()).withMode(ExampleMatcher.MatchMode.ALL);
}

自定匹配器规则

@Test
public void contextLoads() {
    User user = new User();
    user.setUsername("y");
    user.setAddress("sh");
    user.setPassword("admin");
    ExampleMatcher matcher = ExampleMatcher.matching()
            .withMatcher("username", ExampleMatcher.GenericPropertyMatchers.startsWith())//模糊查询匹配开头,即{username}%
            .withMatcher("address" ,ExampleMatcher.GenericPropertyMatchers.contains())//全部模糊查询,即%{address}%
            .withIgnorePaths("password");//忽略字段,即不管password是什么值都不加入查询条件
    Example example = Example.of(user ,matcher);
    List list = userRepository.findAll(example);
    System.out.println(list);
}

打印的sql语句如下:
select
    user0_.id as id1_0_,
    user0_.address as address2_0_,
    user0_.email as email3_0_,
    user0_.password as password4_0_,
    user0_.phone as phone5_0_,
    user0_.username as username6_0_ 
from
    t_user user0_ 
where
    (
        user0_.username like ?
    ) 
    and (
        user0_.address like ?
    )

总结

使用一段时间之后,发现ExampleMatcher对日期的查询很不友好,不支持动态查询的,所以有了接下来研究的Specification复杂查询,可以了解一下。

你可能感兴趣的:(java技术分享,spring,JPA)