Java hibernate-运行时的筛选器关系
我有以下POJO:Java hibernate-运行时的筛选器关系,java,hibernate,runtime,filtering,relation,Java,Hibernate,Runtime,Filtering,Relation,我有以下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
@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() {
}
}
如何筛选项目的成员?例如,假设我只想要名称以“a”开头的成员。当然,我可以做一些客户端过滤(例如使用Guava&Predicate),但让Hibernate改变SQL查询更有意义
我知道,但我不认为他们是为了这个。我认为它们更适用于全局过滤,而不是特定对象的特殊关系过滤
非常欢迎向文档、术语等提供指导。我对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());
}
}
编辑(3)
看看上面的第一个查询,这并不是我想要的。本质上,我想要两个问题:
getMembers()
时,将延迟执行此查询。此查询从表成员中选择,并在项目成员上联接这可能吗?新的JPA 2.1规定了在连接中按条件使用的可能性:
select p from Project p left join p.members m ON m.name like 'a%'
正如我在评论中提到的,我建议在hibernate中研究标准和/或hql文档。举个简单的例子,根据条件,您可以执行以下操作(我假设Spring的会话工厂,但api在其他地方是相同的): 如果您希望在项目中获得不同的结果,也很容易,只需再添加一种方法:
List filteredProjects = criteria.createAlias("member", "member")
.add( Restrictions.ilike("member.mName", "a", MatchMode.ANYWHERE) )
.setProjection(Projections.distinct(Projections.property("mIdentifier"))) //this will make distinct on your id property
.list();
使用HQL,第二个查询如下所示:
List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
.setParameter("param", "%a%")
.list();
@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() {
}
@Formula("<YOUR SQL TO FILTER RESULT>")
@Basic(fetch=FetchType.LAZY)
public Set<Member> getFilteredMembers() {
return mMembers
}
}
编辑:您想要的功能如下所示:
List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
.setParameter("param", "%a%")
.list();
@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() {
}
@Formula("<YOUR SQL TO FILTER RESULT>")
@Basic(fetch=FetchType.LAZY)
public Set<Member> getFilteredMembers() {
return mMembers
}
}
@实体(name=“项目”)
@表(name=“项目”)
公共类项目{
@列(name=“identifier”)
@身份证
@生成值
私有内部标识符;
@多个(级联=级联类型.ALL)
私有集mMembers=new HashSet();
公共int getIdentifier(){
返回中间层;
}
公共集getMembers(){
返回mMembers;
}
公共工程(){
}
@公式(“”)
@基本(fetch=FetchType.LAZY)
公共集getFilteredMembers(){
返回成员
}
}
但是根据这一点:您需要一些额外的工作来让它惰性地工作。那么,标准或hql呢我会研究这个!谢谢谢谢你的回答。请参阅我的编辑。我尝试了类似的标准(我没有包括别名),但没有成功。你知道吗?什么样的SQL是用双createCriteria生成的?我不确定这是否是正确的连接方式,请尝试使用别名,而不是查看编辑(2)!我也尝试过使用别名,但第二个查询总是发生。我刚刚意识到,您的getter/setter不遵循java约定。试着把它做好,然后再试一次,你能详细说明一下吗?
List projects = session.createQuery("select distinct p from Project p join p.mMembers as m where m.mName like :param")
.setParameter("param", "%a%")
.list();
@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() {
}
@Formula("<YOUR SQL TO FILTER RESULT>")
@Basic(fetch=FetchType.LAZY)
public Set<Member> getFilteredMembers() {
return mMembers
}
}