显示子项的 Hibernate 条件查询

Hibernate criteria query to display children

我正在尝试使用 Hibernate 为数据部分开发一个当前非常简单的 Web 应用程序。基本上,我试图获得一个 table 每个类别都有一行。在每一行的一个单元格中,我想显示该类别的 KPI。为此,我尝试使用标准对象。直接的问题是,我无能为力导致第二个查询甚至被触发。

这是我的代码中希望相关的部分。我已经尝试了各种各样的东西,这就是我目前得到的。

Category.java

    @Entity
@Table(name="category")
public class Category {
    @Id
    @Column(name="category_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    @Column(name="category_name")
    private String categoryName;

    @Transient
    private Kpi[] kpis;
...
    public Kpi[] getKpis() {
        return this.kpis;
    }
}

类别DAO

public interface CategoryDAO {

    public List<Category> listCategories();
    public Category getCategoryById(int id);
    public List<Kpi> getKpisForCategory(int cat);
}

CategoryDAOImpl

public class CategoryDAOImpl implements CategoryDAO {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }

...
    @SuppressWarnings("unchecked")
    @Override
    public List<Kpi> getKpisForCategory(int cat) {
        Session session = this.sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(Kpi.class).add(Restrictions.eq("category_id",cat));
        return criteria.list();
    }
}

CategoryServiceImpl

 @Service
    public class CategoryServiceImpl implements CategoryService {

        private CategoryDAO categoryDAO;

        public void setCategoryDAO(CategoryDAO dao) {
            this.categoryDAO = dao;
        }
...    
        @Override
        public List<Kpi> listKpisForCategory(int cat) {
            System.out.println("in service method");
            return this.categoryDAO.getKpisForCategory(cat);
        }
    }

jsp

<c:if test="${!empty listCategories}">
    <table class="tg">
        <tr>
            <th width="80">Category ID</th>
            <th width="120">Category Name</th>
        </tr>
        <c:forEach items="${listCategories}" var="category">
        <tr>
            <td>${category.id}</td>
            <td>${category.categoryName}</td>
            <td>
                <table class="tg">
                    <tr>
                        <th>KPI Name</th>
                    </tr>
                    <tr>

                    <c:forEach items="${category.kpis }" var="kpi">
                        <td>${category.id}
                        <td>${kpi.kpiName }</td>
                    </c:forEach>
                    </tr>
                </table>
            </td>
        </tr>
        </c:forEach>
    </table>    
</c:if>

无论我做什么,我最终都会得到嵌套的 table 为空的结果,并且子查询永远不会触发(由于我的高科技日志记录,我可以看出这一点!)。我错过了什么? (对不起,文字墙...)

您的 Kpi class 应该引用类别字段(我们将其命名为 "category")。然后你的 DAO 应该为类别创建引用标准并在那里添加你的限制。

Criteria criteria = session.createCriteria(Kpi.class);
Criteria categoryCriteria = criteria.createCriteria("category");
categoryCriteria.add(Restrictions.eq("id",cat));
return criteria.list();

或者你可以试试criteria.add(Restrictions.eq("category.id",cat));

多亏了@Naros 的评论,我才能让它工作。在 CategoryDAOImpl class 中,我向 listCategories() 方法添加了一些代码以填充类别对象中的 Kpi 列表:

@SuppressWarnings("unchecked")
    @Override
    public List<Category> listCategories() {
        System.out.println("dao impl list categories");
        Session session = this.sessionFactory.getCurrentSession();
        List<Category> categoryList = session.createQuery("from Category").list();

        for (Category c : categoryList) {
            List<Kpi> kpiList = getKpisForCategory(c.getId());
            c.setKpis(kpiList);
        }
        return categoryList;
    }