Java 使用HQL/对用户执行哪种连接类型的搜索?
我有以下模型Java 使用HQL/对用户执行哪种连接类型的搜索?,java,sql,hibernate,hql,Java,Sql,Hibernate,Hql,我有以下模型 我有用户和规则 可以将用户添加到0、1或更多规则中 规则可以包含0、1或多个用户 以下是UserEntity类: class UserEntity { private String username; private List<RuleEntity> rules; @Column(name = "username", nullable = false, unique = true) public String getUs
- 我有用户和规则
- 可以将用户添加到0、1或更多规则中
- 规则可以包含0、1或多个用户
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;
}
...
}
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;
}
...
}
尝试左连接
从UserEntity中选择不同的用户作为左用户加入users.rules作为规则,其中users.username类似:MaybeApartialUserName和rules.ruleName类似:MaybeApartialRuleName
它将为您提供所有int左边的内容(本例中为userEntity)。这对我来说很有用(谢谢@sergiu): 以下方法创建查询的select部分:
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);
}
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);
}
谢谢,虽然左连接也不起作用,但它会像内部连接一样返回零结果,问题是,对于左/内部连接,sql“rules.ruleName”的这一部分(如:maybeapartialruleName)会导致结果返回零结果。是否有一条记录同时满足这两个条件?不,在这种情况下,用户没有规则。好的,因此,只有当条件不为null或空时,才需要传递这些条件。例如,如果maybePartialRuleName为null或为空,则查询将不包含“and rules.ruleName like:maybePartialRuleName”。这同样适用于其他条件。必须使用内部连接。谢谢@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);
}
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);
}