Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用spring数据示例匹配器解决列表属性查询问题_Java_Arraylist_Spring Data Jpa_Findby - Fatal编程技术网

Java 如何使用spring数据示例匹配器解决列表属性查询问题

Java 如何使用spring数据示例匹配器解决列表属性查询问题,java,arraylist,spring-data-jpa,findby,Java,Arraylist,Spring Data Jpa,Findby,我想问一下,对于具有列表属性的类,如何使用exampleMatcher。假设有一个用户可以同时扮演多个角色。我想从数据库中获取具有用户角色的所有用户 实体 @Entity(name = "UserEntity") public class User { Private Long id; private String name; private String surname; @OneToOne(cascade = CascadeType.ALL) @Jo

我想问一下,对于具有列表属性的类,如何使用exampleMatcher。假设有一个用户可以同时扮演多个角色。我想从数据库中获取具有用户角色的所有用户

实体

@Entity(name = "UserEntity")
public class User {
    Private Long id;
    private String name;
    private String surname;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn
    private Address address;

    @ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
    @JoinColumn
    private List<UserRole> roles;
}

@Entity
public class UserRole {
    private Long id;    
    private String name;
}
@Entity(name=“UserEntity”)
公共类用户{
私人长id;
私有字符串名称;
私家姓;
@OneToOne(级联=级联类型.ALL)
@连接柱
私人地址;
@ManyToMany(cascade=CascadeType.MERGE,fetch=FetchType.EAGER)
@连接柱
私有列表角色;
}
@实体
公共类用户角色{
私人长id;
私有字符串名称;
}
我向getExampleEntity发送了一个带有一些属性的用户类。我正在尝试从UI发送所选角色的列表

控制器中的函数

@Override
    protected User getExampleEntity() {
        User clonedUser = new User();
        List<UserRole> selectedRole = new ArrayList<>();
        // this cycle just find and add all roles in db based on selection from UI
        for (Long roleID : selectedUserRoleIDs)
           selectedRole.add(userRoleService.find(roleID));
        clonedUser.setRoles(selectedRole);
        return clonedUser;
    }
@覆盖
受保护用户getExampleEntity(){
User clonedUser=新用户();
List selectedRole=new ArrayList();
//这个循环只是根据用户界面的选择查找并添加数据库中的所有角色
用于(长角色ID:SelectedUserRoleID)
selectedRole.add(userRoleService.find(roleID));
clonedUser.setRoles(selectedRole);
返回克隆用户;
}
来自JpaRepository的函数,该函数使用示例匹配器调用findByExample函数

    @Override
    public List<TObjectType> findByExample(int first, int pageSize, String sortField, Sort.Direction sortOrder, TObjectType type)
    {
        PageRequest pageRequest = getPageRequest(first, pageSize, sortField, sortOrder);
        ExampleMatcher exampleMatcher = getExampleMatcher();
        Example<TObjectType> example = Example.of(type, exampleMatcher);
        return repository.findAll(example, pageRequest).getContent();
    }

    /**
     * Generates an example matcher for the instance of {@link TObjectType}.
     * This can be overriden if a custom matcher is needed! The default property matcher ignores the "id" path and ignores null values.
     * @return
     */
    protected ExampleMatcher getExampleMatcher() {
        return ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreNullValues();

    }
@覆盖
公共列表findByExample(int first、int pageSize、字符串排序字段、Sort.Direction排序器、TObjectType类型)
{
PageRequest PageRequest=getPageRequest(第一个,pageSize,sortField,sortOrder);
ExampleMatcher ExampleMatcher=getExampleMatcher();
Example=Example.of(类型,exampleMatcher);
返回repository.findAll(例如,pageRequest.getContent();
}
/**
*为{@link TObjectType}的实例生成一个示例匹配器。
*如果需要自定义匹配器,则可以覆盖此选项!默认属性匹配器忽略“id”路径并忽略空值。
*@返回
*/
受保护的ExampleMatcher getExampleMatcher(){
返回ExampleMatcher.matching()
.withStringMatcher(例如matcher.StringMatcher.CONTAINING)
.withIgnoreNullValues();
}
如果将发送一个具有属性名称/姓氏的用户,甚至是Address类中的任何属性的用户,它就像一个梦,但它不适用于列表角色。 我将非常感激任何解决这个问题的技巧,以及如何使用findByExample和TObjectType数组作为属性。 多谢各位

编辑: 我发现了问题。有一个repository.findAll函数的代码(org.springframework.data.repository.query.QueryByExampleExecutor#findAll)

@覆盖
公共页面findAll(示例,可分页){
ExampleSpecification spec=新的ExampleSpecification(示例);
类probeType=example.getProbeType();
TypedQuery query=getQuery(新的ExampleSpecification(示例),probeType,pageable);
return pageable==null?new PageImpl(query.getResultList()):readPage(query,probeType,pageable,spec);
}

生成的查询不包含list属性,但我不知道为什么,它包含在示例对象中。有人遇到过这个问题吗?我想只有一些设置/注释问题。

您应该首先尝试使用transformer。下面的示例是针对Mongodb的,但您可以看到这种方法。在我的例子中,User类包含作为字符串的角色列表:

final ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnoreNullValues()
                .withMatcher("roles", match -> match.transform(source -> ((BasicDBList) source).iterator().next()).caseSensitive());

        users = userRepository.findAll(Example.of(criteria, matcher), pageRequest);

我和你有同样的问题。我确实在文档中看到了,尽管它说当前只能使用SingularAttribute属性进行属性匹配。我试着研究什么是SingularAttribute属性,但我认为这可能是指排除列表…你找到解决这个问题的方法了吗?!你的问题很贴切,我对你的实际工作很感兴趣。什么是基本列表?2.当你说“用户类包含字符串形式的角色列表”时,你是指
列表角色?但问题是关于
列出角色我的例子是针对Mongodb的,用它来获得灵感。BasicDBList是来自Mongodb驱动程序的类。我很乐意使用它。但问题是我不明白。。。你能解释一下这个部分吗?
match->match.transform(source->)((BasicDBList)source.iterator().next())
?为了避免“不可逆类型”错误,使用
match->match.transform(source->Optional.of)((BasicDBList)source.get()).iterator().next()).exact()
说,在BasicDBList类中创建方法迭代器
final ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnoreNullValues()
                .withMatcher("roles", match -> match.transform(source -> ((BasicDBList) source).iterator().next()).caseSensitive());

        users = userRepository.findAll(Example.of(criteria, matcher), pageRequest);