显示子项的 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;
}
我正在尝试使用 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;
}