[英]Perform search using HQL/which join type to user?
I have the following model; 我有以下模型;
Here is the UserEntity class: 这是UserEntity类:
class UserEntity {
private String username;
private List<RuleEntity> rules;
@Column(name = "username", nullable = false, unique = true)
public String getUsername() {
return username;
}
@ManyToMany(mappedBy="users" , fetch = FetchType.LAZY)
public List<RuleEntity> getRules() {
return rules;
}
...
}
And the RuleEntity class: 和RuleEntity类:
class RuleEntity {
private String name;
private List<UserEntity> users;
@Column(name = "name", nullable = false)
public String getRuleName() {
return ruleName;
}
@ManyToMany (fetch = FetchType.LAZY)
@JoinTable(name= "RULE_USER" ,joinColumns=@JoinColumn
(name=RuleEntity.RULE_ID, referencedColumnName="ID", insertable = true, updatable = false, nullable = false),
inverseJoinColumns=@JoinColumn
(name=UserEntity.USER_ID, referencedColumnName="ID", insertable = true, updatable = false, nullable = false),
uniqueConstraints = @UniqueConstraint(columnNames = {RuleEntity.RULE_ID, UserEntity.USER_ID}))
public List<UserEntity> getUsers() {
return users;
}
...
}
I am trying to implement a search whereby a user can search using: 我正在尝试实现一种搜索,以便用户可以使用以下方法进行搜索:
So I am performing 2 HQL queries, one to return the matching users and one to return the matching rules eg 因此,我正在执行2个HQL查询,一个返回匹配的用户,另一个返回匹配的规则,例如
public SearchResults search(String maybePartialUsername, String maybePartialRuleName) {
List<UserEntity> userEntities = hqlQuery("select distinct users from UserEntity as users inner join users.rules as rules where users.username like :maybePartialUsername and rules.ruleName like :maybePartialRuleName");
List<RuleEntity> ruleEntities = hqlQuery("select distinct rules from RuleEntity as rules inner join rules.users as users where users.username like :maybePartialUsername and rules.ruleName like :maybePartialRuleName");
return SearchResults(userEntities, ruleEntities);
}
The first HQL query for finding users matching a username (and/or rulename) works fine when a user is a member of at least one rule, but it returns no results when a user has not been added to any rules. 当用户是至少一个规则的成员时,用于查找与用户名(和/或规则名称)匹配的用户的第一个HQL查询可以正常工作,但是当没有将用户添加到任何规则中时,它不会返回任何结果。
Changing the 'inner join' to a 'left join' does not help. 将“内部联接”更改为“左联接”无济于事。 The problem lies in the 'rules.ruleName like :maybePartialRuleName' condition, if I remove this the query works, but I need this in the query in the cases where the join with the rules tables succeeds (ie a user DOES have rules), and thus I then need to filter by rule name as well as username.
问题出在'rules.ruleName like:maybePartialRuleName like'条件下,如果我删除了此查询就可以了,但是如果规则表的连接成功(例如,用户确实有规则),则需要在查询中使用它,因此,我需要按规则名称和用户名进行过滤。
select distinct users from UserEntity as users inner join users.rules as rules where users.username like :maybePartialUsername and rules.ruleName like :maybePartialRuleName
Try left join 尝试左加入
select distinct users from UserEntity as users left join users.rules as rules where users.username like :maybePartialUsername and rules.ruleName like :maybePartialRuleName. 当用户离开时,从UserEntity中选择不同的用户加入用户users.rules作为规则,其中users.username如:maybePartialUsername和rules.ruleName如:maybePartialRuleName。
It will give you all that's int left side (userEntity in this case). 它将为您提供int左侧的所有功能(在本例中为userEntity)。
This is what worked for me (thanks @sergiu): 这对我有用(感谢@sergiu):
The following method creates the select part of the query: 以下方法创建查询的选择部分:
public List<UserEntity> search(final String maybePartialUsername, final String maybePartialRuleName)
throws EntityException {
final String selectUsersStatement = "select distinct users from UserEntity as users";
final String joinUsersWithRulesClause = shouldFilterSearchBy(maybePartialRuleName) ? "inner join users.rules as rules" : null;
return search(Joiner.on(" ").skipNulls().join(selectUsersStatement, joinUsersWithRulesClause),
maybePartialUsername, maybePartialRuleName);
}
Which then calls a method (not shown) which calls the following to build the where parts of the query: 然后调用一个方法(未显示),该方法调用以下内容以构建查询的where部分:
private String buildSearchQueryFrom(final String selectStatement, final String maybePartialUsername,
final String maybePartialRuleName) {
final Collection<String> searchFilters = Lists.newArrayListWithCapacity(2);
if (shouldFilterSearchBy(maybePartialUsername)) {
searchFilters.add("users.username like :maybePartialUsername");
}
if (shouldFilterSearchBy(maybePartialRuleName)) {
searchFilters.add("rules.ruleName like :maybePartialRuleName");
}
final String whereClauseParts = Joiner.on(" and ").skipNulls().join(searchFilters);
return Joiner.on(" where ").skipNulls().join(selectStatement, whereClauseParts);
}
And a helper method called by the method above: 还有一个由上述方法调用的辅助方法:
protected boolean shouldFilterSearchBy(final String searchValue) {
return !Strings.isNullOrEmpty(searchValue);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.