最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis實(shí)現(xiàn)三級(jí)樹(shù)查詢的示例代碼

 更新時(shí)間:2024年12月03日 09:13:23   作者:trymoLiu  
在實(shí)際項(xiàng)目開(kāi)發(fā)中,樹(shù)形結(jié)構(gòu)的數(shù)據(jù)查詢是一個(gè)非常常見(jiàn)的需求,比如組織架構(gòu)、菜單管理、地區(qū)選擇等場(chǎng)景都需要處理樹(shù)形數(shù)據(jù),本文將詳細(xì)講解如何使用MyBatis實(shí)現(xiàn)三級(jí)樹(shù)形數(shù)據(jù)的查詢,需要的朋友可以參考下

引言

在實(shí)際項(xiàng)目開(kāi)發(fā)中,樹(shù)形結(jié)構(gòu)的數(shù)據(jù)查詢是一個(gè)非常常見(jiàn)的需求。比如組織架構(gòu)、菜單管理、地區(qū)選擇等場(chǎng)景都需要處理樹(shù)形數(shù)據(jù)。本文將詳細(xì)講解如何使用MyBatis實(shí)現(xiàn)三級(jí)樹(shù)形數(shù)據(jù)的查詢,從數(shù)據(jù)庫(kù)設(shè)計(jì)到具體代碼實(shí)現(xiàn),幫助大家掌握樹(shù)形數(shù)據(jù)處理的核心要點(diǎn)。

數(shù)據(jù)庫(kù)設(shè)計(jì)

首先,我們需要設(shè)計(jì)一個(gè)合適的數(shù)據(jù)庫(kù)表結(jié)構(gòu)來(lái)存儲(chǔ)樹(shù)形數(shù)據(jù)。以下是一個(gè)典型的樹(shù)形表結(jié)構(gòu):

CREATE TABLE `sys_area` 
(  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`parent_id` bigint(20) DEFAULT NULL COMMENT '父級(jí)ID', 
`name` varchar(50) NOT NULL COMMENT '地區(qū)名稱',
`level` int(11) NOT NULL COMMENT '層級(jí)(1:省份 2:城市 3:區(qū)縣)',
`sort` int(11) DEFAULT 0 COMMENT '排序號(hào)',  
`status` tinyint(4) DEFAULT 1 COMMENT '狀態(tài)(0:禁用 1:啟用)',  
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', 
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間', 
PRIMARY KEY (`id`),  
KEY `idx_parent_id` (`parent_id`)) 
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='地區(qū)表';

實(shí)體類設(shè)計(jì)

接下來(lái),我們需要?jiǎng)?chuàng)建對(duì)應(yīng)的實(shí)體類。為了支持樹(shù)形結(jié)構(gòu),我們需要添加一個(gè)children屬性來(lái)存儲(chǔ)子節(jié)點(diǎn):

@Data
public class Area implements Serializable {
      private static final long serialVersionUID = 1L;
          // 主鍵ID    
          private Long id;
          // 父級(jí)ID
          private Long parentId;
          // 地區(qū)名稱
          private String name;
          // 層級(jí)   
          private Integer level; 
          // 排序號(hào)   
          private Integer sort;   
          // 狀態(tài)   
          private Integer status;
          // 創(chuàng)建時(shí)間   
          private Date createTime;
          // 更新時(shí)間    
          private Date updateTime;  
          // 子節(jié)點(diǎn)列表   
          private List<Area> children;
      }

Mapper接口設(shè)計(jì)

創(chuàng)建AreaMapper接口,定義必要的查詢方法:

@Mapper
public interface AreaMapper {
    /**     
    * 查詢所有地區(qū)數(shù)據(jù)    
    * @return 地區(qū)列表     */  
    List<Area> selectAllAreas(); 
    /**     
    * 根據(jù)父ID查詢子地區(qū)     
    * @param parentId 父級(jí)ID     
    * @return 子地區(qū)列表     */   
    List<Area> selectAreasByParentId(Long parentId);        
    /**    
    * 查詢指定層級(jí)的地區(qū)     
    * @param level 層級(jí)    
    * @return 地區(qū)列表     */  
    List<Area> selectAreasByLevel(Integer level);
}

XML映射文件實(shí)現(xiàn)

在resources目錄下創(chuàng)建AreaMapper.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.AreaMapper">
    <!-- 基礎(chǔ)列 -->  
    <sql id="Base_Column_List"> 
        id, parent_id, name, level, sort, status, create_time, update_time   
    </sql>       
    <!-- 查詢所有地區(qū) --> 
    <select id="selectAllAreas" resultType="com.example.entity.Area"> 
        SELECT   <include refid="Base_Column_List"/>    FROM sys_area 
        WHERE status = 1      
        ORDER BY sort ASC, id ASC   
    </select>       
    <!-- 根據(jù)父ID查詢子地區(qū) -->  
    <select id="selectAreasByParentId" resultType="com.example.entity.Area"> 
        SELECT     <include refid="Base_Column_List"/>     FROM sys_area        
        WHERE status = 1        
        AND parent_id = #{parentId}       
        ORDER BY sort ASC, id ASC   
    </select>      
    <!-- 查詢指定層級(jí)的地區(qū) -->   
    <select id="selectAreasByLevel" resultType="com.example.entity.Area">  
        SELECT     <include refid="Base_Column_List"/>    FROM sys_area        
        WHERE status = 1     
        AND level = #{level}    
        ORDER BY sort ASC, id ASC  
    </select>
</mapper>

Service層實(shí)現(xiàn)

創(chuàng)建Service接口及其實(shí)現(xiàn)類:

@Service
@Slf4j
public class AreaServiceImpl implements AreaService {
    @Autowired
    private AreaMapper areaMapper; 
    @Override
    public List<Area> buildAreaTree() { 
        // 查詢所有地區(qū)數(shù)據(jù) 
        List<Area> allAreas = areaMapper.selectAllAreas(); 
        // 構(gòu)建樹(shù)形結(jié)構(gòu)
        return buildTree(allAreas);
    } 
    /**
    * 構(gòu)建樹(shù)形結(jié)構(gòu) 
    * @param areas 地區(qū)列表 
    * @return 樹(shù)形結(jié)構(gòu)的地區(qū)列表 
    */ 
    private List<Area> buildTree(List<Area> areas) { 
        List<Area> trees = new ArrayList<>(); 
        // 獲取所有根節(jié)點(diǎn)(省份)
        areas.stream().filter(area -> area.getLevel() == 1) .forEach(province -> { 
            // 設(shè)置省份的子節(jié)點(diǎn)(城市) 
            List<Area> cities = getChildren(areas, province.getId()); 
            province.setChildren(cities); 
            // 設(shè)置城市的子節(jié)點(diǎn)(區(qū)縣)
            cities.forEach(city -> { List<Area> districts = getChildren(areas, city.getId());   
                city.setChildren(districts);  
            });
            trees.add(province);
        });
        return trees; 
    } 
    /**
    * 獲取子節(jié)點(diǎn) 
    * @param areas 所有地區(qū)列表 
    * @param parentId 父級(jí)ID 
    * @return 子節(jié)點(diǎn)列表
    */ 
    private List<Area> getChildren(List<Area> areas, Long parentId) { 
        return areas.stream().filter(area -> Objects.equals(area.getParentId(), parentId)) 
        .collect(Collectors.toList()); 
    }
}

Controller層實(shí)現(xiàn)

最后,創(chuàng)建Controller處理前端請(qǐng)求:

@RestController@RequestMapping("/api/areas")
public class AreaController {   
    @Autowired   
    private AreaService areaService;    
    /**    
    * 獲取地區(qū)樹(shù)形數(shù)據(jù)     */ 
    @GetMapping("/tree")   
    public ResponseResult<List<Area>> getAreaTree() { 
        try {       
            List<Area> trees = areaService.buildAreaTree();   
            return ResponseResult.success(trees);    
        } catch (Exception e) {   
            log.error("獲取地區(qū)樹(shù)形數(shù)據(jù)失敗", e);    
            return ResponseResult.error("獲取地區(qū)樹(shù)形數(shù)據(jù)失敗");     
        }  
   }
}

性能優(yōu)化建議

  • 緩存優(yōu)化
  • 考慮使用Redis緩存樹(shù)形數(shù)據(jù),因?yàn)榈貐^(qū)數(shù)據(jù)變動(dòng)頻率較低
  • 可以設(shè)置合理的緩存過(guò)期時(shí)間,如24小時(shí)
@Service
public class AreaServiceImpl implements AreaService {
    @Autowired   
    private RedisTemplate<String, List<Area>> redisTemplate; 
    private static final String AREA_TREE_KEY = "AREA:TREE";  
    private static final long CACHE_TIMEOUT = 24; 
    // 小時(shí)   
    @Override   
    public List<Area> buildAreaTree() {
        // 先從緩存獲取  
        List<Area> cacheTree = redisTemplate.opsForValue().get(AREA_TREE_KEY);   
        if (cacheTree != null) {   
            return cacheTree;  
        }               
        // 緩存未命中,查詢數(shù)據(jù)庫(kù)并構(gòu)建樹(shù)    
        List<Area> trees = buildTreeFromDb();       
        // 放入緩存    
        redisTemplate.opsForValue().set(AREA_TREE_KEY, trees, CACHE_TIMEOUT, TimeUnit.HOURS);                return trees;
    }
}

2. SQL優(yōu)化

  • 適當(dāng)添加索引:parent_id, level, status等字段
  • 考慮使用批量查詢替代循環(huán)查詢

3. 內(nèi)存優(yōu)化

  • 使用Stream API時(shí)注意及時(shí)關(guān)閉
  • 合理設(shè)置集合的初始容量
  • 及時(shí)釋放不再使用的對(duì)象引用

總結(jié)

通過(guò)本文的講解,我們實(shí)現(xiàn)了一個(gè)完整的三級(jí)樹(shù)形數(shù)據(jù)查詢功能。關(guān)鍵要點(diǎn)包括:

  • 合理的數(shù)據(jù)庫(kù)表設(shè)計(jì),包含必要的字段和索引
  • 清晰的實(shí)體類設(shè)計(jì),支持樹(shù)形結(jié)構(gòu)
  • MyBatis映射文件的編寫,實(shí)現(xiàn)基礎(chǔ)的數(shù)據(jù)查詢
  • Service層的樹(shù)形構(gòu)建算法實(shí)現(xiàn)
  • 性能優(yōu)化和緩存的使用

到此這篇關(guān)于MyBatis實(shí)現(xiàn)三級(jí)樹(shù)查詢的示例代碼的文章就介紹到這了,更多相關(guān)MyBatis三級(jí)樹(shù)查詢內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法

    spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法

    本篇文章主要介紹了spring boot整合redis實(shí)現(xiàn)shiro的分布式session共享的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 關(guān)于JDK15的新特性之TextBlocks文本塊的引入和使用

    關(guān)于JDK15的新特性之TextBlocks文本塊的引入和使用

    這篇文章主要介紹了關(guān)于JDK15的新特性之文本塊的引入和使用,如果具有一種語(yǔ)言學(xué)機(jī)制,可以比多行文字更直觀地表示字符串,而且可以跨越多行,而且不會(huì)出現(xiàn)轉(zhuǎn)義的視覺(jué)混亂,那么這將提高廣泛Java類程序的可讀性和可寫性,需要的朋友可以參考下
    2023-07-07
  • 淺談spring-kafka消費(fèi)異常處理

    淺談spring-kafka消費(fèi)異常處理

    本文主要介紹了spring-kafka消費(fèi)異常處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • 淺析Java如何高效將PDF轉(zhuǎn)換為高質(zhì)量TIFF圖片

    淺析Java如何高效將PDF轉(zhuǎn)換為高質(zhì)量TIFF圖片

    在文檔處理和歸檔系統(tǒng)中,將PDF文件轉(zhuǎn)換為TIFF格式是一項(xiàng)非常常見(jiàn)的需求,本文將介紹如何使用Java通過(guò)Spire.PDF?for?Java庫(kù),快速實(shí)現(xiàn)PDF到TIFF的轉(zhuǎn)換,希望對(duì)大家有所幫助
    2026-04-04
  • 實(shí)例講解spring boot 多線程

    實(shí)例講解spring boot 多線程

    這篇文章主要介紹了spring boot 多線程的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Mybatis-Plus select不去查全部字段和去重問(wèn)題

    Mybatis-Plus select不去查全部字段和去重問(wèn)題

    本文介紹了MyBatis-Plus中查詢指定字段的方法和查詢分組查詢的方法,還介紹了使用`queryWrapper`的的`select()`方法來(lái)指定查詢的字段,并并并并提供了查詢?nèi)ブ?IN操作和特殊字符轉(zhuǎn)義的示例代碼
    2026-04-04
  • SpringBoot多種環(huán)境自由切換的實(shí)現(xiàn)

    SpringBoot多種環(huán)境自由切換的實(shí)現(xiàn)

    本文主要介紹了SpringBoot多種環(huán)境自由切換的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • SpringBoot項(xiàng)目中Date類型數(shù)據(jù)在接口返回的時(shí)間不正確的問(wèn)題解決

    SpringBoot項(xiàng)目中Date類型數(shù)據(jù)在接口返回的時(shí)間不正確的問(wèn)題解決

    如果接口返回的Date類型時(shí)間與數(shù)據(jù)庫(kù)中datetime不一致,可能是由于沒(méi)有正確配置時(shí)區(qū)導(dǎo)致的,解決方法是在yaml配置文件中指定正確的日期格式和時(shí)區(qū)配置,修改配置并重啟項(xiàng)目后,可以獲得正確的時(shí)間,下面就來(lái)介紹一下
    2024-09-09
  • 在Spring Boot項(xiàng)目中引入本地JAR包的步驟和配置

    在Spring Boot項(xiàng)目中引入本地JAR包的步驟和配置

    本文探討了在Spring Boot項(xiàng)目中引入本地JAR包的步驟和必要的配置,通過(guò)使用Maven的system作用域,開(kāi)發(fā)者可以將自定義的本地庫(kù)或功能集成到Spring Boot應(yīng)用程序中,,需要的朋友可以參考下
    2023-10-10
  • Java反射機(jī)制詳解

    Java反射機(jī)制詳解

    Java的反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任何一個(gè)類,都可以知道這個(gè)類的所有屬性和方法,對(duì)于任何一個(gè)對(duì)象,都可以調(diào)用它所有的方法和屬性,修改部分類型信息,這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為Java的反射機(jī)制
    2022-09-09

最新評(píng)論

于都县| 延长县| 工布江达县| 乐业县| 丹棱县| 卢龙县| 昭平县| 奉节县| 伽师县| 阿鲁科尔沁旗| 陆河县| 略阳县| 射阳县| 汤原县| 日照市| 平邑县| 浮梁县| 耒阳市| 寿光市| 辽宁省| 虎林市| 清原| 彰武县| 科尔| 马龙县| 桐梓县| 松江区| 图片| 漯河市| 乌鲁木齐市| 宁国市| 伽师县| 福鼎市| 平利县| 太原市| 耒阳市| 武山县| 双鸭山市| 革吉县| 广德县| 鹰潭市|