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

MyBatis-Plus從基礎(chǔ)CRUD到高級(jí)查詢(xún)與性能優(yōu)化實(shí)戰(zhàn)指南

 更新時(shí)間:2026年02月04日 11:22:28   作者:lbb 小魔仙  
MyBatis-Plus 與 Spring Boot 的集成非常簡(jiǎn)潔,只需完成 Maven 依賴(lài)引入和基礎(chǔ)配置,即可快速啟用所有核心功能,本文將從環(huán)境搭建到性能優(yōu)化,系統(tǒng)化講解MyBatis-Plus的實(shí)戰(zhàn)用法,助力開(kāi)發(fā)者快速上手并靈活運(yùn)用,感興趣的朋友跟隨小編一起看看吧

MyBatis-Plus 系統(tǒng)化實(shí)戰(zhàn):從基礎(chǔ) CRUD 到高級(jí)查詢(xún)與性能優(yōu)化

一、引言

在 Java 持久層開(kāi)發(fā)領(lǐng)域,MyBatis 憑借其輕量、靈活、SQL 可控性強(qiáng)的特點(diǎn),成為企業(yè)級(jí)項(xiàng)目的主流選擇。但原生 MyBatis 存在大量重復(fù)編碼工作——例如基礎(chǔ) CRUD 接口的編寫(xiě)、復(fù)雜查詢(xún)條件的拼接、分頁(yè)邏輯的重復(fù)實(shí)現(xiàn)等,這些冗余操作不僅降低開(kāi)發(fā)效率,還可能因人為疏忽引入潛在 Bug。

MyBatis-Plus(簡(jiǎn)稱(chēng) MP)作為 MyBatis 的增強(qiáng)工具,遵循“只做增強(qiáng),不做改變”的核心理念,在完全兼容 MyBatis 原有功能的基礎(chǔ)上,內(nèi)置了大量實(shí)用特性,徹底解決了原生 MyBatis 的痛點(diǎn)。其核心優(yōu)勢(shì)包括:無(wú)侵入式增強(qiáng)、內(nèi)置基礎(chǔ) CRUD 接口無(wú)需手動(dòng)編寫(xiě) SQL、強(qiáng)大的條件構(gòu)造器簡(jiǎn)化查詢(xún)邏輯、完善的分頁(yè)插件與批量操作支持、靈活的關(guān)聯(lián)查詢(xún)方案等。

在企業(yè)開(kāi)發(fā)中,MyBatis-Plus 能夠顯著提升持久層開(kāi)發(fā)效率(減少 60% 以上的重復(fù)編碼),同時(shí)保證 SQL 的靈活性與性能可控性,廣泛應(yīng)用于中大型 Spring Boot 項(xiàng)目中,是 Java 開(kāi)發(fā)者必備的實(shí)戰(zhàn)技能之一。本文將從環(huán)境搭建到性能優(yōu)化,系統(tǒng)化講解 MyBatis-Plus 的實(shí)戰(zhàn)用法,助力開(kāi)發(fā)者快速上手并靈活運(yùn)用。

二、環(huán)境搭建:Spring Boot + MyBatis-Plus 快速集成

MyBatis-Plus 與 Spring Boot 的集成非常簡(jiǎn)潔,只需完成 Maven 依賴(lài)引入和基礎(chǔ)配置,即可快速啟用所有核心功能。以下是完整的搭建步驟(基于 Spring Boot 2.7.x,JDK 8+)。

2.1 引入 Maven 依賴(lài)

在 pom.xml 中引入 MyBatis-Plus 核心依賴(lài)、數(shù)據(jù)庫(kù)驅(qū)動(dòng)(以 MySQL 8.0 為例)、 lombok(簡(jiǎn)化實(shí)體類(lèi)編寫(xiě)),無(wú)需額外引入 MyBatis 依賴(lài)(MP 已內(nèi)置)。

<!-- Spring Boot 父依賴(lài) -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.15</version>
    <relativePath/>
</parent>
<dependencies>
    <!-- Spring Boot Web 依賴(lài)(非必需,用于演示接口調(diào)用) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- MyBatis-Plus 核心依賴(lài) -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <!-- MySQL 驅(qū)動(dòng) -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- lombok 簡(jiǎn)化實(shí)體類(lèi) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <!-- 測(cè)試依賴(lài) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

2.2 核心配置(application.yml)

在 resources 目錄下創(chuàng)建 application.yml 文件,配置數(shù)據(jù)庫(kù)連接信息、MyBatis-Plus 基礎(chǔ)參數(shù)(如 mapper 映射文件路徑、實(shí)體類(lèi)別名包、SQL 日志打印等),配置后即可自動(dòng)加載。

spring:
  # 數(shù)據(jù)庫(kù)配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false
    username: root  # 替換為你的數(shù)據(jù)庫(kù)用戶(hù)名
    password: 123456  # 替換為你的數(shù)據(jù)庫(kù)密碼
# MyBatis-Plus 配置
mybatis-plus:
  # mapper 映射文件路徑(若無(wú)需自定義 SQL,可省略)
  mapper-locations: classpath:mapper/**/*.xml
  # 實(shí)體類(lèi)別名包(簡(jiǎn)化 XML 中實(shí)體類(lèi)引用)
  type-aliases-package: com.example.mpdemo.entity
  # 全局配置
  global-config:
    db-config:
      # 主鍵生成策略(AUTO=自增,NONE=手動(dòng)輸入,ASSIGN_ID=雪花算法等)
      id-type: AUTO
      # 邏輯刪除字段配置(可選,用于軟刪除)
      logic-delete-field: isDeleted
      logic-delete-value: 1  # 已刪除
      logic-not-delete-value: 0  # 未刪除
  # 日志配置(打印執(zhí)行的 SQL,便于調(diào)試)
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2.3 啟動(dòng)類(lèi)配置

在 Spring Boot 啟動(dòng)類(lèi)上添加 @MapperScan 注解,指定 Mapper 接口所在的包路徑,確保 MyBatis-Plus 能夠掃描到 Mapper 接口并生成代理對(duì)象。

package com.example.mpdemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 掃描 Mapper 接口所在包
@MapperScan("com.example.mpdemo.mapper")
@SpringBootApplication
public class MpDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(MpDemoApplication.class, args);
    }
}

三、基礎(chǔ) CRUD 實(shí)戰(zhàn):基于 IService 與 BaseMapper

MyBatis-Plus 提供了兩個(gè)核心接口用于實(shí)現(xiàn)基礎(chǔ) CRUD 操作:BaseMapper(面向 Mapper 層)和 IService(面向 Service 層,封裝了 BaseMapper 的方法,提供更便捷的調(diào)用)。推薦在開(kāi)發(fā)中使用 IService + ServiceImpl 的組合,簡(jiǎn)化 Service 層代碼編寫(xiě)。

以下將以 User 實(shí)體類(lèi)為例,演示完整的基礎(chǔ) CRUD 實(shí)戰(zhàn)(包含實(shí)體類(lèi)、Mapper 接口、Service 接口/實(shí)現(xiàn)類(lèi)、調(diào)用示例),所有代碼可直接復(fù)制運(yùn)行。

3.1 準(zhǔn)備數(shù)據(jù)庫(kù)表

創(chuàng)建 user 表(對(duì)應(yīng) User 實(shí)體類(lèi)),SQL 語(yǔ)句如下(適配 MySQL 8.0,包含邏輯刪除字段):

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
  `username` varchar(50) NOT NULL COMMENT '用戶(hù)名',
  `password` varchar(100) NOT NULL COMMENT '密碼(實(shí)際開(kāi)發(fā)中需加密)',
  `age` int(3) DEFAULT NULL COMMENT '年齡',
  `email` varchar(100) DEFAULT NULL COMMENT '郵箱',
  `is_deleted` tinyint(1) DEFAULT 0 COMMENT '邏輯刪除(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`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用戶(hù)表';

3.2 編寫(xiě)實(shí)體類(lèi) User

使用 lombok 的 @Data 注解簡(jiǎn)化 getter/setter 方法,通過(guò) MyBatis-Plus 的注解指定表名、字段映射、備注等信息。

package com.example.mpdemo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
@TableName("user")  // 指定對(duì)應(yīng)數(shù)據(jù)庫(kù)表名(若實(shí)體類(lèi)名與表名一致,可省略)
public class User {
    // 主鍵,自增(對(duì)應(yīng)全局配置的 id-type: AUTO)
    @TableId(type = IdType.AUTO)
    private Integer id;
    // 用戶(hù)名(非空字段)
    @TableField("username")  // 若實(shí)體類(lèi)字段與表字段一致,可省略
    private String username;
    // 密碼
    private String password;
    // 年齡
    private Integer age;
    // 郵箱
    private String email;
    // 邏輯刪除字段(與全局配置一致,可省略注解)
    @TableLogic
    private Integer isDeleted;
    // 創(chuàng)建時(shí)間(自動(dòng)填充)
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    // 更新時(shí)間(自動(dòng)填充)
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

3.3 自動(dòng)填充配置(可選)

上述實(shí)體類(lèi)中,createTime 和 updateTime 字段使用了 @TableField(fill = …) 注解,用于實(shí)現(xiàn)“插入時(shí)自動(dòng)填充創(chuàng)建時(shí)間、更新時(shí)自動(dòng)填充更新時(shí)間”,無(wú)需手動(dòng)設(shè)置。需創(chuàng)建填充處理器:

package com.example.mpdemo.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 插入時(shí)填充
    @Override
    public void insertFill(MetaObject metaObject) {
        // 填充 createTime 和 updateTime
        strictInsertFill(metaObject, "createTime", Date.class, new Date());
        strictInsertFill(metaObject, "updateTime", Date.class, new Date());
    }
    // 更新時(shí)填充
    @Override
    public void updateFill(MetaObject metaObject) {
        // 只填充 updateTime
        strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

3.4 編寫(xiě) Mapper 接口

UserMapper 繼承 BaseMapper,BaseMapper 已內(nèi)置了 selectById、insert、updateById、deleteById 等基礎(chǔ) CRUD 方法,無(wú)需手動(dòng)編寫(xiě)任何方法。

package com.example.mpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.User;
import org.springframework.stereotype.Repository;
// @Repository 用于標(biāo)識(shí) Mapper 接口,避免 IDE 報(bào)錯(cuò)(可選)
@Repository
public interface UserMapper extends BaseMapper<User> {
    // 無(wú)需編寫(xiě)任何方法,BaseMapper 已提供所有基礎(chǔ) CRUD 操作
}

3.5 編寫(xiě) Service 接口與實(shí)現(xiàn)類(lèi)

IService 是 MyBatis-Plus 提供的 Service 層接口,封裝了 BaseMapper 的方法,還提供了批量操作、條件查詢(xún)等便捷方法。UserService 繼承 IService,UserServiceImpl 繼承 ServiceImpl(實(shí)現(xiàn) IService)并注入 UserMapper。

3.5.1 Service 接口

package com.example.mpdemo.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mpdemo.entity.User;
// 繼承 IService,指定實(shí)體類(lèi)類(lèi)型
public interface UserService extends IService<User> {
    // 可添加自定義 Service 方法(基礎(chǔ) CRUD 無(wú)需添加)
}

3.5.2 Service 實(shí)現(xiàn)類(lèi)

package com.example.mpdemo.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import com.example.mpdemo.service.UserService;
import org.springframework.stereotype.Service;
// 繼承 ServiceImpl,注入 Mapper 接口,實(shí)現(xiàn) Service 接口
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    // 基礎(chǔ) CRUD 方法無(wú)需實(shí)現(xiàn),ServiceImpl 已全部封裝
}

3.6 基礎(chǔ) CRUD 調(diào)用示例(測(cè)試類(lèi))

通過(guò) Spring Boot 測(cè)試類(lèi),演示 IService 中常用的基礎(chǔ) CRUD 方法,運(yùn)行測(cè)試方法即可驗(yàn)證效果。

package com.example.mpdemo;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class UserServiceTest {
    // 注入 UserService
    @Autowired
    private UserService userService;
    // 1. 新增用戶(hù)(insert)
    @Test
    public void testInsert() {
        User user = new User();
        user.setUsername("zhangsan");
        user.setPassword("123456");
        user.setAge(20);
        user.setEmail("zhangsan@example.com");
        // 調(diào)用 IService 的 save 方法(底層調(diào)用 BaseMapper 的 insert)
        boolean success = userService.save(user);
        System.out.println("新增結(jié)果:" + success + ",新增用戶(hù)ID:" + user.getId());
    }
    // 2. 根據(jù)ID查詢(xún)用戶(hù)(selectById)
    @Test
    public void testSelectById() {
        User user = userService.getById(1); // 查詢(xún)ID為1的用戶(hù)
        System.out.println("查詢(xún)到的用戶(hù):" + user);
    }
    // 3. 查詢(xún)所有用戶(hù)(selectList)
    @Test
    public void testSelectAll() {
        List<User> userList = userService.list(); // 查詢(xún)所有未刪除的用戶(hù)(自動(dòng)過(guò)濾邏輯刪除)
        userList.forEach(System.out::println);
    }
    // 4. 根據(jù)ID更新用戶(hù)(updateById)
    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1); // 必須設(shè)置主鍵ID
        user.setAge(22); // 更新年齡為22
        user.setEmail("zhangsan22@example.com"); // 更新郵箱
        boolean success = userService.updateById(user);
        System.out.println("更新結(jié)果:" + success);
    }
    // 5. 根據(jù)ID刪除用戶(hù)(邏輯刪除,deleteById)
    @Test
    public void testDeleteById() {
        boolean success = userService.removeById(1); // 邏輯刪除ID為1的用戶(hù)
        System.out.println("刪除結(jié)果:" + success);
    }
    // 6. 批量新增(saveBatch)
    @Test
    public void testSaveBatch() {
        List<User> userList = List.of(
                new User(null, "lisi", "123456", 25, "lisi@example.com", 0, null, null),
                new User(null, "wangwu", "123456", 28, "wangwu@example.com", 0, null, null)
        );
        // 批量新增,底層會(huì)分批次執(zhí)行SQL(默認(rèn)批次大小1000)
        boolean success = userService.saveBatch(userList);
        System.out.println("批量新增結(jié)果:" + success);
    }
}

四、高級(jí)查詢(xún)技巧:提升查詢(xún)靈活性與效率

基礎(chǔ) CRUD 僅能滿(mǎn)足簡(jiǎn)單的業(yè)務(wù)需求,在實(shí)際開(kāi)發(fā)中,往往需要復(fù)雜的查詢(xún)條件(如多字段模糊查詢(xún)、范圍查詢(xún))、分頁(yè)查詢(xún)、關(guān)聯(lián)查詢(xún)等。MyBatis-Plus 提供了完善的高級(jí)查詢(xún)特性,以下講解最常用、最實(shí)用的技巧。

4.1 條件構(gòu)造器:QueryWrapper / LambdaQueryWrapper

條件構(gòu)造器是 MyBatis-Plus 高級(jí)查詢(xún)的核心,用于動(dòng)態(tài)拼接 SQL 查詢(xún)條件(無(wú)需手動(dòng)拼接 SQL 字符串,避免 SQL 注入風(fēng)險(xiǎn))。常用的構(gòu)造器有兩個(gè):

  • QueryWrapper:通過(guò)字符串指定字段名,靈活性高,但字段名容易寫(xiě)錯(cuò)(無(wú)編譯期檢查);
  • LambdaQueryWrapper:通過(guò) Lambda 表達(dá)式獲取字段名,有編譯期檢查,避免字段名寫(xiě)錯(cuò),推薦使用。

以下通過(guò)示例演示兩種構(gòu)造器的常用用法(基于 UserService):

package com.example.mpdemo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class QueryWrapperTest {
    @Autowired
    private UserService userService;
    // 1. QueryWrapper 示例:多條件查詢(xún)(年齡大于20,郵箱包含example,用戶(hù)名不為null)
    @Test
    public void testQueryWrapper() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        // 年齡 > 20
        queryWrapper.gt("age", 20);
        // 郵箱 like %example%
        queryWrapper.like("email", "example");
        // 用戶(hù)名 is not null
        queryWrapper.isNotNull("username");
        // 排序:按年齡降序,按ID升序
        queryWrapper.orderByDesc("age").orderByAsc("id");
        List<User> userList = userService.list(queryWrapper);
        userList.forEach(System.out::println);
    }
    // 2. LambdaQueryWrapper 示例(推薦):同樣的條件,避免字段名寫(xiě)錯(cuò)
    @Test
    public void testLambdaQueryWrapper() {
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 年齡 > 20(Lambda表達(dá)式獲取字段,編譯期檢查)
        lambdaQueryWrapper.gt(User::getAge, 20);
        // 郵箱 like %example%
        lambdaQueryWrapper.like(User::getEmail, "example");
        // 用戶(hù)名 is not null
        lambdaQueryWrapper.isNotNull(User::getUsername);
        // 排序:按年齡降序,按ID升序
        lambdaQueryWrapper.orderByDesc(User::getAge).orderByAsc(User::getId);
        List<User> userList = userService.list(lambdaQueryWrapper);
        userList.forEach(System.out::println);
    }
    // 3. 條件構(gòu)造器常用方法補(bǔ)充
    @Test
    public void testLambdaQueryWrapperAdvanced() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        // 1. 范圍查詢(xún):年齡在20-30之間(包含20和30)
        wrapper.between(User::getAge, 20, 30);
        // 2. 等值查詢(xún):用戶(hù)名 = zhangsan
        wrapper.eq(User::getUsername, "zhangsan");
        // 3. 非等值查詢(xún):密碼 != 123456
        wrapper.ne(User::getPassword, "123456");
        // 4. 模糊查詢(xún):用戶(hù)名以zhang開(kāi)頭(like 'zhang%')
        wrapper.likeLeft(User::getUsername, "zhang");
        // 5. 模糊查詢(xún):用戶(hù)名以san結(jié)尾(like '%san')
        wrapper.likeRight(User::getUsername, "san");
        // 6. 空值查詢(xún):郵箱 is null
        wrapper.isNull(User::getEmail);
        // 7. 非空查詢(xún):郵箱 is not null
        wrapper.isNotNull(User::getEmail);
        // 8. 邏輯或:年齡 < 20 或 年齡 > 30
        wrapper.or().lt(User::getAge, 20).or().gt(User::getAge, 30);
        // 9. 邏輯與(默認(rèn),可省略):年齡 > 20 且 郵箱不為空
        wrapper.and(i -> i.gt(User::getAge, 20).isNotNull(User::getEmail));
        // 10. 只查詢(xún)指定字段(避免查詢(xún)無(wú)用字段,提升性能)
        wrapper.select(User::getId, User::getUsername, User::getAge);
        List<User> userList = userService.list(wrapper);
        userList.forEach(System.out::println);
    }
}

4.2 分頁(yè)插件配置與調(diào)用示例

MyBatis-Plus 內(nèi)置了分頁(yè)插件(PaginationInnerInterceptor),支持 MySQL、Oracle、SQL Server 等多種數(shù)據(jù)庫(kù),配置簡(jiǎn)單,調(diào)用便捷,無(wú)需手動(dòng)編寫(xiě)分頁(yè) SQL(如 limit 語(yǔ)句)。

4.2.1 分頁(yè)插件配置

創(chuàng)建 MyBatis-Plus 配置類(lèi),注入分頁(yè)插件,指定數(shù)據(jù)庫(kù)類(lèi)型(避免分頁(yè)語(yǔ)法兼容問(wèn)題)。

package com.example.mpdemo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
    // 配置分頁(yè)插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加分頁(yè)插件,指定數(shù)據(jù)庫(kù)類(lèi)型為 MySQL
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

4.2.2 分頁(yè)查詢(xún)調(diào)用示例

使用 Page 類(lèi)封裝分頁(yè)參數(shù)(當(dāng)前頁(yè)碼、每頁(yè)條數(shù)),結(jié)合條件構(gòu)造器,調(diào)用 IService 的 page 方法即可實(shí)現(xiàn)分頁(yè)查詢(xún),返回結(jié)果包含分頁(yè)信息(總條數(shù)、總頁(yè)數(shù)、當(dāng)前頁(yè)數(shù)據(jù)等)。

package com.example.mpdemo;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class PageTest {
    @Autowired
    private UserService userService;
    // 1. 基礎(chǔ)分頁(yè)查詢(xún)(無(wú)條件)
    @Test
    public void testPageBasic() {
        // 分頁(yè)參數(shù):當(dāng)前頁(yè)(從1開(kāi)始)、每頁(yè)條數(shù)
        Page<User> page = new Page<>(1, 2);
        // 調(diào)用 page 方法,返回分頁(yè)結(jié)果
        IPage<User> userIPage = userService.page(page);
        // 分頁(yè)信息解析
        System.out.println("總條數(shù):" + userIPage.getTotal());
        System.out.println("總頁(yè)數(shù):" + userIPage.getPages());
        System.out.println("當(dāng)前頁(yè)碼:" + userIPage.getCurrent());
        System.out.println("每頁(yè)條數(shù):" + userIPage.getSize());
        System.out.println("當(dāng)前頁(yè)數(shù)據(jù):");
        userIPage.getRecords().forEach(System.out::println);
    }
    // 2. 帶條件的分頁(yè)查詢(xún)(結(jié)合 LambdaQueryWrapper)
    @Test
    public void testPageWithCondition() {
        // 分頁(yè)參數(shù):第2頁(yè),每頁(yè)3條
        Page<User> page = new Page<>(2, 3);
        // 條件:年齡 > 20,按年齡降序
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
                .gt(User::getAge, 20)
                .orderByDesc(User::getAge);
        // 帶條件分頁(yè)查詢(xún)
        IPage<User> userIPage = userService.page(page, wrapper);
        // 輸出分頁(yè)結(jié)果
        System.out.println("總條數(shù):" + userIPage.getTotal());
        System.out.println("總頁(yè)數(shù):" + userIPage.getPages());
        userIPage.getRecords().forEach(System.out::println);
    }
    // 3. 分頁(yè)查詢(xún)指定字段(避免查詢(xún)無(wú)用字段)
    @Test
    public void testPageSelectField() {
        Page<User> page = new Page<>(1, 2);
        LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
                .gt(User::getAge, 20)
                .select(User::getId, User::getUsername, User::getAge); // 只查詢(xún)3個(gè)字段
        IPage<User> userIPage = userService.page(page, wrapper);
        userIPage.getRecords().forEach(System.out::println);
    }
}

4.3 關(guān)聯(lián)查詢(xún):注解與手動(dòng) SQL 最佳實(shí)踐

MyBatis-Plus 本身不直接提供像 MyBatis-Plus Join 那樣的強(qiáng)關(guān)聯(lián)查詢(xún)封裝,但可以通過(guò) MyBatis 的原生注解(@One、@Many)或手動(dòng)編寫(xiě) XML SQL 實(shí)現(xiàn)關(guān)聯(lián)查詢(xún)(一對(duì)一、一對(duì)多),以下是企業(yè)開(kāi)發(fā)中最常用的兩種方式。

示例場(chǎng)景:新增 Order 實(shí)體類(lèi)(訂單表),User 與 Order 是一對(duì)多關(guān)系(一個(gè)用戶(hù)可以有多個(gè)訂單),演示一對(duì)多關(guān)聯(lián)查詢(xún)。

4.3.1 準(zhǔn)備關(guān)聯(lián)表與實(shí)體類(lèi)

(1)訂單表 SQL
CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '訂單ID',
  `order_no` varchar(50) NOT NULL COMMENT '訂單編號(hào)',
  `user_id` int(11) NOT NULL COMMENT '關(guān)聯(lián)用戶(hù)ID(外鍵)',
  `total_amount` decimal(10,2) NOT NULL COMMENT '訂單總金額',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`) COMMENT '用戶(hù)ID索引,提升關(guān)聯(lián)查詢(xún)效率'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='訂單表';
(2)Order 實(shí)體類(lèi)
package com.example.mpdemo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("`order`")  // 訂單表名是關(guān)鍵字order,需用反引號(hào)包裹
public class Order {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String orderNo;
    // 關(guān)聯(lián)用戶(hù)ID(外鍵)
    private Integer userId;
    private BigDecimal totalAmount;
    private Date createTime;
}
(3)修改 User 實(shí)體類(lèi)(添加訂單列表屬性)
package com.example.mpdemo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
import java.util.List;
@Data
@TableName("user")
public class User {
    // 原有字段不變,新增以下屬性
    // 一對(duì)多關(guān)聯(lián):一個(gè)用戶(hù)有多個(gè)訂單(非數(shù)據(jù)庫(kù)字段,需用@TableField(exist = false)標(biāo)識(shí))
    @TableField(exist = false)
    private List<Order> orderList;
}

4.3.2 方式一:通過(guò) @One / @Many 注解實(shí)現(xiàn)關(guān)聯(lián)查詢(xún)

通過(guò) MyBatis 的 @Many 注解(一對(duì)多),在 UserMapper 中編寫(xiě)關(guān)聯(lián)查詢(xún)方法,無(wú)需編寫(xiě) XML 文件,適合簡(jiǎn)單的關(guān)聯(lián)場(chǎng)景。

package com.example.mpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.Order;
import com.example.mpdemo.entity.User;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper extends BaseMapper<User> {
    // 一對(duì)多關(guān)聯(lián)查詢(xún):查詢(xún)用戶(hù)及其所有訂單
    @Select("SELECT * FROM user WHERE id = #{userId}")
    @Results({
            // 映射用戶(hù)自身字段(id、username等)
            @Result(column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "age", property = "age"),
            @Result(column = "email", property = "email"),
            // 關(guān)聯(lián)查詢(xún)訂單:通過(guò)user的id關(guān)聯(lián)order的user_id
            @Result(
                    column = "id",  // 關(guān)聯(lián)字段(user的id)
                    property = "orderList",  // 映射到user的orderList屬性
                    // 一對(duì)多關(guān)聯(lián),使用@Many注解
                    many = @Many(select = "com.example.mpdemo.mapper.OrderMapper.selectByUserId")
            )
    })
    User selectUserWithOrders(Integer userId);
    // 批量查詢(xún)用戶(hù)及其訂單(可選)
    @Select("SELECT * FROM user WHERE id IN (#{ids})")
    @Results({
            @Result(column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(
                    column = "id",
                    property = "orderList",
                    many = @Many(select = "com.example.mpdemo.mapper.OrderMapper.selectByUserId")
            )
    })
    List<User> selectUsersWithOrders(List<Integer> ids);
}
// 新增 OrderMapper 接口
package com.example.mpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.Order;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface OrderMapper extends BaseMapper<Order> {
    // 根據(jù)用戶(hù)ID查詢(xún)訂單(供UserMapper的@Many注解調(diào)用)
    @Select("SELECT * FROM `order` WHERE user_id = #{userId}")
    List<Order> selectByUserId(Integer userId);
}

4.3.3 方式二:手動(dòng)編寫(xiě) XML SQL 實(shí)現(xiàn)關(guān)聯(lián)查詢(xún)(推薦)

對(duì)于復(fù)雜的關(guān)聯(lián)查詢(xún)(如多表關(guān)聯(lián)、多條件過(guò)濾),推薦使用 XML 編寫(xiě) SQL,靈活性更高,便于維護(hù)。以下演示通過(guò) XML 實(shí)現(xiàn)用戶(hù)與訂單的一對(duì)多關(guān)聯(lián)查詢(xún)。

(1)修改 UserMapper 接口,添加關(guān)聯(lián)查詢(xún)方法
package com.example.mpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.User;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper extends BaseMapper<User> {
    // 新增:通過(guò)XML實(shí)現(xiàn)用戶(hù)與訂單的關(guān)聯(lián)查詢(xún)
    List<User> selectUserWithOrdersByXml(Integer userId);
}
(2)編寫(xiě) XML 映射文件

在 resources/mapper 目錄下創(chuàng)建 UserMapper.xml 文件(與 application.yml 中 mapper-locations 配置一致),編寫(xiě)關(guān)聯(lián)查詢(xún) SQL。

<?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.mpdemo.mapper.UserMapper"><!-- 一對(duì)多關(guān)聯(lián)查詢(xún):查詢(xún)用戶(hù)及其所有訂單 -->
    <select id="selectUserWithOrdersByXml" resultMap="UserWithOrdersMap">
        SELECT
            u.id AS user_id,
            u.username,
            u.age,
            u.email,
            o.id AS order_id,
            o.order_no,
            o.total_amount,
            o.create_time AS order_create_time
        FROM
            user u
        LEFT JOIN
            `order` o ON u.id = o.user_id
        WHERE
            u.id = #{userId}
            AND u.is_deleted = 0
    </select><!-- 結(jié)果集映射:關(guān)聯(lián)用戶(hù)和訂單 -->
    <resultMap id="UserWithOrdersMap" type="com.example.mpdemo.entity.User">
        <!-- 用戶(hù)自身字段映射 -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="age" property="age"/>
        <result column="email" property="email"/>
        <!-- 一對(duì)多關(guān)聯(lián):映射訂單列表 -->
        <collection property="orderList" ofType="com.example.mpdemo.entity.Order">
            <id column="order_id" property="id"/>
            <result column="order_no" property="orderNo"/>
            <result column="user_id" property="userId"/>
            <result column="total_amount" property="totalAmount"/>
            <result column="order_create_time" property="createTime"/>
        </collection>
    </resultMap>
</mapper>
(3)關(guān)聯(lián)查詢(xún)調(diào)用示例
package com.example.mpdemo;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class RelationQueryTest {
    @Autowired
    private UserMapper userMapper;
    // 測(cè)試注解方式關(guān)聯(lián)查詢(xún)
    @Test
    public void testSelectUserWithOrders() {
        User user = userMapper.selectUserWithOrders(1);
        System.out.println("用戶(hù)信息:" + user.getUsername() + "," + user.getEmail());
        System.out.println("用戶(hù)訂單:");
        user.getOrderList().forEach(order -> System.out.println(order.getOrderNo() + "," + order.getTotalAmount()));
    }
    // 測(cè)試XML方式關(guān)聯(lián)查詢(xún)
    @Test
    public void testSelectUserWithOrdersByXml() {
        User user = userMapper.selectUserWithOrdersByXml(1);
        System.out.println("用戶(hù)信息:" + user.getUsername() + "," + user.getEmail());
        System.out.println("用戶(hù)訂單:");
        user.getOrderList().forEach(order -> System.out.println(order.getOrderNo() + "," + order.getTotalAmount()));
    }
}

五、性能優(yōu)化策略:提升系統(tǒng)響應(yīng)速度與穩(wěn)定性

MyBatis-Plus 的高效性不僅體現(xiàn)在開(kāi)發(fā)效率上,通過(guò)合理的配置與優(yōu)化,還能顯著提升系統(tǒng)的運(yùn)行性能。以下講解企業(yè)開(kāi)發(fā)中最常用的 3 種性能優(yōu)化策略,涵蓋緩存、批量操作、SQL 日志分析。

5.1 二級(jí)緩存配置:減少數(shù)據(jù)庫(kù)查詢(xún)壓力

MyBatis 提供了兩級(jí)緩存:一級(jí)緩存(SqlSession 級(jí)緩存,默認(rèn)開(kāi)啟)和二級(jí)緩存(Mapper 級(jí)緩存,默認(rèn)關(guān)閉)。MyBatis-Plus 完全兼容 MyBatis 的緩存機(jī)制,開(kāi)啟二級(jí)緩存后,多個(gè) SqlSession 可以共享 Mapper 層的緩存數(shù)據(jù),減少重復(fù)查詢(xún)數(shù)據(jù)庫(kù)的次數(shù),提升查詢(xún)性能。

5.1.1 二級(jí)緩存開(kāi)啟步驟

(1)全局開(kāi)啟二級(jí)緩存(application.yml)
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    cache-enabled: true  # 全局開(kāi)啟二級(jí)緩存(默認(rèn)false)
(2)在 Mapper 接口上添加 @CacheNamespace 注解

二級(jí)緩存是 Mapper 級(jí)別的,需在具體的 Mapper 接口上添加注解,標(biāo)識(shí)該 Mapper 開(kāi)啟二級(jí)緩存。

package com.example.mpdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo.entity.User;
import org.apache.ibatis.annotations.CacheNamespace;
import org.springframework.stereotype.Repository;
// 開(kāi)啟二級(jí)緩存,eviction=緩存回收策略,flushInterval=緩存刷新間隔(毫秒)
@CacheNamespace(eviction = org.apache.ibatis.cache.decorators.LruCache.class, flushInterval = 60000)
@Repository
public interface UserMapper extends BaseMapper<User> {
    // 接口方法不變
}

5.1.2 二級(jí)緩存注意事項(xiàng)

  • 緩存的數(shù)據(jù)必須是可序列化的(實(shí)體類(lèi)需實(shí)現(xiàn) Serializable 接口),否則會(huì)報(bào)錯(cuò);
  • 二級(jí)緩存適用于查詢(xún)頻繁、修改較少的數(shù)據(jù)(如字典表、配置表),避免緩存雪崩;
  • 當(dāng) Mapper 中的增刪改方法被調(diào)用時(shí),該 Mapper 的二級(jí)緩存會(huì)自動(dòng)清空,保證數(shù)據(jù)一致性;
  • 對(duì)于關(guān)聯(lián)查詢(xún)的緩存,需在關(guān)聯(lián)的 Mapper 接口上也開(kāi)啟二級(jí)緩存,避免緩存失效。

5.2 批量操作:saveBatch、updateBatchById 的注意事項(xiàng)

MyBatis-Plus 提供了批量新增(saveBatch)、批量更新(updateBatchById)等批量操作方法,相比循環(huán)調(diào)用單條操作,批量操作能減少數(shù)據(jù)庫(kù)連接次數(shù),提升操作效率。但在使用時(shí)需注意以下細(xì)節(jié),避免出現(xiàn)性能問(wèn)題或數(shù)據(jù)異常。

5.2.1 批量操作核心注意事項(xiàng)

  • 批次大小控制:saveBatch、updateBatchById 方法默認(rèn)批次大小為 1000(即每 1000 條數(shù)據(jù)執(zhí)行一次批量 SQL)。若批量操作的數(shù)據(jù)量過(guò)大(如 10 萬(wàn)條),無(wú)需修改默認(rèn)批次大小(過(guò)大的批次會(huì)導(dǎo)致 SQL 語(yǔ)句過(guò)長(zhǎng),占用數(shù)據(jù)庫(kù)連接資源);若數(shù)據(jù)量較?。ㄈ鐜装贄l),可手動(dòng)指定批次大?。ㄈ?batchSize = 500)。
  • // 手動(dòng)指定批次大小為500 userService.saveBatch(userList, 500); userService.updateBatchById(userList, 500);
  • 數(shù)據(jù)庫(kù)連接配置優(yōu)化:批量操作需要占用數(shù)據(jù)庫(kù)連接較長(zhǎng)時(shí)間,需在 application.yml 中優(yōu)化數(shù)據(jù)庫(kù)連接池配置(以 HikariCP 為例,Spring Boot 默認(rèn)連接池):
  • spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false username: root password: 123456 hikari: maximum-pool-size: 20 # 最大連接數(shù),根據(jù)服務(wù)器性能調(diào)整 minimum-idle: 5 # 最小空閑連接 connection-timeout: 30000 # 連接超時(shí)時(shí)間(毫秒) idle-timeout: 600000 # 空閑連接超時(shí)時(shí)間(毫秒)
  • 避免嵌套批量操作:不要在批量操作中嵌套另一個(gè)批量操作(如批量新增用戶(hù)時(shí),嵌套批量新增訂單),會(huì)導(dǎo)致數(shù)據(jù)庫(kù)連接耗盡,建議分步驟執(zhí)行,或使用事務(wù)控制。
  • 事務(wù)控制:批量操作建議添加事務(wù)注解(@Transactional),確保批量操作要么全部成功,要么全部失敗,避免數(shù)據(jù)不一致。
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Override
@Transactional(rollbackFor = Exception.class)
public boolean batchSaveUser(List userList) {
// 批量新增,添加事務(wù)控制
return saveBatch(userList, 500);
}
}

5.3 SQL 日志分析與慢查詢(xún)排查建議

在實(shí)際開(kāi)發(fā)中,SQL 性能是影響系統(tǒng)響應(yīng)速度的關(guān)鍵因素。MyBatis-Plus 支持打印執(zhí)行的 SQL 日志,通過(guò)分析日志可以排查慢查詢(xún)、冗余查詢(xún)等問(wèn)題,優(yōu)化 SQL 性能。

5.3.1 SQL 日志配置(application.yml)

已在環(huán)境搭建部分配置了日志打?。╨og-impl: org.apache.ibatis.logging.stdout.StdOutImpl),會(huì)在控制臺(tái)打印執(zhí)行的 SQL 語(yǔ)句、參數(shù)、執(zhí)行時(shí)間等信息,示例如下:

==>  Preparing: SELECT id,username,age FROM user WHERE (age > ?) LIMIT ?,?
==> Parameters: 20(Integer), 0(Long), 2(Long)
<==      Total: 2

5.3.2 慢查詢(xún)排查與優(yōu)化建議

  • 識(shí)別慢查詢(xún):通過(guò) SQL 日志中的執(zhí)行時(shí)間,判斷是否為慢查詢(xún)(一般認(rèn)為執(zhí)行時(shí)間超過(guò) 500ms 的 SQL 為慢查詢(xún))。例如:若某條查詢(xún) SQL 執(zhí)行時(shí)間達(dá)到 2000ms,需重點(diǎn)優(yōu)化。
  • 慢查詢(xún)優(yōu)化方法
    • 添加索引:對(duì)查詢(xún)條件中頻繁使用的字段(如 where、join on 后的字段)添加索引,減少數(shù)據(jù)庫(kù)掃描行數(shù);
    • 避免全表掃描:避免使用 select * 查詢(xún)所有字段,只查詢(xún)需要的字段;避免使用 or、not in 等關(guān)鍵字(可替換為 in、exists);
    • 優(yōu)化關(guān)聯(lián)查詢(xún):減少關(guān)聯(lián)表的數(shù)量,對(duì)關(guān)聯(lián)字段添加索引;避免在關(guān)聯(lián)查詢(xún)中使用子查詢(xún),可替換為 join;
    • 分頁(yè)查詢(xún)優(yōu)化:確保分頁(yè)查詢(xún)的排序字段有索引,避免分頁(yè)時(shí)出現(xiàn)全表排序;
    • 批量操作優(yōu)化:如前所述,使用 MyBatis-Plus 的批量方法,減少數(shù)據(jù)庫(kù)連接次數(shù)。
  • 日志進(jìn)階配置:對(duì)于生產(chǎn)環(huán)境,不建議將日志打印到控制臺(tái)(影響性能),可配置將 SQL 日志輸出到文件,并只打印慢查詢(xún)?nèi)罩荆ㄍㄟ^(guò) Logback/Log4j2 配置),示例(Logback):

到此這篇關(guān)于MyBatis-Plus從基礎(chǔ)CRUD到高級(jí)查詢(xún)與性能優(yōu)化實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)mybatisplus crud查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springMVC中基于token防止表單重復(fù)提交方法

    springMVC中基于token防止表單重復(fù)提交方法

    本篇文章主要介紹了springMVC中基于token防止表單重復(fù)提交方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Springboot Mybatis type-aliases-package錯(cuò)誤的解決方案

    Springboot Mybatis type-aliases-package錯(cuò)誤的解決方案

    在使用Spring Boot 2.7.0整合MyBatis 2.1.3時(shí),遇到mybatis.type-aliases-package配置后XML別名爆紅的問(wèn)題,通過(guò)在model類(lèi)上添加@Alias注解,為類(lèi)定義別名,解決了問(wèn)題
    2026-02-02
  • Java使用hutool實(shí)現(xiàn)文件大小的友好輸出

    Java使用hutool實(shí)現(xiàn)文件大小的友好輸出

    這篇文章主要為大家詳細(xì)介紹了Java如何使用hutool實(shí)現(xiàn)文件大小的友好輸出,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下
    2023-11-11
  • Java實(shí)現(xiàn)郵件找回密碼功能

    Java實(shí)現(xiàn)郵件找回密碼功能

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)郵件找回密碼功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • 簡(jiǎn)單了解Spring Cloud Alibaba相關(guān)知識(shí)

    簡(jiǎn)單了解Spring Cloud Alibaba相關(guān)知識(shí)

    這篇文章主要介紹了簡(jiǎn)單了解Spring Cloud Alibaba相關(guān)知識(shí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • InterlliJ IDEA2020新建java web項(xiàng)目找不到Static Web的解決

    InterlliJ IDEA2020新建java web項(xiàng)目找不到Static Web的解決

    這篇文章主要介紹了InterlliJ IDEA2020新建java web項(xiàng)目找不到Static Web的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Java開(kāi)發(fā)中synchronized的定義及用法詳解

    Java開(kāi)發(fā)中synchronized的定義及用法詳解

    這篇文章主要介紹了Java開(kāi)發(fā)中synchronized的定義及用法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java多線程實(shí)現(xiàn)之Callable詳解

    Java多線程實(shí)現(xiàn)之Callable詳解

    這篇文章主要介紹了Java多線程實(shí)現(xiàn)之Callable詳解,Callable是一個(gè)接口,用于實(shí)現(xiàn)多線程,與實(shí)現(xiàn)Runnable類(lèi)似,但是功能更強(qiáng)大,通過(guò)實(shí)現(xiàn)Callable接口,我們需要重寫(xiě)call()方法,該方法可以在任務(wù)結(jié)束后提供一個(gè)返回值,需要的朋友可以參考下
    2023-08-08
  • java實(shí)現(xiàn)簡(jiǎn)單登錄界面的實(shí)戰(zhàn)過(guò)程

    java實(shí)現(xiàn)簡(jiǎn)單登錄界面的實(shí)戰(zhàn)過(guò)程

    學(xué)習(xí)JAVA的過(guò)程當(dāng)中,登陸界面是多數(shù)人第一個(gè)實(shí)現(xiàn)的小程序,下面這篇文章主要給大家介紹了關(guān)于利用java實(shí)現(xiàn)簡(jiǎn)單登錄界面的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • java 多態(tài)性詳解及簡(jiǎn)單實(shí)例

    java 多態(tài)性詳解及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了java 多態(tài)性詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02

最新評(píng)論

上蔡县| 神池县| 常州市| 永福县| 涞源县| 平原县| 白城市| 临泽县| 托里县| 乐东| 敦化市| 嘉黎县| 文安县| 墨竹工卡县| 奎屯市| 娄烦县| 梅河口市| 永善县| 昌乐县| 盐城市| 浦东新区| 维西| 长乐市| 潍坊市| 宜春市| 镇远县| 广昌县| 马尔康县| 天门市| 永济市| 崇义县| 合阳县| 乐平市| 广安市| 霍林郭勒市| 康乐县| 利津县| 宣城市| 连云港市| 龙岩市| 丰顺县|