Java 如何使用spring数据示例匹配器解决列表属性查询问题
我想问一下,对于具有列表属性的类,如何使用exampleMatcher。假设有一个用户可以同时扮演多个角色。我想从数据库中获取具有用户角色的所有用户 实体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
@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);