【问题标题】:Select multiple items based on multiple IDs with hibernate使用hibernate根据多个ID选择多个项目
【发布时间】:2015-07-17 08:39:34
【问题描述】:

我在 Eclipse 中使用休眠。

我有 3 个一对多关系表。

ONE [Company] --> MANY [Officer],以及 ONE [Officer] --> MANY [Task]。

它们都有唯一的 id(companyId、officerId、taskId)。

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

这里是sn-p的代码:

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 方法。

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,第一个将被替换。

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

【问题讨论】:

  • 您只需要两个 join company->officer->task 和一个 distinct,因为官员可能共享相同的任务:为了简洁和可读性,我会使用 HQL 查询。
  • @medveshonok117 感谢您的关注,但我很确定在我的情况下,官员不会分担相同的任务。你知道如何使用标准来做到这一点吗?请多解释一下?非常感谢:)

标签: java hibernate hibernate-criteria


【解决方案1】:

ONE [Company] --> MANY [Officer],以及 ONE [Officer] --> MANY [Task]。

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

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

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'

注意:正如我所说,我对标准的经验是有限的。但是看看你的代码,我有两个 cmets。也许您不应该使用军官地图,而是使用列表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();

【讨论】:

  • 感谢您的建议,但我对 HQL 的经验完全为零。不知道如何实施。不用担心,我今天才进入标准......所以,我认为你更有经验:P。如果您可以使用标准方法对问题进行更多解释,那就太好了。
  • 我现在无法检查文档,但条件支持加入作为条件,请在 hibernate.org 上搜索休眠文档以获取条件并加入。我将在今天晚些时候检查 - 但这样的例子很多。
  • 这几天有点忙,后天试试。非常感谢您提前提供的帮助。干杯
  • Hrmm,第一次不工作,但第二次我重新启动我的服务器,是的,它工作正常。谢谢你的帮助!!干杯
猜你喜欢
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 2022-12-10
相关资源
最近更新 更多