簡體   English   中英

使用HQL /用戶執行哪種連接類型執行搜索?

[英]Perform search using HQL/which join type to user?

我有以下模型;

  • 我有用戶和規則
  • 可以將一個用戶添加到0、1個或多個規則
  • 一個規則可以包含0、1個或多個用戶

這是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM