自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用 Spring Boot3.3 與 MyBatis-Plus 聯(lián)合實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載策略

開發(fā) 前端
本文介紹了如何使用Spring Boot結(jié)合MyBatis-Plus實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載策略。我們通過一個簡單的分類樹示例展示了如何在前端逐步加載節(jié)點(diǎn),避免一次性加載大量數(shù)據(jù)帶來的性能問題。

在使用 Spring Boot 和 MyBatis-Plus 實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載策略時,理解其基本原理和技術(shù)背景是至關(guān)重要的。本文將詳細(xì)探討如何通過 Spring Boot 的 RESTful API 和 MyBatis-Plus 的強(qiáng)大功能實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載,并展示如何使用 Thymeleaf、Bootstrap 和 JavaScript 實(shí)現(xiàn)前端的動態(tài)渲染。

什么是多層次樹結(jié)構(gòu)?

多層次樹結(jié)構(gòu)是許多應(yīng)用場景中的常見需求,尤其是在分類管理、組織結(jié)構(gòu)、權(quán)限管理等場景中。例如,電商平臺中的商品分類可以有多個層級,從根類別到具體商品的詳細(xì)分類,形成一個遞歸的樹形結(jié)構(gòu)。為了有效管理和展示這些數(shù)據(jù),通常需要對其進(jìn)行異步加載,即在用戶需要時才加載具體的層級數(shù)據(jù),而不是一次性加載所有數(shù)據(jù)。這不僅能夠減少初始數(shù)據(jù)加載的時間,還可以提高用戶體驗。

異步加載的意義

在處理大型樹結(jié)構(gòu)時,性能是一個非常重要的考量因素。一次性加載所有層級的數(shù)據(jù)不僅可能會導(dǎo)致數(shù)據(jù)傳輸過大,還會引發(fā)前端頁面的性能問題。異步加載策略通過在用戶展開某個節(jié)點(diǎn)時,動態(tài)加載該節(jié)點(diǎn)下的子節(jié)點(diǎn)數(shù)據(jù),有效地減少了數(shù)據(jù)傳輸量,提高了頁面響應(yīng)速度。這種方法尤其適用于需要處理大量數(shù)據(jù)并且層級較多的場景。

技術(shù)選型與實(shí)現(xiàn)思路

為了實(shí)現(xiàn)上述功能,我們將采用 Spring Boot 構(gòu)建后端 API,使用 MyBatis-Plus 處理數(shù)據(jù)庫操作,并通過前端的 Thymeleaf 模板、Bootstrap 進(jìn)行 UI 展示。具體實(shí)現(xiàn)步驟包括:

  1. 數(shù)據(jù)庫設(shè)計: 創(chuàng)建一個 category 表,包含 id、parent_id、name 等字段,用于存儲分類的層次結(jié)構(gòu)。
  2. 后端實(shí)現(xiàn): 使用 Spring Boot 構(gòu)建 RESTful API,通過 MyBatis-Plus 進(jìn)行數(shù)據(jù)查詢。后端 API 將支持根據(jù) parent_id 查詢子節(jié)點(diǎn)數(shù)據(jù),提供給前端進(jìn)行異步加載。
  3. 前端實(shí)現(xiàn): 使用 Thymeleaf 模板引擎生成 HTML 頁面,并通過 Bootstrap 提供的組件美化頁面。通過 JavaScript 實(shí)現(xiàn)異步加載功能,當(dāng)用戶點(diǎn)擊某個分類節(jié)點(diǎn)時,發(fā)送請求加載其子分類數(shù)據(jù),并動態(tài)渲染到頁面上。
  4. 代碼示例與配置: 文章中將提供完整的代碼示例,包括 Spring Boot 項目配置、MyBatis-Plus 的 Mapper 和 Service 實(shí)現(xiàn),以及前端 HTML、JavaScript 代碼,幫助開發(fā)者快速理解和實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載。

本篇文章將深入講解如何使用 Spring Boot3.3 和 MyBatis-Plus 聯(lián)合實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載,并提供完整的代碼示例。

運(yùn)行效果:

圖片圖片

若想獲取項目完整代碼以及其他文章的項目源碼,且在代碼編寫時遇到問題需要咨詢交流,歡迎加入下方的知識星球。

項目結(jié)構(gòu)

我們將構(gòu)建一個Spring Boot項目,使用MyBatis-Plus進(jìn)行數(shù)據(jù)庫操作,并結(jié)合Thymeleaf模板引擎在前端展示樹結(jié)構(gòu)。以下是項目的基本結(jié)構(gòu):

springboot-tree-async
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com.icoderoad.treeasync
│   │   │       ├── controller
│   │   │       ├── entity
│   │   │       ├── mapper
│   │   │       ├── service
│   │   │       └── serviceImpl
│   │   ├── resources
│   │   │   ├── templates
│   │   │   ├── application.yml
│   └── test
│       └── java
│           └── com.icoderoad.treeasync
└── pom.xml

項目配置(pom.xml)

首先,我們需要配置pom.xml,包括Spring Boot和MyBatis-Plus的依賴:

<?xml versinotallow="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>treeasync</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>treeasync</name>
	<description>Demo project for Spring Boot</description>
	
	<properties>
		<java.version>17</java.version>
		 <mybatis-plus-boot-starter.version>3.5.7</mybatis-plus-boot-starter.version>
        <mybatis-spring.version>3.0.3</mybatis-spring.version>
	</properties>
	<dependencies>
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
	        <groupId>com.baomidou</groupId>
	        <artifactId>mybatis-plus-boot-starter</artifactId>
	        <version>${mybatis-plus-boot-starter.version}</version>
	    </dependency>
	   
	     <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>${mybatis-spring.version}</version>
      	</dependency>
        <!-- 數(shù)據(jù)庫驅(qū)動依賴 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

配置文件(application.yml)

接下來,我們配置application.yml,指定數(shù)據(jù)源及MyBatis-Plus的配置。

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/tree_db?useUnicode=true&characterEncoding=UTF-8&serverTimeznotallow=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:/mapper/*.xml
  global-config:
    db-config:
      id-type: auto

實(shí)體類與Mapper接口

我們使用一個簡單的Category實(shí)體來表示樹結(jié)構(gòu)中的節(jié)點(diǎn):

package com.icoderoad.treeasync.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("category")
public class Category {
    @TableId(type = IdType.AUTO)
    private Long id;
    private Long parentId;
    private String name;
}

CategoryMapper接口定義了數(shù)據(jù)庫操作:

package com.icoderoad.treeasync.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.icoderoad.treeasync.entity.Category;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface CategoryMapper extends BaseMapper<Category> {
}

Service層

在Service層,我們實(shí)現(xiàn)了獲取樹結(jié)構(gòu)節(jié)點(diǎn)的邏輯:

package com.icoderoad.treeasync.service;

import com.icoderoad.treeasync.entity.Category;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

public interface CategoryService extends IService<Category> {
    List<Category> getChildren(Long parentId);
}


package com.icoderoad.treeasync.service.impl;

import com.icoderoad.treeasync.entity.Category;
import com.icoderoad.treeasync.mapper.CategoryMapper;
import com.icoderoad.treeasync.service.CategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public List<Category> getChildren(Long parentId) {
        return lambdaQuery().eq(Category::getParentId, parentId).list();
    }
}

控制器

控制器用來處理前端的異步請求:

package com.icoderoad.treeasync.controller;

import com.icoderoad.treeasync.entity.Category;
import com.icoderoad.treeasync.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/category")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    @GetMapping("/children/{parentId}")
    public List<Category> getChildren(@PathVariable Long parentId) {
        return categoryService.getChildren(parentId);
    }
}

前端頁面與異步加載實(shí)現(xiàn)

前端使用Thymeleaf模板結(jié)合Bootstrap和JavaScript實(shí)現(xiàn)樹結(jié)構(gòu)的展示與異步加載:

在 src/main/resources/templates 目錄下創(chuàng)建 index.html 模板文件。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>分類樹結(jié)構(gòu)</title>
    <link rel="stylesheet" >
    <link rel="stylesheet" >
    <style>
        .tree-item {
            cursor: pointer;
            padding-left: 1rem;
        }

        .tree-icon {
            margin-right: 0.5rem;
        }
    </style>
</head>
<body>
<div class="container">
    <h2 class="my-4">分類樹結(jié)構(gòu)</h2>
    <ul id="categoryTree" class="list-group">
        <!-- 根節(jié)點(diǎn)會從服務(wù)器加載并插入到這里 -->
    </ul>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>
    $(document).ready(function () {
        // 加載根節(jié)點(diǎn)
        loadTreeNodes(0, $('#categoryTree'));

        // 動態(tài)加載節(jié)點(diǎn)
        function loadTreeNodes(parentId, ulElement) {
            $.ajax({
                url: '/category/children/' + parentId,
                method: 'GET',
                success: function (data) {
                    $.each(data, function (index, category) {
                        const li = $('<li>').addClass('list-group-item tree-item');
                        const icon = $('<i>').addClass('bi bi-chevron-right tree-icon');
                        const span = $('<span>').text(category.name);

                        li.append(icon).append(span).data('id', category.id);
                        ulElement.append(li);

                        // 點(diǎn)擊展開或折疊
                        li.on('click', function (e) {
                            e.stopPropagation();
                            const iconElement = $(this).find('.tree-icon');
                            const childrenUl = $(this).find('ul');

                            if (childrenUl.length === 0) {
                                // 加載子節(jié)點(diǎn)
                                const newUl = $('<ul>').addClass('list-group ml-3');
                                loadTreeNodes($(this).data('id'), newUl);
                                $(this).append(newUl);
                                iconElement.removeClass('bi-chevron-right').addClass('bi-chevron-down');
                            } else {
                                // 切換展開/折疊
                                childrenUl.toggle();
                                iconElement.toggleClass('bi-chevron-right bi-chevron-down');
                            }
                        });
                    });
                }
            });
        }
    });
</script>
</body>
</html>

數(shù)據(jù)庫結(jié)構(gòu)

數(shù)據(jù)庫表category的SQL DDL語句如下:

CREATE TABLE `category` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `parent_id` bigint DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

初始化分類表數(shù)據(jù):

-- 插入第一層數(shù)據(jù)(根節(jié)點(diǎn))
INSERT INTO category (parent_id, name) VALUES (0, '電子產(chǎn)品');
INSERT INTO category (parent_id, name) VALUES (0, '家用電器');
INSERT INTO category (parent_id, name) VALUES (0, '時尚服飾');

-- 插入第二層數(shù)據(jù)
INSERT INTO category (parent_id, name) VALUES (1, '手機(jī)');
INSERT INTO category (parent_id, name) VALUES (1, '筆記本電腦');
INSERT INTO category (parent_id, name) VALUES (2, '冰箱');
INSERT INTO category (parent_id, name) VALUES (2, '洗衣機(jī)');
INSERT INTO category (parent_id, name) VALUES (3, '男裝');
INSERT INTO category (parent_id, name) VALUES (3, '女裝');

-- 插入第三層數(shù)據(jù)
INSERT INTO category (parent_id, name) VALUES (4, '智能手機(jī)');
INSERT INTO category (parent_id, name) VALUES (4, '功能手機(jī)');
INSERT INTO category (parent_id, name) VALUES (5, '游戲筆記本');
INSERT INTO category (parent_id, name) VALUES (5, '超極本');
INSERT INTO category (parent_id, name) VALUES (6, '雙門冰箱');
INSERT INTO category (parent_id, name) VALUES (6, '單門冰箱');
INSERT INTO category (parent_id, name) VALUES (7, '滾筒洗衣機(jī)');
INSERT INTO category (parent_id, name) VALUES (7, '波輪洗衣機(jī)');
INSERT INTO category (parent_id, name) VALUES (8, '休閑裝');
INSERT INTO category (parent_id, name) VALUES (8, '正裝');
INSERT INTO category (parent_id, name) VALUES (9, '連衣裙');
INSERT INTO category (parent_id, name) VALUES (9, '上衣');

-- 插入第四層數(shù)據(jù)
INSERT INTO category (parent_id, name) VALUES (10, '安卓手機(jī)');
INSERT INTO category (parent_id, name) VALUES (10, '蘋果手機(jī)');
INSERT INTO category (parent_id, name) VALUES (13, '變形筆記本');
INSERT INTO category (parent_id, name) VALUES (13, '傳統(tǒng)筆記本');
INSERT INTO category (parent_id, name) VALUES (17, '辦公室連衣裙');
INSERT INTO category (parent_id, name) VALUES (17, '休閑連衣裙');

總結(jié)

本文介紹了如何使用Spring Boot結(jié)合MyBatis-Plus實(shí)現(xiàn)多層次樹結(jié)構(gòu)的異步加載策略。我們通過一個簡單的分類樹示例展示了如何在前端逐步加載節(jié)點(diǎn),避免一次性加載大量數(shù)據(jù)帶來的性能問題。希望通過這篇文章,您能夠?qū)pring Boot和MyBatis-Plus的聯(lián)合使用有更深入的理解,并能夠?qū)⑵鋺?yīng)用到實(shí)際項目中。

責(zé)任編輯:武曉燕 來源: 路條編程
相關(guān)推薦

2024-07-31 09:56:20

2024-10-14 13:26:42

2024-08-26 09:15:55

RedissonMyBatisSpring

2023-12-13 12:20:36

SpringMySQL數(shù)據(jù)源

2024-08-29 08:23:22

EasyOCRSpring文字識別

2024-12-20 16:49:15

MyBatis開發(fā)代碼

2024-09-14 11:31:27

@AsyncSpring異步

2012-09-24 15:34:33

2025-02-20 08:21:36

2011-03-25 09:15:32

2021-01-05 05:36:39

設(shè)計Spring Boot填充

2025-02-06 07:45:44

2025-04-17 03:33:00

SpringSQL動態(tài)查詢

2025-02-27 09:45:47

2014-09-18 09:00:27

2009-06-20 10:20:26

2024-02-28 09:35:52

2024-09-05 09:35:58

CGLIBSpring動態(tài)代理

2023-01-12 09:13:49

Mybatis數(shù)據(jù)庫

2024-09-09 16:18:12

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號