+-------+ +--------------| +-------+
| BOY | | BOY_GIRL | | GIRL |
+-------+ +--------------| +-------+
| id | | id | | id |
| name | | boy_id | | name |
| birth | | girl_id | | birth |
+-------+ | start_dating | +-------+
+--------------|
START_DATING
的类型为TIMESTAMP
或DATE
我有两个豆子男孩和女孩有多对多的关系
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "BOY_GIRL", joinColumns = {@JoinColumn(name = "BOY_ID")}, inverseJoinColumns = {@JoinColumn(name = "GIRL_ID")})
public Set<Girl> getGirls() {
return girls;
}
现在,我如何使用HQL选择查询,如果我想让列表女孩有条件:
where boy_id = (some_boy_id) and START_DATING > (some_timestamp)
答案 0 :(得分:4)
我认为你的实体模型不正确,你需要一个代表关系属性的第三个实体,你应该将男孩和女孩同时映射到该实体。 否则,无法在您的情况下将starting_date指定为关系属性,作为查询中的条件。 查看this link,您可以找到有关如何使用其他属性映射连接表的详细说明。
答案 1 :(得分:4)
我认为你必须创建一个BoyGirl
类,因为表BOY_GIRL
不是一个简单的多对多表(如果是,那么列必须只有boy_id
和girl_id
)。那么你应该做的是创建BoyGirl
类,然后将BOY
映射到BOY_GIRL
一对多,并将GIRL
映射到BOY_GIRL
,其中一个 - 对多
表关系
+-------+ +--------------+ +-------+
| BOY | | BOY_GIRL | | GIRL |
+-------+ +--------------| +-------+
| id | 0..* --- 1..1 | id | 1..1 --- 0..* | id |
| name | | boy_id | | name |
| birth | | girl_id | | birth |
+-------+ | start_dating | +-------+
+--------------+
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;
}
您需要的选择查询
// 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;
}
答案 2 :(得分:1)
由于中间表BOY_GIRL
有一些额外的属性(start_dating
),您需要在域模型中为它创建另一个中间实体,例如:
@Table(name="BOY_GIRL")
class Relationship {
@Id
long id;
@ManyToOne
Boy boy;
@ManyToOne;
Girl girl;
@Column
Date startDating;
}
答案 3 :(得分:0)
我认为将约会信息直接保存在联接表中并不是很好(因为这样做的目的应该只是关联一个男孩和一个女孩)。
但是,如果您真的想保留当前的结构并使用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