假设我有两个表(猫与小猫):
==== Cat.java ====
@Id @GeneratedValue( strategy = GenerationType.IDENTITY )
private long id;
@Column( unique = true, nullable = false )
private String name;
@OneToMany @JoinColumn( name = "cat_id" )
private List<Kitten> kitten;
==== Kitten.java ====
@Id @GeneratedValue( strategy = GenerationType.IDENTITY )
private long id;
@Column( unique = true, nullable = false )
private String name;
包含以下数据
Cat(id, name)
Cat(1, "Cat 1")
Cat(2, "Cat 2")
Kitten(id, cat_id, name)
Kitten(1, 1, "Kitten 1")
Kitten(2, 1, "Kitten 2")
Kitten(3, 2, "Kitten 3")
Kitten(3, 2, "Bad Kit")
现在我想看到所有猫都有一只名叫“小猫”的小猫。
list = sess().createCriteria( Cat.class ).createAlias( "kitten", "kitten" )
.add( Restrictions.like( "kitten.name", "%kitten%" ) ).list();
上一个命令不是很好,因为连接我会得到重复的条目,例如count和maxresult不起作用。这是一个记录良好的问题,并且提到使用子查询。
我正在考虑这样的事情(但是使用Criteria-Api):
from Cat where id in
(select cat_id from Kitten where name like '%kitten%')
这不起作用,因为hibernate不允许我访问“cat_id”,我不想让它只针对此查询进行双向处理。
答案 0 :(得分:2)
如果您只是添加投影以获取cat ID,那么您的查询就是您要使用的子查询。所以你只需要以下内容:
DetachedCriteria acceptedCatIds = DetachedCriteria.forClass(Cat.class);
acceptedCatIds.createAlias("kitten", "kitten")
.add(Restrictions.like("kitten.name", "%kitten%" ))
.setProjection(Projections.id());
Criteria acceptedCats = session.createCriteria(Cat.class)
acceptedCats.add(Subqueries.propertyIn("id", acceptedCatIds));
答案 1 :(得分:0)
我强烈建议你让Kitten包含对Cat的引用。尽管需要更多关注以保持小猫和猫方的关系一致,但值得。
class Cat {
@Id @GeneratedValue( strategy = GenerationType.IDENTITY )
private long id;
@OneToMany(mappedBy="parent")
private List<Kitten> kitten;
}
class Kitten {
@Id @GeneratedValue( strategy = GenerationType.IDENTITY )
private long id;
@Column( unique = true, nullable = false )
private String name;
@ManyToOne
@JoinColumn( name = "cat_id" )
private Cat parent;
}
HQL应该变得像你想要的一样简单:
from Cat c where c in
(select parent from Kitten where name like '%kitten%')
甚至
select distinct parent from Kitten where name like '%kitten%'