软件工程应用与实践(2)——知识图谱树形结构获取
2021SC@SDUSC
目錄
- 一、知識圖譜的結構
- 二、前端代碼
- 2.1 對axios請求的封裝
- 2.2 樹形控件代碼及其分析
- 三、后端代碼
- 3.1 樹形結構對應的實體類
- 3.2 填充知識樹的過程
- 3.3 知識樹的JSON表示
- 四、總結
一、知識圖譜的結構
老年健康知識圖譜系統的知識結構是一棵4層的樹,每個葉子節點對應一個知識。
以老年綜合征為例,具體的圖形如下(該圖僅包含部分細節)
該系統實現的功能是,獲取整棵樹的所有節點,并返回到前端,用戶點擊對應的節點后,查看該知識的詳細信息(包含視頻,圖片,文字,音頻)
二、前端代碼
2.1 對axios請求的封裝
設置baseURL及超時時間
通過設置baseURL,可以簡化每次發請求時輸入的路徑,只需要寫后面的路徑,前面的路徑直接省略,避免請求路徑重復的問題。設置超時時間為5秒,若網速過慢發送不成功則會報錯
import axios from "axios"; //創建默認實例 const instance = axios.create({baseURL:"http://localhost:8989",timeout:5000 }) //暴露instance實例 export default instance設置請求攔截器,響應攔截器,并添加加載效果
當前端向后端請求數據,數據尚未返回時,由于被請求攔截器攔截,會出現加載效果,當返回數據時,經過響應攔截器,終止加載效果。加載效果的具體動畫使用element ui自帶的loading組件實現
let loadingInstance = null; //請求攔截器 instance.interceptors.request.use(config=>{//展示loading效果loadingInstance = Loading.service({fullscreen:true,background:'rgba(0,0,0,0.6)',text:'拼命加載中'});return config; }) //響應攔截器 instance.interceptors.response.use(response=>{//隱藏loading效果loadingInstance.close()return response; })設置導航守衛
當用戶未登錄時,部分頁面無法訪問,若用戶直接訪問鏈接,則需跳轉到登錄界面,不能直接進入受到保護的界面,本項目使用vue的beforeEach方法實現導航守衛
子路由中配置頁面的權限,使用meta中的requireAuth進行配置,如果為true,則說明需要登錄權限才可訪問
{path: '/personInfo',name: 'PersonInfo',component: PersonInfo,meta:{requireAuth:true,title:'個人信息'} },設置路由攔截方法
所有請求都會經過這個方法,如果需要權限且用戶未登錄,則跳轉至登錄界面,如果有權限,則使用next方法放行該請求
//路由攔截 router.beforeEach((to,from,next)=>{//設置標題if (to.meta.title) {document.title = to.meta.title}// 判斷該路由是否需要登錄權限if (to.meta.requireAuth) {// 通過sessionStorage檢驗當前的token是否存在if (sessionStorage.getItem("token") == 'login') {next();}else {next({path: '/login',// 將跳轉的路由path作為參數,登錄成功后跳轉到該路由query: {redirect: to.fullPath}})}}else {next();} })2.2 樹形控件代碼及其分析
前端使用element ui的樹形控件,展示知識圖譜
樹形控件及其方法
使用element ui的el-tree標簽,該系統定義了 @node-click="getCheckedNodes"方法,實現點擊“葉子”后,向后端發送請求,后端返回具體的數據,并呈現在表格中
<el-treeclass="filter-tree":data="treeData":props="defaultProps"default-expand-all:filter-node-method="filterNode"@node-click="getCheckedNodes"ref="tree"> </el-tree>對應的數據和方法
treeData用于保存后端返回的樹形數據
data(){return{//樹形控件數據filterText: '',treeData: [{label: '一級',children: [{label: '二級 1-1',children: [{label: '三級 1-1-1'}, {label: '三級 1-1-2'}]}]}],defaultProps: {children: 'children',label: 'label'},//表格數據tableData: []} },getCheckedNodes(data,node,element)方法在用戶點擊具體的葉子時觸發,根據node.level獲取當前知識所在的層數,由于第三層和第四層都有相應的數據(有部分第三層的節點沒有第四層)。同時,第三層的節點有屬于自己的數據,與第四層的數據不同,因此需要分別獲取。
<script>methods:{//獲取當前選中的節點并呈現數據getCheckedNodes(data,node,element){//如果是第3層節點if(node.level == 3){//獲取知識名稱let knowledgeName = data.label;//向后端發送axios請求,獲取數據instance.get("knowledge/third/" + knowledgeName).then(res=>{this.tableData = res.data;})}//如果是第4層節點else if(node.level == 4){//獲取知識名稱let knowledgeName = data.label;//向后端發送axios請求,獲取數據instance.get("knowledge/fourth/" + knowledgeName).then(res=>{this.tableData = res.data;})}}} } </script>vue的created方法執行時,data數據已經初始化完成,此時從后端獲取樹形知識圖譜的數據(即整棵樹)
created() {//從后端獲取對應的數據instance.get("treeDate/nodes").then(res=>{this.treeData = res.data}) }三、后端代碼
后端代碼分為controller層,service層,dao層
controller層負責定義與前端交互的接口,service層負責定義執行具體的事務,dao層負責操作數據庫
controller層調用service層,service層調用dao層代碼
3.1 樹形結構對應的實體類
為了返回對應的樹形結構到前端,后端需要定義對應的實體類存儲對應的樹形結構,在定義實體類的時候,本項目使用lombok注解,避免了大量的set,get方法重復書寫。
葉子節點使用List結構存儲
package com.sdu.nurse.entity;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors;import java.util.List;@Data @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) public class TreeData {//節點名private String label;//節點對應的子節點private List<TreeData> children; }3.2 填充知識樹的過程
在本項目中,知識樹共有四層,本項目使用了逐層獲取,逐層填充的方式從數據庫中獲取對應的數據,并填充知識樹
dao層接口
本項目使用mybatis-plus,繼承BaseMapper,可以對單表查詢進行快速操作
package com.sdu.nurse.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.sdu.nurse.entity.TreeData; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param;import java.util.List;@Mapper public interface TreeDataDao extends BaseMapper<TreeData> {//獲取所有一級名稱List<TreeData> getAllFirstNodes();//根據一級名稱獲取所有二級名稱List<TreeData> getAllSecondNodes(@Param("firstNodeName") String firstNodeName);//根據二級名稱獲取所有三級名稱List<TreeData> getAllThirdNodes(@Param("secondNodeName") String secondNodeName);//根據三級名稱獲取所有四級名稱List<TreeData> getALlFourthNodes(@Param("thirdNodeName") String thirdNodeName); }service層代碼
使用@Autowired注解,利用spring工廠自動注入的特性將TreeDataDao注入,不需要程序員手動注入。在service層中通過getAllTreeNodes方法逐層獲取葉子節點的數據,最終將List<TreeData>填充完成,返回給controller層
package com.sdu.nurse.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.sdu.nurse.dao.TreeDataDao; import com.sdu.nurse.entity.TreeData; import com.sdu.nurse.service.TreeDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.ArrayList; import java.util.List;@Service public class TreeDateServiceImpl implements TreeDataService {@Autowiredprivate TreeDataDao treeDataDao;@Overridepublic List<TreeData> getAllTreeNodes() {//獲取一級節點List<TreeData> healthTreeNodes = getFirstNodes();//獲取二級節點healthTreeNodes.forEach(healthTreeNode->{healthTreeNode.setChildren(getSecondNodes(healthTreeNode.getLabel()));});//獲取三級節點healthTreeNodes.forEach(healthTreeNode->{healthTreeNode.getChildren().forEach(second->{second.setChildren(getThirdNodes(second.getLabel()));});});//獲取四級節點healthTreeNodes.forEach(healthTreeNode->{healthTreeNode.getChildren().forEach(second->{second.getChildren().forEach(third->{third.setChildren(getFourthNodes(third.getLabel()));});});});return healthTreeNodes;}@Overridepublic List<TreeData> getFirstNodes() {return treeDataDao.getAllFirstNodes();}@Overridepublic List<TreeData> getSecondNodes(String firstNodeName) {return treeDataDao.getAllSecondNodes(firstNodeName);}@Overridepublic List<TreeData> getThirdNodes(String secondNodeName) {return treeDataDao.getAllThirdNodes(secondNodeName);}@Overridepublic List<TreeData> getFourthNodes(String thirdNodeName) {return treeDataDao.getALlFourthNodes(thirdNodeName);} }controller層代碼
@CrossOrigin注解解決前后端通過AJAX傳輸數據時跨域的問題,@RestController注解表明這是一個符合restful規范的,前后端交互的接口。@GetMapper注解表明使用get請求獲取數據
package com.sdu.nurse.controller;import com.sdu.nurse.entity.TreeData; import com.sdu.nurse.service.TreeDataService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;import java.util.List;@CrossOrigin @RestController @RequestMapping("treeDate") public class TreeDataController {@Autowiredprivate TreeDataService treeDataService;@GetMapping("nodes")public List<TreeData> getAllTreeNodes(){return treeDataService.getAllTreeNodes();} }3.3 知識樹的JSON表示
使用postman工具對后端接口進行測試,返回的知識樹的部分結構如下
將此JSON返回到前端,結合element ui的樹形控件,即可實現樹形數據的呈現與選擇
四、總結
由于本項目的主要功能之一就是方便老年人查看關于老年疾病的各種類型和詳細信息,因此獲取知識圖譜的樹狀數據是該系統很重要的一項功能,經過小組討論與分工,最終決定由我完成樹形結構獲取及樹形數據具體展示的源代碼分析。本項目關于知識圖譜的內容還是比較清晰的,除了本篇博客以外,之后還會有一篇補充博客對獲取具體葉子節點對應的具體知識數據進行分析。
總結
以上是生活随笔為你收集整理的软件工程应用与实践(2)——知识图谱树形结构获取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 利用python爬取淘宝的商品图片
- 下一篇: 【Python知识树 -- 预备知识】之