[英]Hibernate many-to-many join with condition
+-------+ +--------------| +-------+
| BOY | | BOY_GIRL | | GIRL |
+-------+ +--------------| +-------+
| id | | id | | id |
| name | | boy_id | | name |
| birth | | girl_id | | birth |
+-------+ | start_dating | +-------+
+--------------|
START_DATING
is type of TIMESTAMP
or DATE
START_DATING
是TIMESTAMP
或DATE
类型
I have two beans Boy and Girl with many-to-many relation 我有两个豆子男孩和女孩有多对多的关系
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "BOY_GIRL", joinColumns = {@JoinColumn(name = "BOY_ID")}, inverseJoinColumns = {@JoinColumn(name = "GIRL_ID")})
public Set<Girl> getGirls() {
return girls;
}
Now, how can I do select query with HQL, if I want to get the list girls with condition: 现在,我如何使用HQL选择查询,如果我想获得有条件的列表女孩:
where boy_id = (some_boy_id) and START_DATING > (some_timestamp)
I think your entity model is not correct, you need a third entity representing the relationship attribute and you should map both Boy and Girl as many to one to that entity. 我认为你的实体模型不正确,你需要一个代表关系属性的第三个实体,你应该将男孩和女孩同时映射到该实体。 Otherwise there is no way to specify the relationship attribute, in your case starting_date, as a condition in a query.
否则,无法在您的情况下将starting_date指定为关系属性,作为查询中的条件。 Look at this link , you can find a detailed explanation on how to map a join table with additional attributes.
查看此链接 ,您可以找到有关如何使用其他属性映射连接表的详细说明。
I think you have to create a BoyGirl
class because table BOY_GIRL
is not a simple many-to-many table (If it is, then the columns are has to be only boy_id
and girl_id
). 我认为你必须创建一个
BoyGirl
类,因为表BOY_GIRL
不是一个简单的多对多表(如果是,那么列必须只是boy_id
和girl_id
)。 So what you should do is create the BoyGirl
class then map BOY
to BOY_GIRL
with one-to-many and also map GIRL
to BOY_GIRL
with one-to-many 那么你应该做的是创建
BoyGirl
类然后用BoyGirl
映射BOY
到BOY_GIRL
,并用一对多映射GIRL
到BOY_GIRL
table relations 表关系
+-------+ +--------------+ +-------+
| BOY | | BOY_GIRL | | GIRL |
+-------+ +--------------| +-------+
| id | 0..* --- 1..1 | id | 1..1 --- 0..* | id |
| name | | boy_id | | name |
| birth | | girl_id | | birth |
+-------+ | start_dating | +-------+
+--------------+
java classes java类
public class BoyGirl {
private long id;
private Boy boy;
private Girl girl;
private Date startDating;
}
public class Boy {
//other attributes omitted
private Set<BoyGirl> boyGirls;
}
public class Girl {
//other attributes omitted
private Set<BoyGirl> boyGirls;
}
The select query you need 您需要的选择查询
// I'm using criteria here, but it will have the same result as your HQL
public List getGirls(Boy boy, Date startDating) {
Criteria c = sessionFactory.getCurrentSession().createCriteria(BoyGirl.class);
c.add(Restrictions.eq("boy.id", boy.getId());
c.add(Restrictions.lt("startDating", startDating);
List<BoyGirl> boyGirls = (List<BoyGirl>) c.list();
// at this point you have lazily fetch girl attributes
// if you need the girl attributes to be initialized uncomment line below
// for (BoyGirl boyGirl : boyGirls) Hibernate.initialize(boyGirl.getGirl());
return boyGirls;
}
As the intermediate table BOY_GIRL
has some additional attributes ( start_dating
) you need to create another intermediate entity in your domain model for it, eg: 由于中间表
BOY_GIRL
具有一些额外的属性( start_dating
),您需要在域模型中为它创建另一个中间实体,例如:
@Table(name="BOY_GIRL")
class Relationship {
@Id
long id;
@ManyToOne
Boy boy;
@ManyToOne;
Girl girl;
@Column
Date startDating;
}
I don't think its great to keep the dating information directly inside the join table (since the purpose of this should simply be to associate a boy and a girl). 我认为将约会信息直接保存在联接表中并不是很好(因为这样做的目的应该只是关联一个男孩和一个女孩)。
However, if you really want to keep your current structure, and solve it with HQL, you should be able to do something like 但是,如果你真的想保留当前的结构,并用HQL解决它,你应该能够做类似的事情
SELECT g FROM GIRL g, BOY_GIRL bg
WHERE bg.start_dating = :revelantdate
AND bg.boy_id = :boyid
AND g.id = bg.girl_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.