1. 程式人生 > >springboot jpa 樹物件 遞迴遍歷知道當前第幾層

springboot jpa 樹物件 遞迴遍歷知道當前第幾層

現在時間是週五晚上九點十八分,視線左邊手機播放著電影《鬼入侵》,正對著我的就是我的電腦了。剛才玩了幾局吃雞遊戲,眼睛花的不想玩了,乾脆就敲程式碼吧,沒有女朋友的都和我一樣嗎?哈哈

最近想把家裡的網站升級一下,這個防火布網站主要是把後臺重新做一下,昨天寫到了資料的顯示,今天就寫儲存了。後臺是用vue element寫的,感覺這個框架非常好用,有興趣的可以瞭解一下,這個tree支援拖拽的。

我的願望是娶個媳婦幫著設計介面,因為我做出的介面太醜了,有意的可以留言,我還沒談過戀愛呢(用我爸爸的話說還是小雛雞呢),妳要抓緊聯絡我呀。

分類物件:Category

package com.dcssn.weian.cms.entity;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 分類
 *
 * @author lihy
 * @version 2018/10/15
 */
@Entity
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 名稱
     */
    private String name;

    /**
     * 關鍵詞
     */
    private String keywords;

    /**
     * 描述
     */
    private String description;

    /**
     * 層級
     */
    private Integer level;

    /**
     * 排序
     */
    private Integer sequence;

    /**
     * 子類
     */
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "parent_id")
    @OrderBy("sequence asc")
    private List<Category> 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 String getKeywords() {
        return keywords;
    }

    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    public String getDescription() {
        return description;
    }

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

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    public Integer getSequence() {
        return sequence;
    }

    public void setSequence(Integer sequence) {
        this.sequence = sequence;
    }

    public List<Category> getChildren() {
        return children;
    }

    public void setChildren(List<Category> children) {
        this.children = children;
    }
}

資料庫中的內容:

keywords 和 description是我做seo優化用的
CategoryRepository
package com.dcssn.weian.cms.repository;

import com.dcssn.weian.cms.entity.Category;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**
 * 分類
 *
 * @author lihy
 * @version 2018/10/16
 */
public interface CategoryRepository extends JpaRepository<Category, Long> {
    /**
     * 根據層級查詢
     *
     * @param level 層級
     * @return java.util.List<com.dcssn.weian.cms.entity.Category>
     * @author lihy
     */
    List<Category> findByLevel(Integer level);

    /**
     * 獲取最新的id
     *
     * @return java.lang.Long
     * @author lihy
     */
    @Query(value = "select id from category order by id desc limit 1", nativeQuery = true)
    Long getLatestId();

}
findByLevel(1) 查出資料用於頁面展示
[{
	"id": 1,
	"name": "蔬菜",
	"keywords": null,
	"description": null,
	"level": 1,
	"sequence": 0,
	"children": [{
		"id": 3,
		"name": "蘿蔔",
		"keywords": null,
		"description": null,
		"level": 2,
		"sequence": 0,
		"children": []
	}, {
		"id": 2,
		"name": "白菜",
		"keywords": null,
		"description": null,
		"level": 2,
		"sequence": 1,
		"children": []
	}]
}, {
	"id": 4,
	"name": "水果",
	"keywords": null,
	"description": null,
	"level": 1,
	"sequence": 1,
	"children": [{
		"id": 5,
		"name": "蘋果",
		"keywords": null,
		"description": null,
		"level": 2,
		"sequence": 0,
		"children": [{
			"id": 6,
			"name": "青蘋果",
			"keywords": null,
			"description": null,
			"level": 3,
			"sequence": 1,
			"children": []
		}, {
			"id": 7,
			"name": "紅將軍",
			"keywords": null,
			"description": null,
			"level": 3,
			"sequence": 2,
			"children": []
		}]
	}, {
		"id": 8,
		"name": "香蕉",
		"keywords": null,
		"description": null,
		"level": 2,
		"sequence": 1,
		"children": []
	}]
}]

結構就是這樣的,當我提交儲存的時候也會提交上述格式的資料,返回的資料沒有level和sequence資訊,所以我們在遍歷儲存的時候為其賦值。

寫個測試類

package com.dcssn.weian;

import com.dcssn.weian.cms.entity.Category;
import com.dcssn.weian.cms.repository.CategoryRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class WeianApplicationTests {

    @Autowired
    CategoryRepository categoryRepository;

    /**
     * 新增資料
     *
     * @author lihy
     */
    @Test
    public void addData() {
        Category category = new Category();
        category.setName("蔬菜");
        Category categoryChild = new Category();
        categoryChild.setName("白菜");
        Category categoryChild2 = new Category();
        categoryChild2.setName("蘿蔔");
        category.setChildren(new ArrayList<Category>() {{
            add(categoryChild);
            add(categoryChild2);
        }});
        categoryRepository.save(category);
    }

    /**
     * 讀取資料
     *
     * @author lihy
     */
    @Test
    public void readData() {
        List<Category> categoryList = categoryRepository.findByLevel(1);
        for (int i = 0; i < categoryList.size(); i++) {
            recursion(categoryList.get(i), 1, i);
        }
    }

    /**
     * 遞迴
     *
     * @param category 分類
     * @param level    層級
     * @param index    同級排序
     * @author lihy
     */
    private void recursion(Category category, int level, int index) {
        System.out.printf("%" + level * 2 + "s\n", category.getName());
        // TODO: 設定 category的level和sequence 並儲存
        Category categoryTemp;
        for (int i = 0; i < category.getChildren().size(); i++) {
            categoryTemp = category.getChildren().get(i);
            recursion(categoryTemp, level + 1, i);
        }
    }

}

執行結果

q群 806893930