Select 基于休眠的多个 ID 的多个项目

Select multiple items based on multiple IDs with hibernate

我在 eclipse 中使用休眠。

我有 3 个一对多关系表。

一个[公司] --> 多个[主管],一个[主管] --> 多个[任务]。

他们都有唯一的 ID (companyId, officerId, taskId)。

目前我知道如何找到一个官员的所有任务,我也知道如何找到一个公司的所有官员。

这是代码片段:

public static ArrayList<Officer> getOfficersByCompany(Company company){
    ArrayList<Officer> officers = new ArrayList<Officer>();
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Officer.class);

    detachedCriteria.add(Restrictions.eq(Key.COMPANY, company));
    detachedCriteria.add(Restrictions.eq(Key.OBJSTATUS, Value.ACTIVED));

    List<Object> list = HibernateUtil.detachedCriteriaReturnList(detachedCriteria);

    for(Object o : list){
        officers.add((Officer) o);
    }
    return officers;
}

下面是 HibernateUtil 中的 detachedCriteriaReturnList 方法class。

public static List<Object> detachedCriteriaReturnList(DetachedCriteria dc){
    Session session = getSessionFactory().openSession();
    session.beginTransaction();
    Criteria criteria = dc.getExecutableCriteria(session);
    List<Object> list = criteria.list();
    session.getTransaction().commit();
    session.close();
    return list;
}

但是,如果我尝试获取所有任务属于公司,我应该如何实现代码。我试过使用:detachedCriteria.add(Restrictions.allEq(officers));

public static ArrayList<Task> getTasksByOfficers(Map<String, Object> officers){
    ArrayList<Task> tasks = new ArrayList<Task>();

    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Task.class);

    detachedCriteria.add(Restrictions.allEq(officers));
    List<Object> list = HibernateUtil.detachedCriteriaReturnList(detachedCriteria);

    for(Object o : list){
        tasks.add((Task) o);
    }

    return tasks;
}

但我意识到地图只存储唯一的键和值对,如果我尝试使用二副的 id,第一个将被替换。

或者有没有其他方法可以更快更有效地进行选择?

一个[公司] --> 多个[主管],一个[主管] --> 多个[任务]。

在 HQL 中,这应该非常简单(我放弃了使用 Criteria API,因为它不允许两次连接同一个对象 class):

显然,我没有测试查询,但它们应该可以工作...

select Task 
  from Task join Task.Officer o join o.Company c
 where c.name = 'xxx'

select t
  from Company c join c.Officers o join o.Tasks t
 where  c.name = 'xxx'

注意:正如我所说,我对标准的经验是有限的。但是看看你的代码,我有两条评论。也许你不应该使用 Map of officers 而应该使用列表 officers.values()allEq()。第二个评论:如果你没有做错,Hibernate 显然会神奇地找到你想要 allEq 的 属性 的引用,否则,allEq 会错过你想要比较的 属性。

更新:好的,正如我所承诺的,我为您检查了 Javadocs:https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/Criteria.html

HQL 中的一个join 相当于一个条件添加到另一个条件或别名:

detachedCriteria = DetachedCriteria.forClass(Task.class)
                   .createCriteria("Officer") // Officer property of task
                   .createCriteria("Company") // Company property of officer
                   .add(Restriction.eq(Key.COMPANY, compKey); // the company

List<Object> list = detachedCriteria
                    .getExecutableCriteria(hibernateSession)
                    .list();

这应该让你继续......

关于 HQL 的说明:

对于 运行 查询,您使用 HQL 从休眠会话中获取查询,然后在其上调用 list()executeUpdate()taskHqlString 是上面的 HQL 语句。将查询中的 companyKey 替换为命名参数 :companyKey:

String taskHqlString = "select Task "  
                     + "  from Task join Task.Officer o "
                     + "            join o.Company c "
                     + " where c.name = :companyKey";

List<Task> list = (List<Task>)hibernateSession
                  .createQuery(taskHqlString)
                  .setParameter("companyKey", companyKeyValue)
                  .list();