功能點分析:商品類目表


  • 前言

    作為電商網站,必然要有商品類目表,以便商品分類檢索。而設計商品類目表,又是一件特別繁雜的事情。一件商品可能有多個類目來檢索出來,比如蘋果手機,可以從品牌檢索也可以從手機檢索。一個類目對應多個商品,比如手機下對應了多款屬於手機類的商品。而類目是一個多叉樹結構,類似於文件夾的結構。通常大電商都是把類目整理好了放在cache上,就不用頻繁訪問數據庫和整理排序了。

  • 個人類目標的結構設計

    參考了一下網上無限級分類的表設計,簡化模型為一個表內存在父子級從屬關系。

    表中的isRoot可以去掉,只要parent為0就認為是根節點就好了。而為什么不存子節點而是存父節點,因為子節點的映射類,生成整理的時候比存父節點要復雜一些,當然程序寫的不復雜而是這個問題需要花費的時間就會多一些。

    表設計好了之后,就需要查詢數據並且整理出他們的從屬關系。為了減少數據庫的查詢次數,我采用了全部查詢,在內存中生成多叉樹的形式。節點類的定義想法非常直接,它存在唯一識別:id,真實信息:name,以及它的子樹:List or Map。

/*
 * 樹型存儲
 */
class CategoryTree{
    private long id;
    private String name;
    private List<CategoryTree> children;
    public CategoryTree(){
        children = new ArrayList<>();
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<CategoryTree> getChildren() {
        return children;
    }
    public void setChildren(List<CategoryTree> children) {
        this.children = children;
    }
    
}
/*
 * 哈希表存儲
 */
class CategoryMap{
    private long id;
    private String name;
    private Map<Long,CategoryMap> children;
    public CategoryMap(){
        children = new HashMap<>();
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Map<Long, CategoryMap> getChildren() {
        return children;
    }
    public void setChildren(Map<Long, CategoryMap> children) {
        this.children = children;
    }
}

    在對亂序數組生成三級n叉樹這個過程中,最快的方式是用map。在生成過程中,只能一級級生成,因為沒有父節點不可能有子節點跟隨這個邏輯的存在。

    //集合存儲
    public void test1(){
        tool.connection2MYSQL();
        Connection conn = tool.getCon();
        String sql = "select * from category";
        Statement stm = null;
        List<category> clist = new ArrayList<>();
        try {
            stm = conn.createStatement();
            ResultSet rs = stm.executeQuery(sql); 
            while(rs.next()){
                category c = new category();
                c.setId(rs.getLong("id"));
                c.setName(rs.getString("name"));
                c.setParentId(rs.getLong("parent_id"));
                c.setIsRoot(rs.getInt("is_root"));
                clist.add(c);
            }
            tool.closeConn(conn);
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        /*
         * 檢查集合
         */
//        for(category ca:clist){
//            System.out.println("id: "+ca.getId()+" name: "+ca.getName()+" parentId: "+ca.getParentId()+" isRoot: "+ca.getIsRoot());
//        }
        /**
         * 邏輯嘗試=====
         */
        List<CategoryTree> roots = new ArrayList<>();
        List<CategoryTree> second = new ArrayList<>();
        List<CategoryTree> third = new ArrayList<>();
        //一次遍歷 添加根節點
        int i = 0;
        while(i != clist.size()-1){
            if(clist.get(i).getParentId() == 0){
                CategoryTree ct = new CategoryTree();
                ct.setId(clist.get(i).getId());
                ct.setName(clist.get(i).getName());
                roots.add(ct);
                clist.remove(i);
            }else
                i++;
        }
        //二次遍歷 添加二級節點
        for(int j=0;j<roots.size();j++){
            i = 0;
            while(i < clist.size()){
                if(clist.get(i).getParentId() == roots.get(j).getId()){
                    CategoryTree ct = new CategoryTree();
                    ct.setId(clist.get(i).getId());
                    ct.setName(clist.get(i).getName());
                    roots.get(j).getChildren().add(ct);
                    second.add(ct);//用空間換
                    clist.remove(i);
                }else
                    i++;
            }
        }
        //三次遍歷 添加三級節點
        for(int j=0;j<second.size();j++){
            i = 0;
            while(i < clist.size()){
                if(clist.get(i).getParentId() == second.get(j).getId()){
                    CategoryTree ct = new CategoryTree();
                    ct.setId(clist.get(i).getId());
                    ct.setName(clist.get(i).getName());
                    second.get(j).getChildren().add(ct);
                    third.add(ct);//用空間換
                    clist.remove(i);
                }else
                    i++;
            }
        }
        for(category ca:clist){
            System.out.println("id: "+ca.getId()+" name: "+ca.getName()+" parentId: "+ca.getParentId()+" isRoot: "+ca.getIsRoot());
        }
        for(CategoryTree ct:roots){
            System.out.println("id: "+ct.getId()+" name: "+ct.getName());
            {
            for(CategoryTree ct1:ct.getChildren())
            {
                System.out.println("二級 id: "+ct1.getId()+" name: "+ct1.getName());
                for(CategoryTree ct2:ct1.getChildren())
                    System.out.println("三級 id: "+ct2.getId()+" name: "+ct2.getName());
            }
                
            }
        }/**
         * 邏輯嘗試=====
         */
        
    }

    我對每一級的節點做了一個額外的存儲,在第三級生成的時候簡化一個循環,也就是n平方的復雜度。

    使用map生成的話,僅在生成這個過程,就可以把問題化簡成n的復雜度。因為Map“知道”自己存儲的對象的id,而List要通過遍歷才知道它的自己存的元素的id。

public void test2(){
        tool.connection2MYSQL();
        Connection conn = tool.getCon();
        String sql = "select * from category";
        Statement stm = null;
        List<category> clist = new ArrayList<>();
        try {
            stm = conn.createStatement();
            ResultSet rs = stm.executeQuery(sql); 
            while(rs.next()){
                category c = new category();
                c.setId(rs.getLong("id"));
                c.setName(rs.getString("name"));
                c.setParentId(rs.getLong("parent_id"));
                c.setIsRoot(rs.getInt("is_root"));
                clist.add(c);
            }
            tool.closeConn(conn);
        } catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        /**
         * 邏輯嘗試=====
         */
        Map<Long,CategoryMap> rootMap = new HashMap<>();
        Map<Long,CategoryMap> secondMap = new HashMap<>();
        //遍歷一級
        int i = 0;
        while(i < clist.size()){
            if(clist.get(i).getParentId() == 0){
                CategoryMap cm = new CategoryMap();
                cm.setId(clist.get(i).getId());
                cm.setName(clist.get(i).getName());
                rootMap.put(cm.getId(),cm);
                clist.remove(i);
            }else
                i++;
        }
        //遍歷二級
        i = 0;
        while (i < clist.size()) {
            if (rootMap.get(clist.get(i).getParentId()) != null) {
                CategoryMap cm = new CategoryMap();
                cm.setId(clist.get(i).getId());
                cm.setName(clist.get(i).getName());
                rootMap.get(clist.get(i).getParentId()).getChildren().put(cm.getId(), cm);
                secondMap.put(cm.getId(), cm);
                clist.remove(i);
            } else
                i++;
        }
        //遍歷三級
        i = 0;
        while (i < clist.size()) {
            if (secondMap.get(clist.get(i).getParentId()) != null) {
                CategoryMap cm = new CategoryMap();
                cm.setId(clist.get(i).getId());
                cm.setName(clist.get(i).getName());
                secondMap.get(clist.get(i).getParentId()).getChildren().put(cm.getId(), cm);
                clist.remove(i);
            } else
                i++;
        }
//        for (Map.Entry<Long, CategoryMap> entry : rootMap.entrySet()) {  
//            System.out.println("Key = " + entry.getKey() + ", id : " + entry.getValue().getId()+" name : "+entry.getValue().getName());
//            for (Map.Entry<Long, CategoryMap> entry1 : entry.getValue().getChildren().entrySet()){
//                System.out.println("二級 Key = " + entry1.getKey() + ", id : " + entry1.getValue().getId()+" name : "+entry1.getValue().getName());
//                  for (Map.Entry<Long, CategoryMap> entry2 : entry1.getValue().getChildren().entrySet()){
//                      System.out.println("三級 Key = " + entry2.getKey() + ", id : " + entry2.getValue().getId()+" name : "+entry2.getValue().getName());
//                  }
//            }
//            
//        }
        JSONArray json = new JSONArray();
        for (CategoryMap entry : rootMap.values()) { 
            JSONObject job1 = new JSONObject();
            job1.put("id", entry.getId());
            job1.put("name", entry.getName());
            JSONArray joa1 = new JSONArray();
//            System.out.println("id : " + entry.getId()+" name : "+entry.getName());
            for (CategoryMap entry1 : entry.getChildren().values()){
                JSONObject job2 = new JSONObject();
                job2.put("id", entry1.getId());
                job2.put("name", entry1.getName());
                JSONArray joa2 = new JSONArray();
//                System.out.println("二級 id : " + entry1.getId()+" name : "+entry1.getName());
                  for (CategoryMap entry2 : entry1.getChildren().values()){
                    JSONObject job3 = new JSONObject();
                    job3.put("id", entry2.getId());
                    job3.put("name", entry2.getName());
                    joa2.add(job3);
//                    System.out.println("三級 id : " + entry2.getId() + " name : "+entry2.getName());
                  }
                  job2.put("chird", joa2);
                  joa1.add(job2);
            }
            job1.put("chird", joa1);
            json.add(job1);
        }
        
        for(int k=0;k<json.size();k++){
            JSONObject jo = json.getJSONObject(k);
            System.out.println(jo.toString());
        }
        /**
         * 邏輯嘗試=====
         */
    }

    最后的生成json的時候,仍然需要三次方的復雜度,我在考慮如何能在整理過程中順帶生成json,現在還沒做出來,不過優化成n應該還是有機會的。

    另外,遍歷源數據的時候,把抽掉的節點remove掉也是一種減少重復遍歷的方式。

    最后生成的結果如同預期。

連接成功
{"chird":[{"chird":[{"name":"襯衣","id":16}],"name":"七匹狼","id":6},{"chird":[{"name":"運動服","id":17}],"name":"阿迪達斯","id":7}],"name":"男裝","id":1}
{"chird":[{"chird":[{"name":"毛衣","id":18}],"name":"zara","id":8},{"chird":[{"name":"包包","id":19}],"name":"普拉達","id":9}],"name":"女裝","id":2}
{"chird":[{"chird":[{"name":"筆記本電腦","id":20}],"name":"dell","id":10},{"chird":[{"name":"台式電腦","id":21}],"name":"lenovo","id":11}],"name":"電腦","id":3}
{"chird":[{"chird":[{"name":"note","id":22}],"name":"三星","id":12},{"chird":[{"name":"iPhone","id":23}],"name":"蘋果","id":13}],"name":"手機","id":4}
{"chird":[{"chird":[{"name":"第一版","id":24}],"name":"Java程序設計","id":14},{"chird":[{"name":"第三版","id":25}],"name":"C++程序設計","id":15}],"name":"圖書","id":5}

  • 總結

    對於表設計和這個問題的解決不知道有沒有更加規范一點的方式,還需要繼續探討。對於我們項目來說,這個方法已經可以適應了,商品分類我打算用個分類表來做映射,類目表葉子節點的id和商品的id存入,檢索的時候根據葉子節點id檢索所有商品。本次問題,在於對亂序數組轉化為多叉樹的模型建立,解決了這個問題,對轉化思維又有了進一步的提高。(在這里其實問題的階並不重要,因為這是有窮集合,類目表的條目基本不會超過幾百,考慮的最多的就是訪問量的問題,因為小電商不會做cache,每一次訪問都生成三級樹,所以本次問題重在如何用更好的運算模型去解決同一個問題)

  • 追加

    關於三級關系樹的運用,我做了一個小的地域管理頁面,與類目樹是一樣的結構。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@include file="/common.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
        <script type="text/javascript" src="js/jquery.js" ></script>
        <script type="text/javascript" src="js/jquery.form.js"></script>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>地域信息</title>
        <style>
            .chosen{
                background:blue;
            }
            .select{
                width:30px;
            }
        </style>
</head>
<body>
<div>
    <div style="margin-left:20px;float:left;">
        <h2>一級類別</h2>
        <h3>當前:${current1.name}</h3>
    <form action="letao_DevelopmentModelArea_addArea" id="addForm1">
        編碼:<input size="8" name="code"> name:<input size="8" name="name"> <input size="8" name="parent" type="hidden" value="0">
        <br/>
    </form>
    <br/>
    <button class="add1">添加</button>
        <table style="border: 2px solid BLACK;">
            <thead>
                <tr>
                    <th>選擇</th>
                    <th>id</th>
                    <th>name</th>
                    <th>編碼</th>
                    <th>操作</th>
                </tr>
            </thead>
            <s:iterator id="r1" value="#rank1">
            <s:if test="#current1.id == #r1.id">
            <tr class="chosen" type="${ r1.id}">
                <td><button class="select" id="${ r1.id}" type="1">選擇</button></td>
                <td>${ r1.id}</td>
                <td><input value ="${ r1.name}" id="name${ r1.id}" size="8" ></td>
                <td><input value ="${ r1.code}" id="code${ r1.id}" size="8"></td>
                <td><button type="${ r1.id}" class="update">更新</button> | <button type="${ r1.id}" class="del">刪除</button></td>
            </tr>
            </s:if>
            <s:else>
            <tr type="${ r1.id}">
                <td><button class="select" id="${ r1.id}" type="1">選擇</button></td>
                <td>${ r1.id}</td>
                <td><input value ="${ r1.name}" id="name${ r1.id}" size="8" ></td>
                <td><input value ="${ r1.code}" id="code${ r1.id}" size="8"></td>
                <td><button type="${ r1.id}" class="update">更新</button> | <button type="${ r1.id}" class="del">刪除</button></td>
            </tr>
            </s:else>
            </s:iterator>
        </table>
    </div>
    
    <div style="margin-left:20px;float:left;">
        <h2>二級類別</h2>
        <h3>上級:${current1.name}</h3>
        <form action="letao_DevelopmentModelArea_addArea" id="addForm2">
        編碼:<input size="8" name="code"> name:<input size="8" name="name"><input size="8" name="parent" type="hidden" value="${current1.id}">
        <br/>
        </form>
        <br/>
        <button class="add2">添加</button>
        <table style="border: 2px solid BLACK;">
            <thead>
                <tr>
                    <th>選擇</th>
                    <th>id</th>
                    <th>name</th>
                    <th>編碼</th>
                    <th>操作</th>
                </tr>
            </thead>
            <s:iterator id="r2" value="#rank2">
            
                <s:if test="#current2.id == #r2.id">
                <tr class="chosen" type="${ r2.id}">
                    <td><button class="select" id="${ r2.id}" type="2">選擇</button></td>
                    <td>${ r2.id}</td>
                    <td><input value ="${ r2.name}" id="name${ r2.id}" size="8"></td>
                    <td><input value ="${ r2.code}" id="code${ r2.id}" size="8"></td>
                    <td><button type="${ r2.id}"  class="update">更新</button> | <button type="${ r2.id}" class="del">刪除</button></td>
                </tr>
                </s:if>
                <s:else>
                <tr  type="${ r2.id}">
                    <td><button class="select" id="${ r2.id}" type="2">選擇</button></td>
                    <td>${ r2.id}</td>
                    <td><input value ="${ r2.name}" id="name${ r2.id}" size="8"></td>
                    <td><input value ="${ r2.code}" id="code${ r2.id}" size="8"></td>
                    <td><button type="${ r2.id}"  class="update">更新</button> | <button type="${ r2.id}" class="del">刪除</button></td>
                </tr>
                </s:else>

            </s:iterator>
        </table>
    </div>
        <div style="margin-left:20px;float:left;">
        <h2>三級類別</h2>
        <h3>上級:${current1.name}->${current2.name}</h3>
        <form action="letao_DevelopmentModelArea_addArea" id="addForm3">
        編碼:<input size="8" name="code"> name:<input size="8" name="name"> <input size="8" name="parent" type="hidden" value="${current2.id }">
        <br/>
        </form>
        <br/>
        <button class="add3">添加</button>
        <table style="border: 2px solid BLACK;">
            <thead>
                <tr>
                    <th>id</th>
                    <th>name</th>
                    <th>編碼</th>
                    <th>操作</th>
                </tr>
            </thead>
            <s:iterator id="r3" value="#rank3">
            <tr>
                <td>${ r3.id}</td>
                <td><input value ="${ r3.name}" id="name${ r3.id}" size="8"></td>
                <td><input value ="${ r3.code}" id="code${ r3.id}" size="8"></td>
                <td><button type="${ r3.id}" class="update">更新</button> | <button type="${ r3.id}" class="del">刪除</button></td>
            </tr>
            </s:iterator>
        </table>
    </div>
</div>
<form action="letao_DevelopmentModelArea_updateInfo" method="post" id="updateForm" style="display:none;">
    <input id="hideId" type="hidden" name="id" type="hidden">
    <input id="updateCode" type="hidden" name="code">
    <input id="updateName" type="hidden" name="name">
</form>
<form action = "letao_DevelopmentModelArea_listArea" method="post" id="listForm">
    <input id="firstRankId" type="hidden" name="firstRankId" value="${current1.id }">
    <input id="secondRankId" type="hidden" name="secondRankId" value="${current2.id }">
</form>
</body>
<script>
$('.update').click(function(e){
    var dataId = $(e.target).attr("type");
    $("#hideId").val(dataId);
    $("#updateCode").val($("#code"+dataId).val());
    $("#updateName").val($("#name"+dataId).val());
    $('#updateForm').ajaxSubmit({
            type:'post',
            dataType: 'json',
            success: function (data) {
                if(data.status==1){
                    alert(data.info);
                    location.reload();
                }else{
                    alert(data.info);
                }
            },
            error: function (XMLResponse) {
                //alert(XMLResponse.responseText);
                var ss =JSON.stringify(XMLResponse);
                alert('操作失敗!'+ss);
            }
        });
});
$('.del').click(function(e){
    var dataId = $(e.target).attr("type");
                $.getJSON("letao_DevelopmentModelArea_deleteInfo?id=" + dataId,
                        function(data) {
                            if (data.status == 1) {
                                alert(data.info);
                                location.reload();
                            } else {
                                alert(data.info);
                            }
                        });
            });
$('.add1').click(function(){
    $('#addForm1').ajaxSubmit({
        type:'post',
        dataType: 'json',
        success: function (data) {
            if(data.status==1){
                alert(data.info);
                location.reload();
            }else{
                alert(data.info);
            }
        },
        error: function (XMLResponse) {
            //alert(XMLResponse.responseText);
            var ss =JSON.stringify(XMLResponse);
            alert('操作失敗!'+ss);
        }
    });
});
$('.add2').click(function(){
    $('#addForm2').ajaxSubmit({
        type:'post',
        dataType: 'json',
        success: function (data) {
            if(data.status==1){
                alert(data.info);
                location.reload();
            }else{
                alert(data.info);
            }
        },
        error: function (XMLResponse) {
            //alert(XMLResponse.responseText);
            var ss =JSON.stringify(XMLResponse);
            alert('操作失敗!'+ss);
        }
    });
});
$('.add3').click(function(){
    $('#addForm3').ajaxSubmit({
        type:'post',
        dataType: 'json',
        success: function (data) {
            if(data.status==1){
                alert(data.info);
                location.reload();
            }else{
                alert(data.info);
            }
        },
        error: function (XMLResponse) {
            //alert(XMLResponse.responseText);
            var ss =JSON.stringify(XMLResponse);
            alert('操作失敗!'+ss);
        }
    });
});
$('.select').click(function(e){
    if($(e.target).attr("type") === "1"){
        $('#firstRankId').val($(e.target).attr("id"));
    }else if($(e.target).attr("type") === "2"){
        $('#secondRankId').val($(e.target).attr("id"));
    }
    $('#listForm').submit();
});
</script>
</html>

 

    查詢用的sql語句使用in來構造。頁面控制使用一級當前id和二級當前id作為請求參數刷新頁面。

    action的設計也是一般操作數據庫的形式,不過列表作為頁面展示,而其他作為REST接口。

package com.dijing.letao.action;

import java.util.List;

import com.dijing.letao.DJActionSupport;
import com.dijing.letao.NoNeedLogin;
import com.dijing.letao.dao.AreaDao;
import com.dijing.letao.model.Headquarters.Area;
import com.dijing.server.web.DJAction;
import com.dijing.server.web.action.JsonResult;
import com.opensymphony.xwork2.ActionContext;

/**
 * 地區開發模式校准控制器
 */
public class DevelopmentModelAreaAction extends DJActionSupport{
    private long id;
    private String name;
    private long parent;
    private long firstRankId;
    private long secondRankId;
    private long code;
    /**
     * letao_DevelopmentModelArea_listArea
     * @return
     * @throws Exception
     */
    @NoNeedLogin
    public String listArea() throws Exception {
        return executePage(() -> {
            AreaDao aDao = new AreaDao();
            if(firstRankId == 0 && secondRankId == 0){
                List<Area> rank1 = aDao.findByParent(0);
                List<Area> rank2 = null;
                List<Area> rank3 = null;
                if(rank1.size() > 0){
                    rank2 = aDao.findByParent(rank1.get(0).getId());
                    ActionContext.getContext().put("current1", rank1.get(0));
                }
                if(rank2.size() > 0){
                    rank3 = aDao.findByParent(rank2.get(0).getId());
                    ActionContext.getContext().put("current2", rank2.get(0));
                }
                ActionContext.getContext().put("rank1", rank1);
                ActionContext.getContext().put("rank2", rank2);
                ActionContext.getContext().put("rank3", rank3);
                return DJAction.SHOW;
            }else if(firstRankId != 0 && secondRankId == 0){
                List<Area> rank1 = aDao.findByParent(0);
                List<Area> rank2 = null;
                List<Area> rank3 = null;
                if(rank1.size() > 0){
                    rank2 = aDao.findByParent(rank1.get(0).getId());
                    ActionContext.getContext().put("current1", aDao.findByById(firstRankId));
                }
                if(rank2.size() > 0){
                    rank3 = aDao.findByParent(rank2.get(0).getId());
                    ActionContext.getContext().put("current2", rank2.get(0));
                }
                ActionContext.getContext().put("rank1", rank1);
                ActionContext.getContext().put("rank2", rank2);
                ActionContext.getContext().put("rank3", rank3);
                return DJAction.SHOW;
            }else if(firstRankId != 0 && secondRankId != 0){
                System.out.println("===================");
                List<Area> rank1 = aDao.findByParent(0);
                List<Area> rank2 = null;
                List<Area> rank3 = null;
                if(rank1.size() > 0){
                    rank2 = aDao.findByParent(rank1.get(0).getId());
                    ActionContext.getContext().put("current1", aDao.findByById(firstRankId));
                }
                if(rank2.size() > 0){
                    rank3 = aDao.findByParent(aDao.findByById(secondRankId).getId());
                    ActionContext.getContext().put("current2", aDao.findByById(secondRankId));
                }
                ActionContext.getContext().put("rank1", rank1);
                ActionContext.getContext().put("rank2", rank2);
                ActionContext.getContext().put("rank3", rank3);
                return DJAction.SHOW;
            }else
                return DJAction.FAILURE;
        });
    }
    /**
     * letao_DevelopmentModelArea_updateInfo
     * @return
     * @throws Exception
     */
    @NoNeedLogin
    public String updateInfo() throws Exception {
        return execute(() -> {
            if(name == null || code == 0 || id == 0)
                return ok(JsonResult.jsonResultError("請求為空"));
            AreaDao aDao = new AreaDao();
            Area a = aDao.findByById(id);
            a.setName(name);
            a.setCode(code);
            if(a.update())
                return ok(JsonResult.jsonResultSuccess("更新成功:"));
            else
                return ok(JsonResult.jsonResultError("更新失敗"));
        });
    }
    /**
     * letao_DevelopmentModelArea_deleteInfo
     * @return
     * @throws Exception
     */
    @NoNeedLogin
    public String deleteInfo() throws Exception {
        if(id == 0)
            return ok(JsonResult.jsonResultError("請求為空"));
        AreaDao aDao = new AreaDao();
        Area a = aDao.findByById(id);
        if(a == null)
            return ok(JsonResult.jsonResultError("條目不存在"));
        List<Area> son1 = aDao.findByParent(a.getId());
        
        if(son1.size() >0){
            List<Area> son2 = aDao.findByParentList(son1);
            for(Area s:son2)
                s.delete();
        }
        for(Area s:son1)
            s.delete();
        a.delete();
        return ok(JsonResult.jsonResultSuccess("刪除成功"));
    }
    /**
     * letao_DevelopmentModelArea_addArea
     * @return
     * @throws Exception
     */
    @NoNeedLogin
    public String addArea() throws Exception {
        return execute(() -> {
            if(name == null)
                return ok(JsonResult.jsonResultError("請求為空"));
            if(parent >0){
                AreaDao aDao = new AreaDao();
                if(aDao.findByParent(parent) == null)
                    ok(JsonResult.jsonResultError("父級不存在 添加不合法"));
            }
            Area a = new Area();
            a.setName(name);
            a.setCode(code);
            a.setParent(parent);
            if(a.save())
                return ok(JsonResult.jsonResultSuccess("添加成功:"));
            else
                return ok(JsonResult.jsonResultError("添加失敗,已存在"));
        });
    }
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public long getParent() {
        return parent;
    }
    public void setParent(long parent) {
        this.parent = parent;
    }
    public long getFirstRankId() {
        return firstRankId;
    }
    public void setFirstRankId(long firstRankId) {
        this.firstRankId = firstRankId;
    }
    public long getSecondRankId() {
        return secondRankId;
    }
    public void setSecondRankId(long secondRankId) {
        this.secondRankId = secondRankId;
    }
    public long getCode() {
        return code;
    }
    public void setCode(long code) {
        this.code = code;
    }
}

    dao層查詢的方法,也是很簡單的單表查詢。

    public List<Area> findByParent(long parent) {
        return mysql.queryListSql(model, " where parent="+parent);
    }
    public List<Area> findByParentList(List<Area> list){
        StringBuilder sb = new StringBuilder();
        sb.append("where parent in (");
        sb.append(list.get(0).getId());
        for(int i=1;i<list.size();i++){
            sb.append(",");
            sb.append(list.get(i).getId());
        }
        sb.append(")");
        return mysql.queryListSql(model, sb.toString());
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM