在springmvc中使用hibernate获取子计数

时间:2016-06-08 12:50:15

标签: java spring hibernate spring-mvc jpa

如果我们要为网站创建后端。我们显然会创建类别和帖子/产品。要添加/编辑/删除类别,我们显然会创建一个类似于结构的表。例如:This is category listing as table

类别在同一个表中具有子类别,子类别的数量可以是1 - 多个。我想显示上面图片中提到的儿童类别数量。

作为CI开发人员,我通过在视图中使用Query来实现这一目的,

  

以下是示例

<?php 
            if(sizeof($results)>0)
                {     
                $i=1;

                foreach($results as $key => $list)
                  {


                  if($i%2==0)$cls="row1"; else $cls="row2";   
            ?>       
            <tr id="<?php echo $list->id;?>" class="<?php echo $cls; ?>">    
                <td> <?php echo $list->title, anchor("admin/categories/update/".$list->id."/", '<i class="fa fa-pencil rtrt"></i>' ); ?></td>

                <td> 

                     <?php 
                        // it will return number of childs
                         echo anchor ('admin/categories/category/'.$list->id, $this->Common->select_child ('tbl_category', $list->id) );
                     ?>
                </td>

现在我正在使用Spring-mvc,hibernate,Jpa和Mysql DB。我知道从jsp进行sql查询是一种不好的做法。

这是我的Jsp Code for table like structure,

<table class="table table-striped">
    <thead>
    <tr>
         <th><i class="fa fa-pencil"></i></th>
         <th>Category Name</th>
         <th>Child</th>
         <th>Created</th>
         <th>Updated</th>
         <th><input type="checkbox" /></th>
    </tr>
    </thead>
    <tbody>
    <c:if test="${not empty category}">
          <c:forEach var="cat" items="${category}">
            <tr>
                 <td><a href="${pageContext.request.contextPath}/category/${cat.id}/edit"><i class="fa fa-pencil"></i></a></td>
                 <td>${cat.title}</td>
                 <td><a href="${pageContext.request.contextPath}/category/show/${cat.id}"><i class="fa fa-folder-open"></i></a></td>
                 <td>${cat.created}</td>
                 <td>${cat.updated}</td>
                 <td><input type="checkbox" /></td>
            </tr>
        </c:forEach>
    </c:if>
  

这是类别POjo类

@Entity
@Table(name = "categories")
public class Categories {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

private Long parent_id;

private String title;

private String url_title;

private String description;

private String created;

private String updated;

/* 
 * @ At the time of Creating new user
 * Auto persist created date
 * Auto persist updated for first time
 */
@PrePersist
protected void onCreate (){

    // Date conversion to string
    Date date = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd h:mm:s");
    sdf.setLenient(false);
    String now = sdf.format(date);

    created = now;
    updated = now;


}


/*
 *  Respective Getter and Setter Methods
 *  
 */
public Long getId() {
    return id;
}public void setId(Long id) {
    this.id = id;
}

public Long getParent_id() {
    return parent_id;
}public void setParent_id(Long parent_id) {
    this.parent_id = parent_id;
}

public String getTitle() {
    return title;
}public void setTitle(String title) {
    this.title = title;
}

public String getUrl_title() {
    return url_title;
}public void setUrl_title(String url_title) {
    this.url_title = url_title;
}

public String getCreated() {
    return created;
}public void setCreated(String created) {
    this.created = created;
}

public String getUpdated() {
    return updated;
}public void setUpdated(String updated) {
    this.updated = updated;
}

public String getDescription() {
    return description;
}public void setDescription(String description) {
    this.description = description;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Categories other = (Categories) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    return true;
}
  

问题是

如何在不从Jsp进行sql查询的情况下获取子项数? 请帮帮我,我需要一个建议。

2 个答案:

答案 0 :(得分:0)

获取jsp端的List计数使用如下的jstl函数:

声明jstl.functions的taglibe

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

然后你可以试试这个

<c:set var="count" value="${fn:length(you_array)}" />

这将创建一个变量"count",其值为:you_array.size()

答案 1 :(得分:0)

希望它会帮助像我这样的人,

  

修改过的实体类

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private Long id;

private Long parent_id;
private String title;
private String url_title;
private String description;
private Long status;
private String created;
private String updated;

@ManyToOne 
@JoinColumn(
name="parent_id", 
insertable=false, 
updatable=false) 
@NotFound(action = NotFoundAction.IGNORE)
private Categories parentCategory;

@OneToMany(
fetch = FetchType.EAGER, 
mappedBy="parentCategory", 
cascade=CascadeType.REMOVE, 
orphanRemoval=true )

private Set<Categories> child = new HashSet<Categories>();

由于我是Jpa / orm / hibernate / spring的新手,当我发布这个问题时,我不知道我们可以在hibernate中管理的实体关系。我做了一些研究,发现了使用注释的hibernate 'Uni / Bi orientation'关联(一对多,多对一,多对多)。我建议如果您是JPA和hibernate的新手,请在浪费时间之前访问This link

  

我做了什么

与join的双向关联:使用@ManyToOne @Onetomany @joinColumn

使用@NotFound解决未发现的异常(NotFoundAction.IGNORE) 我有一个类别(例如基类别),它没有任何父类别,所以它的'parent_id'在数据库中将为0但是Hibernate将在成功关联后从ID为0的数据库查询记录时抛出异常。

使用insertable / updatable = false:如果一次只插入和更新一个类别,则将此属性设置为false。

使用“cascade = cascadetype.remove”“orphanremoval = true”:如果要在删除父类别时删除子类别,请设置此属性。当你调用serviceImplementation.delete(类别cat)方法时,如果“cat:object”是其他类别的父类,hibernate会在删除cat:object本身之前自动删除它的子类别。

  

最后回答我的问题

与注释成功关联后,您将从数据库中查询类别行。如果它是其他类别的父类别,hibernate将在您的对象中添加“child Collection”,如下所示。

03:20:16.490 [http-bio-8080-exec-5] DEBUG
o.h.internal.util.EntityPrinter -
com.pack.librarymanagementsystem.model.Categories
{created=2016-06-10 7:45:32, parent_id=38, url_title=Bhm 5th sem, 
description=<p>asd</p>,
parentCategory=com.pack.librarymanagementsystem.model.Categories#38,
id=43, title=Bhm 5th sem, updated=2016-06-10 7:45:32, child=[], status=1}

如果您正在使用eclipse,请在控制台日志中检查它。刚刚添加的子集合hibernate没有任何数据。 Hibernate只会存储代理。

  

解决方案是获得子集合的大小。

如果您要执行 isEmpty()检查该子集合,结果将为true。这就是“fetch = FetchType.EAGER”开始的地方。默认情况下,fetchtype设置为lazy。将fetchtype更改为eager hibernate后,会将对象添加为子项,而不是添加代理。

如果您现在要检查该子集合 isEmpty ,则结果将为false。这意味着我们可以获得集合的大小。

  

这是jsp

<c:if test="${not empty category}">
<c:forEach var="cat" items="${category}">
<tr>
    <td><a href="${pageContext.request.contextPath}/category/${cat.id}/edit"><i class="fa fa-pencil"></i></a></td>
    <td>${cat.title}</td>
    <td>
        // Child count
        <c:if test="${not empty cat.child}" >
            <a href="${pageContext.request.contextPath}/category/show/${cat.id}">
                <i class="fa fa-folder-open"></i> ${ fn:length(cat.child)}
            </a>    
        </c:if>
        <c:if test="${empty cat.child}" >
            <i class="fa fa-folder"></i> 0
        </c:if>
    </td>
    <td>${cat.created}</td>
    <td>${cat.updated}</td>
    <td>
        <c:choose>
            <c:when test="${cat.status == 1}">Published</c:when>
            <c:otherwise>Unpublished</c:otherwise>
        </c:choose>
    </td>
    <td><input type="checkbox" name="ids[]" id="ids[]" value="${cat.id}" /></td>
</tr>
</c:forEach>

  

这是控制器

@RequestMapping(value = "/show/", method = RequestMethod.GET)
public String viewCategory( Map<String, Object> model) {

List<Categories> category = categoryService.getAllCategoriesByParent(Id); 
model.put("category",category);

return "category/view";
}

我希望这可以帮助某人节省他/她的时间。 谢谢