根据具有休眠

时间:2015-07-17 08:39:35

标签: java hibernate hibernate-criteria

我在eclipse中使用hibernate。

我有3个ONE TO MANY关系表。

ONE [公司] - >很多[官员]和一个[官员] - >很多[任务]。

他们都有唯一的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方法。

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(官员));

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

或者还有其他方法可以更快更有效地执行选择吗?

1 个答案:

答案 0 :(得分:0)

ONE [公司] - &gt;很多[官员]和一个[官员] - &gt;很多[任务]。

在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'

注意:正如我所说,我对标准的体验有限。但是看看你的代码,我有两条评论。也许您不应该使用人员地图,而是使用列表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从hibernate会话中获取查询,然后在其上调用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();