4
+-------+    +--------------|     +-------+
| BOY   |    | BOY_GIRL     |     | GIRL  | 
+-------+    +--------------|     +-------+
| id    |    | id           |     | id    |
| name  |    | boy_id       |     | name  |
| birth |    | girl_id      |     | birth |
+-------+    | start_dating |     +-------+
             +--------------|

START_DATING是类型TIMESTAMPDATE

我有两个豆子男孩和女孩具有多对多关系

@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)
4

4 回答 4

4

我认为您的实体模型不正确,您需要表示关系属性的第三个实体,并且您应该将 Boy 和 Girl 尽可能多地映射到该实体。否则,无法将关系属性(在您的情况下为starting_date)指定为查询中的条件。查看此链接,您可以找到有关如何使用附加属性映射连接表的详细说明。

于 2012-10-31T09:06:37.133 回答
4

我认为您必须创建一个BoyGirl类,因为 tableBOY_GIRL不是简单的多对多表(如果是,那么列必须是boy_idand girl_id)。所以你应该做的是创建BoyGirl类,然后映射BOYBOY_GIRL一对多,也映射GIRLBOY_GIRL一对多

表关系

+-------+               +--------------+               +-------+
| BOY   |               | BOY_GIRL     |               | GIRL  | 
+-------+               +--------------|               +-------+
| id    | 0..* --- 1..1 | id           | 1..1 --- 0..* | id    |
| name  |               | boy_id       |               | name  |
| birth |               | girl_id      |               | birth |
+-------+               | start_dating |               +-------+
                        +--------------+

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;
}
于 2012-10-31T09:11:24.357 回答
1

由于中间表BOY_GIRL有一些附加属性 ( start_dating),您需要在域模型中为其创建另一个中间实体,例如:

@Table(name="BOY_GIRL")
class Relationship {

  @Id
  long id;

  @ManyToOne
  Boy boy;

  @ManyToOne;
  Girl girl;

  @Column
  Date startDating;
}
于 2012-10-31T09:13:09.020 回答
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
于 2012-10-31T09:19:58.847 回答