运行时的java hibernate筛选器关系
我有以下POJO:
@Entity(name = "member")
@Table(name = "member")
public class Member {
@Column(name = "identifier")
@Id
@GeneratedValue
private int mIdentifier;
@Column(name = "name", columnDefinition = "text")
private String mName;
@ManyToMany(mappedBy = "mMembers")
private Set<Project> mProjects = new HashSet<Project>();
public int getIdentifier() {
return mIdentifier;
}
public String getName() {
return mName;
}
public void setName(final String pName) {
mName = pName;
}
public Set<Project> getProjects() {
return mProjects;
}
public Member() {
}
}
及
@Entity(name = "project")
@Table(name = "project")
public class Project {
@Column(name = "identifier")
@Id
@GeneratedValue
private int mIdentifier;
@ManyToMany(cascade = CascadeType.ALL)
private Set<Member> mMembers = new HashSet<Member>();
public int getIdentifier() {
return mIdentifier;
}
public Set<Member> getMembers() {
return mMembers;
}
public Project() {
}
}
以下代码获取某个项目,并返回所有成员:
Project project = (Project) db.load(Project.class, 1);
System.out.println(project);
System.out.println(project.getMembers());
如何筛选项目的成员?例如,假设我只想要名称以“a”开头的成员。当然,我可以做一些客户端过滤(例如使用Guava&;Predicate),但让Hibernate更改SQL查询更有意义
我知道Hibernate filters,但我不认为他们是为了这个。我认为它们更适用于全局过滤,而不是特定对象的特殊关系过滤
非常欢迎向文档、术语等提供指导。我对Hibernate还比较陌生,很难获得这个问题的文档
编辑
我用标准试过了。我有两名成员,“约翰·斯诺”和“斯诺”。下面仍然返回两个成员
final Criteria criteria = db.createCriteria(Project.class)
.createCriteria("mMembers")
.add(Restrictions.eq("mName", "John Snow"));
for (final Project project : (List<Project>) criteria.list()) {
System.out.println(project.getIdentifier());
for (final Member member : project.getMembers()) {
System.out.println(member.getName());
}
}
有什么想法吗
编辑(2)
看起来执行了第二个查询,以获取所有成员。我们如何防止这种情况,而仅仅依靠基于标准的数据
Hibernate:
select
this_.identifier as identifi1_1_1_,
mmembers3_.mProjects_identifier as mProject1_1_,
mmembers1_.identifier as mMembers2_2_,
mmembers1_.identifier as identifi1_0_0_,
mmembers1_.name as name2_0_0_
from
project this_
inner join
project_member mmembers3_
on this_.identifier=mmembers3_.mProjects_identifier
inner join
member mmembers1_
on mmembers3_.mMembers_identifier=mmembers1_.identifier
where
mmembers1_.name=?
1
Hibernate:
select
mmembers0_.mProjects_identifier as mProject1_1_1_,
mmembers0_.mMembers_identifier as mMembers2_2_1_,
member1_.identifier as identifi1_0_0_,
member1_.name as name2_0_0_
from
project_member mmembers0_
inner join
member member1_
on mmembers0_.mMembers_identifier=member1_.identifier
where
mmembers0_.mProjects_identifier=?
Snow
John Snow
编辑(3)
看看上面的第一个查询,这并不是我想要的。本质上,我想要两个问题:
- 第一个查询获取某个项目。此查询从表项目中进行选择李>
- 第二个查询获取符合特定条件的所有成员。当调用
getMembers()
时,将延迟执行此查询。此查询从表成员中进行选择,并在项目成员上进行联接李>
我不想将其合并到一个查询中,并从表项目成员中进行选择,因为这将导致大量解析开销。我不想以笛卡尔积结束
这可能吗
# 1 楼答案
正如我在评论中提到的,我建议在hibernate中使用研究标准和/或hql文档。举个简单的例子,根据标准,您可以执行以下操作(我假设Spring的会话工厂,但api在其他地方是相同的):
如果你想在项目中获得不同的结果,也很简单,只需再添加一种方法:
使用HQL,第二个查询如下所示:
编辑:你想要的功能如下:
但是根据这个:Is it possible to make @Formula annotation lazily loaded?你需要一些额外的工作来让它懒散地工作
# 2 楼答案
新的JPA 2.1规定了在连接条件下使用的可能性: