日韩精品欧美激情国产一区_中文无码精品一区二区三区在线_岛国毛片AV在线无码不卡_亞洲歐美日韓精品在線_使劲操好爽好粗视频在线播放_日韩一区欧美二区_八戒八戒网影院在线观看神马_亚洲怡红院在线色网_av无码不卡亚洲电影_国产麻豆媒体MDX

基于springboot jpa thymeleaf的java無限分類

時(shí)間:2020-08-24 23:17:48 類型:JAVA
字號(hào):    

基于springboot jpa thymeleaf的java無限分類的樣式及表格創(chuàng)建見:

http://tjegd.cn/news/show/866.html

一. 建立實(shí)體文件如下:

@Entity
public class Sorts {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String sortName;
    private int parentId;
    private String sortPath;
    private int levels;
    private int orders;
    @Transient
    private String space; //列表查詢時(shí), 前面的空間隔
    @Transient
    private String oldSortPath;
    @Transient
    private String newSortPath;



    public String getSortName() {
        return sortName;
    }

    public void setSortName(String sortName) {
        this.sortName = sortName;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }



    public int getParentId() {
        return parentId;
    }

    public void setParentId(int parentId) {
        this.parentId = parentId;
    }

    public String getSortPath() {
        return sortPath;
    }

    public void setSortPath(String sortPath) {
        this.sortPath = sortPath;
    }

    public int getLevels() {
        return levels;
    }

    public void setLevels(int levels) {
        this.levels = levels;
    }

    public int getOrders() {
        return orders;
    }

    public void setOrders(int orders) {
        this.orders = orders;
    }

    public String getSpace() {
        return space;
    }

    public void setSpace(String space) {
        this.space = space;
    }

    public String getOldSortPath() {
        return oldSortPath;
    }

    public void setOldSortPath(String oldSortPath) {
        this.oldSortPath = oldSortPath;
    }

    public String getNewSortPath() {
        return newSortPath;
    }

    public void setNewSortPath(String newSortPath) {
        this.newSortPath = newSortPath;
    }
}

二.  建立Resotitory接口

public interface SortsRepository extends JpaRepository<Sorts,Integer>, JpaSpecificationExecutor<Sorts> {
    @Query(value=" select * from sorts where parentId = ?1 order by orders asc ",nativeQuery=true )
    public ArrayList<Sorts> selectByParentId(Integer id) ;
    @Query(value="select * from sorts where parentId = :#{#sorts.parentId} and sortName = :#{#sorts.sortName}",nativeQuery=true )
    public Sorts selectBySortNameAndParendId(@Param("sorts") Sorts sorts);
    @Query(value = " select * from sorts where parentId = :#{#sorts.parentId} and sortName = :#{#sorts.sortName} " +
            "and id <> :#{#sorts.id}",nativeQuery = true)
    public Sorts selectSortsByParentIdSortName(@Param("sorts") Sorts sorts);
    @Query(value = " update sorts set sortPath = replace(sortPath,:#{#sorts.oldSortPath},:#{#sorts.newSortPath}) where\n" +
            "        sortPath like concat('%',:#{#sorts.oldSortPath},'%') and id <> :#{#sorts.id}",
            nativeQuery = true)
    @Transactional
    @Modifying
    public int updateAllChildSorts(@Param("sorts")Sorts sorts);

    @Query(value = "  update sorts set levels = length(sortPath)- length(replace(sortPath,',','')) - 1 where\n" +
            "        sortPath like concat('%',:#{#sorts.newSortPath},'%') and id <> :#{#sorts.id}",
            nativeQuery = true)
    @Transactional
    @Modifying
    public int updateAllChildSortsLevels(@Param("sorts")Sorts sorts);

    @Query(value = "delete from sorts where sortPath like concat ('%',','+ :id +',','%')",
            nativeQuery = true)
    @Transactional
    @Modifying
    public int deleteAllSortsById(@Param("id") Integer id);
}

三.  建立service接口

public interface SortsService {
    public ArrayList<Sorts> getChildren(int parentId, String  space, ArrayList<Sorts> arr);
    public StringBuffer selectTrees(int pid,String selectName,int currentId);
    public String addSorts(Sorts sorts);
    public String updateSorts(Sorts sorts);
    public String deleteAllSortsById(Integer id);
}

四. 實(shí)現(xiàn)SortsService接口類

@Service("sortsService")
public class SortsServiceImpl implements SortsService {
    @Autowired
    private SortsRepository sortsDao;
    private static ArrayList<Sorts> all;  //存儲(chǔ)所有的查詢子類數(shù)據(jù)
    @Override
    //parentId:  父類 ID, 查詢當(dāng)前類別下的所有子類
    //space :  // 類別前面的空隔
    public  ArrayList<Sorts> getChildren(int parentId, String  space, ArrayList<Sorts> arr){
        if(arr == null){
            //第一次查詢
            System.out.println(parentId);
            arr = sortsDao.selectByParentId(parentId);
            all = new ArrayList<>(); //第一次時(shí), 初始化, 避免刷新調(diào)用重新添加信息
        }
        if(arr != null){
            for(Sorts sorts : arr){
                //根據(jù)級(jí)別不一樣, 在前面加上相應(yīng)的分隔符
                int levels = sorts.getLevels();
                if(levels == 1){
                    sorts.setSpace("");
                }
                else if(levels == 2){
                    space = "  |---->";
                    sorts.setSpace(space);
                }
                else{
                    sorts.setSpace(space);
                }
                all.add(sorts); //將所有的信息都加到all里, 并增加一個(gè)space字段
                parentId = sorts.getId();
                ArrayList<Sorts> arr_child = sortsDao.selectByParentId(parentId);
                if(arr_child != null){
                    getChildren(parentId,"  |" + space,arr_child);
                }
            }
        }
        return  all;
    }

    @Override
    //得到無限分類的select下拉列表
    //pid : 父id
    //selectName select的名字
    //currenId : 被選擇的id, 沒有的話,傳遞0 
    public StringBuffer selectTrees(int pid, String selectName, int currentId) {
        StringBuffer sBuffer = new StringBuffer();
        ArrayList<Sorts> results = getChildren(pid,"",null);
        if(results != null){
            sBuffer.append("<select name='"+selectName+"'>\n");
            sBuffer.append("<option value='0'>一級(jí)類別</option> \n");
            for(Sorts sorts : results){
                int id = sorts.getId();
                if( id == currentId){
                    sBuffer.append("<option value='"+id+"' style='background:#E20A0A; color:#fff;' selected>"+
                            sorts.getSpace() + sorts.getSortName() + "</option> \n");
                }
                else{
                    sBuffer.append("<option value='"+id+"'>"+ sorts.getSpace() + sorts.getSortName() + "</option> \n");
                }
            }
            sBuffer.append("</select>\n");
        }

        return  sBuffer;
    }

    @Override
    public String addSorts(Sorts sorts) {
        //判斷類名不能為空
        if(sorts.getSortName().equals("")) {
            return "<script>alert('類別名稱不能為空');history.back();</script>";
        }
        //判斷同一級(jí)下不能重復(fù)的名稱
        if(sortsDao.selectBySortNameAndParendId(sorts) != null){
            return "<script>alert('父類下已存在相同類別!!!');history.back();</script>";
        }
        //設(shè)置level, sortpath 信息  begin
        sorts.setLevels(1);
        sorts.setSortPath("0,");
        if(sorts.getParentId() != 0){
            //最頂級(jí)時(shí)使用默認(rèn)設(shè)置值, 否則根據(jù)父級(jí)來決定
            Sorts getSorts = sortsDao.getOne(sorts.getParentId());
            sorts.setLevels(getSorts.getLevels() + 1);
            sorts.setSortPath(getSorts.getSortPath());
            //暫時(shí)為父級(jí)sortPath, 當(dāng)添加后, 再更新,將當(dāng)前的id鏈接上
        }

        //將信息添加到數(shù)據(jù)庫(kù)sorts
        sortsDao.save(sorts); //sorts中會(huì)更新為新增加的id主鍵

        //更新sortPath 到數(shù)據(jù)庫(kù)
        sorts.setSortPath(sorts.getSortPath() + sorts.getId() + ",");
        sortsDao.save(sorts);
        return "<script>alert('添加成功');location.href='/admin/sorts/list';</script>";
    }

    @Override
    public String updateSorts(Sorts sorts) {
        //判斷類名不能為空
        if(sorts.getSortName().equals("")) {
            return "<script>alert('類別名稱不能為空');history.back();</script>";
        }
        //根據(jù)id得到原來的信息
        Sorts oldSorts = sortsDao.getOne(sorts.getId());
        int oldPid = oldSorts.getParentId(); //原父id
        String oldSortPath = oldSorts.getSortPath();
        //判斷類別名稱是否重復(fù)
        Sorts exitSorts = sortsDao.selectSortsByParentIdSortName(sorts);
        if(exitSorts != null){
            return "<script>alert('類別已經(jīng)存在,請(qǐng)更換類別名稱');history.back();</script>";
        }

        if(oldPid == sorts.getParentId()){
            //父id不變, 則parentid, level都不需要修改
            sorts.setSortPath(oldSorts.getSortPath());
            sorts.setLevels(oldSorts.getLevels());
            sortsDao.save(sorts);
        }
        else if(sorts.getParentId() == 0){
            //移動(dòng)到一級(jí)類別
            sorts.setSortPath("0," + sorts.getId() + ",");
            sorts.setLevels(1);
            //更新當(dāng)前類別信息
            sortsDao.save(sorts);

            //更新所有的修改類別的子類sortPath
            Sorts sort1 = new Sorts();
            sort1.setOldSortPath(oldSortPath);
            sort1.setNewSortPath(sorts.getSortPath());
            sort1.setId(sorts.getId());
            sortsDao.updateAllChildSorts(sort1);
            //更新所有子類的層級(jí)
            sortsDao.updateAllChildSortsLevels(sort1);
        }
        else{
            //判斷是否移到到了子類另, 這樣是不允許的, 中間會(huì)斷層
            //得到當(dāng)前父類的path
            Sorts parentSorts = sortsDao.getOne(sorts.getParentId());
            String parentSortPath = parentSorts.getSortPath();
            if(parentSortPath.indexOf(oldSortPath) >= 0){
                return "<script>alert('類別不能選擇為原父類的子類');history.back();</script>";
            }
            else{
                //父類更新到上一級(jí)或者其它的類別下, 那么該類別下所有的子類都需要更新父級(jí)sortpath
                //新的sortpath
                String newSortPath = parentSortPath + sorts.getId() + ",";
                int    newLevel    = parentSorts.getLevels() + 1;
                sorts.setSortPath(newSortPath);
                sorts.setLevels(newLevel);
                sortsDao.save(sorts);
                //更新所有的修改類別的子類

                //更新所有的修改類別的子類sortPath
                //更新所有的修改類別的子類sortPath
                Sorts sort1 = new Sorts();
                sort1.setOldSortPath(oldSortPath);
                sort1.setNewSortPath(sorts.getSortPath());
                sort1.setId(sorts.getId());
                sortsDao.updateAllChildSorts(sort1);
                //更新所有子類的層級(jí)
                sortsDao.updateAllChildSortsLevels(sort1);
            }
        }
        return "<script>alert('修改成功');location.href='/admin/sorts/list';</script>";
    }

    //刪除所有的子類
    @Override
    public String deleteAllSortsById(Integer id) {
        sortsDao.deleteAllSortsById(id);
        return "<script>alert('刪除成功');location.href='/admin/sorts/list';</script>";
    }
}

五. 控制器實(shí)現(xiàn)如下:

@Controller
public class SortsController {
    @Autowired
    @Qualifier("sortsService")
    private SortsService sortsService;
    @Autowired
    private SortsRepository sortsDao;
    @GetMapping(value = "/admin/sorts/add")
    public String add(@RequestParam(defaultValue = "0") Integer parentId, Model model){
        model.addAttribute("selectTrees",sortsService.selectTrees(0,"parentId",parentId));
        return "admin/sorts/add";
    }
    @PostMapping(value = "/admin/sorts/addSave")
    @ResponseBody
    public String addSave(Sorts sorts){
        return sortsService.addSorts(sorts);
    }

    @GetMapping(value = "/admin/sorts/list")
    public String list(Model model){
        ArrayList<Sorts> all = sortsService.getChildren(0,"",null);
        model.addAttribute("all",all);
        return "admin/sorts/list";
    }

    @GetMapping(value = "/admin/sorts/update")
    public String update(@RequestParam(defaultValue = "0") Integer id,Model model){
        Sorts sorts = sortsDao.getOne(id);
        model.addAttribute("sorts",sorts);
        model.addAttribute("selectTrees",sortsService.selectTrees(0,"parentId",sorts.getParentId()));
        return "/admin/sorts/update";
    }

    @PostMapping(value = "/admin/sorts/updateSave")
    @ResponseBody
    public String updateSave(Sorts sorts){
        return sortsService.updateSorts(sorts);
    }

    @GetMapping(value = "/admin/sorts/del")
    @ResponseBody
    public String del(@RequestParam(defaultValue = "0") Integer id){
        return sortsService.deleteAllSortsById(id);
    }
}

六. 對(duì)應(yīng)的視圖文件如下:

    添加視圖:

<form action="/admin/sorts/addSave" method="post">
    <li>
        <label>父級(jí)類別:</label>
        [(${selectTrees})]
    </li>
    <li>
        <lable>類別名稱: </lable>
        <input type="text" name="sortName" />
    </li>
    <li>
        <label>排序: </label>
        <input type="number"  name="orders" value="1" />
    </li>
    <li>
        <input type="submit"/>
    </li>
</form>

修改視圖:

<form action="/admin/sorts/updateSave" method="post" th:object="${sorts}">
    <li>
        <label>父級(jí)類別:</label>
        [(${selectTrees})]
    </li>
    <li>
        <lable>類別名稱: </lable>
        <input type="text" th:field="*{sortName}"/>
    </li>
    <li>
        <label>排序: </label>
        <input type="number" th:field="*{orders}"/>
    </li>
    <li>
        <input type="hidden" th:field="*{id}">
        <input type="submit"/>
    </li>
</form>

列表視圖:

<table>
    <tr>
        <td colspan="4">
            <a href="/admin/sorts/add">添加一級(jí)類別</a>
        </td>
    </tr>
    <tr>
        <td>ID</td>
        <td>類別名稱</td>
        <td>排序</td>
        <td>操作</td>
    </tr>

    <tr th:each="sorts : ${all}">
        <td th:text="${sorts.id}">id</td>
        <td th:text="${sorts.space}+${sorts.sortName}">類別名稱</td>
        <td th:text="${sorts.orders}">排序</td>
        <td>
            <a th:href="@{'/admin/sorts/add?parentId='+ ${sorts.id}}">添加子類</a>
            <a th:href="@{'/admin/sorts/update?id='+ ${sorts.id}}">修改</a>
            <a th:href="@{'/admin/sorts/del?id='+ ${sorts.id}}"  onclick="return confirm('確認(rèn)要?jiǎng)h除嗎');">刪除</a>
        </td>
    </tr>
</table>

源碼下載:

springboot jpa無限分類.zip


<