[英]Perform search using HQL/which join type to user?
我有以下模型;
這是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;
}
...
}
和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;
}
...
}
我正在嘗試實現一種搜索,以便用戶可以使用以下方法進行搜索:
因此,我正在執行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);
}
當用戶是至少一個規則的成員時,用於查找與用戶名(和/或規則名稱)匹配的用戶的第一個HQL查詢可以正常工作,但是當沒有將用戶添加到任何規則中時,它不會返回任何結果。
將“內部聯接”更改為“左聯接”無濟於事。 問題出在'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
嘗試左加入
當用戶離開時,從UserEntity中選擇不同的用戶加入用戶users.rules作為規則,其中users.username如:maybePartialUsername和rules.ruleName如:maybePartialRuleName。
它將為您提供int左側的所有功能(在本例中為userEntity)。
這對我有用(感謝@sergiu):
以下方法創建查詢的選擇部分:
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);
}
然后調用一個方法(未顯示),該方法調用以下內容以構建查詢的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);
}
還有一個由上述方法調用的輔助方法:
protected boolean shouldFilterSearchBy(final String searchValue) {
return !Strings.isNullOrEmpty(searchValue);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.