MyBatis-Plus 复杂查询Lambda+Wrapper 多条件功能实现

 更新时间:2026年01月08日 16:54:08   作者:Jinkxs  
通过本文的介绍,我们深入了解了MyBatis-Plus中Lambda+Wrapper的强大功能,它不仅极大地简化了SQL的编写,还提高了代码的安全性和可维护性,感兴趣的朋友跟随小编一起看看吧

Java 数据 01:MyBatis-Plus 复杂查询(Lambda+Wrapper 多条件)

在现代 Java Web 开发中,持久层框架的选择对于提升开发效率和系统性能至关重要。MyBatis-Plus 作为 MyBatis 的增强工具,极大地简化了 MyBatis 的使用,提供了丰富的 CRUD 操作和强大的条件构造器。特别是其 LambdaWrapper 结合使用的方式,使得构建复杂查询语句变得简洁而优雅。本文将深入探讨如何利用 MyBatis-Plus 的 Lambda + Wrapper 功能进行复杂的多条件查询。

一、MyBatis-Plus 简介与核心概念

1.1 什么是 MyBatis-Plus?

MyBatis-Plus 是一个 MyBatis 的增强工具,它在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。它提供了许多便捷的功能,如:

  • 代码生成器:一键生成 Mapper、Service、Controller 等代码。
  • 通用 CRUD 操作:无需编写 SQL,即可完成基本的增删改查。
  • 条件构造器 (Wrapper):提供强大且灵活的条件拼接功能。
  • 分页插件:轻松实现分页查询。
  • 性能分析插件:帮助分析 SQL 性能。
  • 乐观锁支持:简化并发控制。
  • 多租户支持:方便实现数据隔离。

1.2 核心组件

  • Mapper 接口:继承 BaseMapper<T>,获得通用 CRUD 方法。
  • Entity 实体类:映射数据库表结构。
  • Wrapper 条件构造器:用于构建查询、更新、删除的条件。
  • LambdaQueryWrapper / LambdaUpdateWrapper:基于 Lambda 表达式的 Wrapper,避免硬编码字段名,提高安全性。

二、Lambda + Wrapper 基础入门

2.1 准备工作

首先,确保你的项目已引入 MyBatis-Plus 依赖。例如,在 Maven 项目中:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.2</version> <!-- 请根据实际情况选择版本 -->
</dependency>

假设我们有一个用户表 user,对应的实体类 User 如下:

package com.example.demo.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("user") // 指定数据库表名
public class User {
    @TableId(value = "id", type = IdType.AUTO) // 主键自增
    private Long id;
    private String name; // 用户名
    private Integer age; // 年龄
    private String email; // 邮箱
    private Integer status; // 状态 (例如: 0 - 无效, 1 - 有效)
    @TableField(fill = FieldFill.INSERT) // 插入时自动填充
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充
    private LocalDateTime updateTime;
    // 构造函数、getter、setter 等省略...
}

对应的 Mapper 接口:

package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 继承 BaseMapper 后,通常不需要额外定义方法
}

2.2 基本查询示例

让我们从最基础的查询开始。假设我们要查询所有状态为有效的用户(status = 1)。

// UserService.java
package com.example.demo.service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public List<User> getUsersByStatus(Integer status) {
        // 使用 LambdaQueryWrapper 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getStatus, status); // WHERE status = ?
        return userMapper.selectList(queryWrapper);
    }
    // 或者更简洁的写法,使用 Wrappers 工具类
    public List<User> getUsersByStatusWithWrappers(Integer status) {
        return userMapper.selectList(Wrappers.<User>lambdaQuery().eq(User::getStatus, status));
    }
}

关键点解析:

  • LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); 创建了一个 Lambda 查询包装器。
  • queryWrapper.eq(User::getStatus, status); 构建了一个等于条件。User::getStatus 是一个方法引用,它指向 User 类的 getStatus() 方法,MyBatis-Plus 会通过反射获取该方法对应的字段名(status)。
  • userMapper.selectList(queryWrapper); 执行查询,返回符合条件的对象列表。

这种方式相比传统 MyBatis 直接写 SQL,具有以下优势:

  • 类型安全:使用方法引用来指定字段,避免了字符串写错导致的运行时错误。
  • 可维护性高:当实体类属性名修改时,IDE 会提示相关代码需要修改,降低维护成本。
  • 语法简洁:代码更加清晰易读。

三、复杂查询条件详解

3.1 基础比较操作符

MyBatis-Plus 提供了丰富的条件构造方法,用于构建各种比较操作。

public List<User> getComplexUsers() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 等于 (eq)
    wrapper.eq(User::getStatus, 1);
    // 不等于 (ne)
    wrapper.ne(User::getAge, 18);
    // 大于 (gt)
    wrapper.gt(User::getAge, 18);
    // 大于等于 (ge)
    wrapper.ge(User::getAge, 18);
    // 小于 (lt)
    wrapper.lt(User::getAge, 60);
    // 小于等于 (le)
    wrapper.le(User::getAge, 60);
    // 模糊匹配 (like)
    wrapper.like(User::getName, "张"); // 名字包含 '张'
    // 左模糊匹配 (likeLeft)
    wrapper.likeLeft(User::getName, "张"); // 名字以 '张' 开头
    // 右模糊匹配 (likeRight)
    wrapper.likeRight(User::getName, "三"); // 名字以 '三' 结尾
    // 不为空 (isNotNull)
    wrapper.isNotNull(User::getEmail);
    // 为空 (isNull)
    wrapper.isNull(User::getPhone); // 假设存在 phone 字段
    // 在某个范围内 (between)
    wrapper.between(User::getAge, 18, 60); // 年龄在 18 到 60 之间
    // 在某个集合内 (in)
    List<Integer> statuses = Arrays.asList(0, 1);
    wrapper.in(User::getStatus, statuses); // 状态在 [0, 1] 中
    // 不在某个集合内 (notIn)
    List<Long> ids = Arrays.asList(1L, 2L, 3L);
    wrapper.notIn(User::getId, ids); // ID 不在 [1, 2, 3] 中
    // 空值处理 (isNotNull / isNull) 的组合
    // 例如:查询有邮箱且状态为有效的用户
    wrapper.isNotNull(User::getEmail).eq(User::getStatus, 1);
    return userMapper.selectList(wrapper);
}

3.2 逻辑操作符

在实际应用中,往往需要组合多个条件。MyBatis-Plus 提供了 and()or() 方法来处理逻辑关系。

3.2.1 AND 连接

默认情况下,所有条件都是 AND 关系。例如,查询年龄大于等于 18 且小于等于 60 且状态为有效的用户:

public List<User> getUsersByAgeAndStatus() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 默认就是 AND 关系
    wrapper.ge(User::getAge, 18)
           .le(User::getAge, 60)
           .eq(User::getStatus, 1);
    return userMapper.selectList(wrapper);
}
3.2.2 OR 连接

使用 or() 方法可以将条件转换为 OR 关系。例如,查询用户名包含“张”或邮箱包含“@qq.com”的用户:

public List<User> getUsersByNameOrEmail() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(User::getName, "张")
           .or()
           .like(User::getEmail, "@qq.com");
    return userMapper.selectList(wrapper);
}
3.2.3 复杂嵌套逻辑

可以通过 apply() 方法或者嵌套 LambdaQueryWrapper 来处理更复杂的逻辑。

使用 apply() 方法

apply() 方法允许直接传入 SQL 片段,适用于一些无法通过标准方法表达的复杂条件。

public List<User> getUsersWithApply() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 示例:查询邮箱后缀为 '.com' 且年龄在某个范围内的用户
    wrapper.apply("email LIKE '%.com'")
           .between(User::getAge, 20, 50);
    return userMapper.selectList(wrapper);
}
嵌套 LambdaQueryWrapper

对于复杂的 ORAND 组合,可以创建子 LambdaQueryWrapper 并将其作为参数传递给 and()or() 方法。

public List<User> getUsersComplexLogic() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 示例:查询满足以下任一条件的用户:
    // 1. 年龄大于等于 18 且状态为有效 (age >= 18 AND status = 1)
    // 2. 年龄小于 18 且邮箱包含 '@school.edu' (age < 18 AND email LIKE '%@school.edu')
    wrapper.and(subWrapper -> subWrapper.ge(User::getAge, 18).eq(User::getStatus, 1))
           .or()
           .and(subWrapper -> subWrapper.lt(User::getAge, 18).like(User::getEmail, "@school.edu"));
    return userMapper.selectList(wrapper);
}

3.3 聚合函数与分组查询

MyBatis-Plus 也支持聚合函数和分组查询,常用于统计分析。

public void groupByAgeAndCount() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getAge, "COUNT(*) as count") // 选择年龄和计数
           .groupBy(User::getAge); // 按年龄分组
    // 注意:selectList 返回的是 List<User>,这里需要特别注意
    // 如果你想得到分组后的结果,通常会用到 Map 或自定义 DTO
    // 但 MyBatis-Plus 的 selectList 一般不直接返回聚合结果
    // 更常见的是使用原生 SQL 或者自定义方法
    // 这里展示一种方式,可能需要调整
}
// 更推荐的做法是使用自定义 SQL 或者结合分页插件
// 例如,使用自定义 Mapper 方法

对于更复杂的聚合查询,建议使用自定义 SQL 或者结合 MyBatis 的 <select> 标签。

3.4 排序与分页

3.4.1 排序 (orderBy)
public List<User> getUsersSortedByAgeDesc() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.orderByDesc(User::getAge); // 按年龄降序排列
    return userMapper.selectList(wrapper);
}
public List<User> getUsersSortedMultiple() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 先按年龄降序,再按创建时间升序
    wrapper.orderByDesc(User::getAge).orderByAsc(User::getCreateTime);
    return userMapper.selectList(wrapper);
}
3.4.2 分页 (Page)

MyBatis-Plus 提供了分页插件,配合 Page 对象使用。

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
public IPage<User> getUsersPage(int current, int size) {
    Page<User> page = new Page<>(current, size); // 当前页码,每页大小
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(User::getStatus, 1) // 状态为有效
           .orderByDesc(User::getCreateTime); // 按创建时间倒序
    // 执行分页查询
    return userMapper.selectPage(page, wrapper);
}

四、高级特性与最佳实践

4.1 动态查询构建

在实际业务中,查询条件往往是动态的。我们可以根据传入的参数,动态地构建 LambdaQueryWrapper

public List<User> searchUsers(String name, Integer minAge, Integer maxAge, Integer status, Boolean includeInactive) {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 动态添加条件
    if (name != null && !name.isEmpty()) {
        wrapper.like(User::getName, name);
    }
    if (minAge != null) {
        wrapper.ge(User::getAge, minAge);
    }
    if (maxAge != null) {
        wrapper.le(User::getAge, maxAge);
    }
    if (status != null) {
        wrapper.eq(User::getStatus, status);
    }
    // 特殊处理:如果 includeInactive 为 false,则排除状态为 0 的用户
    if (includeInactive != null && !includeInactive) {
        wrapper.ne(User::getStatus, 0); // 不等于 0
    } else if (includeInactive == null || includeInactive) {
        // 如果 includeInactive 为 null 或 true,可以不加任何条件,或者加上其他逻辑
        // 这里简单示例,不加额外条件
    }
    // 添加排序
    wrapper.orderByDesc(User::getCreateTime);
    return userMapper.selectList(wrapper);
}

4.2 使用select()指定字段

为了提高查询效率,通常只查询需要的字段,而不是使用 *

public List<User> getUsersOnlyNameAndEmail() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getName, User::getEmail); // 只查询 name 和 email 字段
    return userMapper.selectList(wrapper);
}

4.3 使用selectObjs()获取单个字段值

如果你只需要查询某个字段的所有值,可以使用 selectObjs()

public List<String> getUserNames() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(User::getName); // 查询所有用户的姓名
    return userMapper.selectObjs(wrapper, row -> (String) row); // 转换为 String 列表
}

4.4 使用exists()和notExists()

用于检查子查询是否存在记录。

public List<User> getUsersWithOrders() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    // 查询有订单的用户
    wrapper.exists(
        "SELECT 1 FROM order o WHERE o.user_id = user.id"
    );
    return userMapper.selectList(wrapper);
}

4.5 性能优化建议

  1. 索引优化:确保查询条件中涉及的字段有合适的数据库索引。
  2. **避免 SELECT ***:明确指定需要的字段。
  3. 合理使用分页:避免一次性查询大量数据。
  4. 缓存查询结果:对于不经常变动的数据,可以考虑使用缓存。
  5. 避免 N+1 查询:在关联查询时注意性能问题。

五、实战案例:用户管理后台查询接口

让我们结合一个完整的场景来演示如何使用 Lambda + Wrapper 构建复杂的查询。假设我们需要实现一个用户管理后台的查询接口,支持以下功能:

  • 按用户名模糊搜索
  • 按年龄区间筛选
  • 按状态筛选
  • 按邮箱后缀筛选
  • 支持排序(按创建时间倒序)
  • 支持分页

5.1 控制器层 (Controller)

package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    /**
     * 查询用户列表
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    @GetMapping("/list")
    public Page<User> listUsers(UserQueryDTO queryDTO) {
        return userService.getUsersPage(queryDTO);
    }
    /**
     * 获取所有用户(不分页)
     * @param queryDTO 查询条件
     * @return 用户列表
     */
    @GetMapping("/all")
    public List<User> getAllUsers(UserQueryDTO queryDTO) {
        return userService.getAllUsers(queryDTO);
    }
}

5.2 DTO 层 (Data Transfer Object)

package com.example.demo.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserQueryDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name; // 用户名
    private Integer minAge; // 最小年龄
    private Integer maxAge; // 最大年龄
    private Integer status; // 状态
    private String emailSuffix; // 邮箱后缀 (例如: @gmail.com)
    private Integer current = 1; // 当前页码
    private Integer size = 10; // 每页大小
}

5.3 Service 层 (Service)

package com.example.demo.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    /**
     * 分页查询用户
     * @param queryDTO 查询条件
     * @return 分页结果
     */
    public Page<User> getUsersPage(UserQueryDTO queryDTO) {
        Page<User> page = new Page<>(queryDTO.getCurrent(), queryDTO.getSize());
        // 构建查询条件
        buildQueryCondition(queryDTO, page);
        return userMapper.selectPage(page, page.getOptimizeJoinFlag());
    }
    /**
     * 获取所有符合条件的用户(不分页)
     * @param queryDTO 查询条件
     * @return 用户列表
     */
    public List<User> getAllUsers(UserQueryDTO queryDTO) {
        // 构建查询条件
        buildQueryCondition(queryDTO, null); // 注意:这里传入 null 或者构建一个没有分页的 wrapper
        // 由于 selectPage 需要 wrapper 参数,我们直接调用 selectList
        // 但是为了复用逻辑,我们先构建一个 wrapper
        return userMapper.selectList(buildQueryCondition(queryDTO, null));
    }
    /**
     * 构建查询条件并返回 LambdaQueryWrapper
     * @param queryDTO 查询条件
     * @param page 分页对象(可选,如果不需要分页则传 null)
     * @return LambdaQueryWrapper
     */
    private com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> buildQueryCondition(UserQueryDTO queryDTO, Page<User> page) {
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> wrapper = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
        // 动态添加查询条件
        if (queryDTO.getName() != null && !queryDTO.getName().isEmpty()) {
            wrapper.like(User::getName, queryDTO.getName());
        }
        if (queryDTO.getMinAge() != null) {
            wrapper.ge(User::getAge, queryDTO.getMinAge());
        }
        if (queryDTO.getMaxAge() != null) {
            wrapper.le(User::getAge, queryDTO.getMaxAge());
        }
        if (queryDTO.getStatus() != null) {
            wrapper.eq(User::getStatus, queryDTO.getStatus());
        }
        if (queryDTO.getEmailSuffix() != null && !queryDTO.getEmailSuffix().isEmpty()) {
            // 使用 likeRight 或者 apply 都可以
            // 这里使用 likeRight 示例
            wrapper.likeRight(User::getEmail, queryDTO.getEmailSuffix());
            // 或者使用 apply: wrapper.apply("email LIKE '%" + queryDTO.getEmailSuffix() + "'");
        }
        // 添加排序
        wrapper.orderByDesc(User::getCreateTime);
        // 如果传入了分页对象,则设置分页信息
        if (page != null) {
            // 这里可以设置分页信息,但实际上 selectPage 会自动处理
            // 但为了清晰,我们可以将 wrapper 传回给 selectPage
            // 注意:selectPage 方法本身会接收 wrapper 和 page 对象
        }
        return wrapper;
    }
    // 修正后的 getAllUsers 方法,使用单独的方法构建 wrapper
    public List<User> getAllUsersCorrect(UserQueryDTO queryDTO) {
        com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<User> wrapper = buildQueryCondition(queryDTO, null);
        return userMapper.selectList(wrapper);
    }
}

5.4 Mapper 层 (Mapper)

package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // 继承 BaseMapper 后,通常不需要额外定义方法
    // 如果需要自定义 SQL,可以在 XML 文件中定义
}

5.5 请求示例

启动应用后,可以通过如下请求来测试接口:

  • 获取所有有效用户(分页)
    GET /users/list?status=1&current=1&size=10
  • 获取用户名包含“李”且年龄在 20 到 40 之间的有效用户
    GET /users/list?name=李&minAge=20&maxAge=40&status=1&current=1&size=10
  • 获取邮箱以 “@gmail.com” 结尾的所有用户
    GET /users/list?emailSuffix=@gmail.com&current=1&size=10

六、常见问题与解决方案

6.1 字段名拼写错误

使用 Lambda 表达式可以有效避免字段名拼写错误的问题,因为编译期就会检查方法引用是否正确。

6.2 性能问题

  • 原因:未建立合适的索引、查询字段过多、未使用分页等。
  • 解决:确保查询字段上有索引;只查询需要的字段;使用分页。

6.3 空指针异常

  • 原因:在构建条件时,没有对传入的参数进行非空判断。
  • 解决:在构建条件前,对参数进行判空处理。

6.4 SQL 注入风险

  • 原因:使用 apply() 方法时,如果直接拼接用户输入,可能导致 SQL 注入。
  • 解决:使用参数化查询,避免直接拼接用户输入。对于 apply(),应谨慎使用,并确保输入经过验证。

七、总结与展望

通过本文的介绍,我们深入了解了 MyBatis-Plus 中 Lambda + Wrapper 的强大功能。它不仅极大地简化了 SQL 的编写,还提高了代码的安全性和可维护性。从简单的条件查询到复杂的嵌套逻辑,从动态构建到性能优化,Lambda + Wrapper 都能胜任。

掌握这些技巧,可以让我们的 Java Web 开发更加高效和优雅。随着 MyBatis-Plus 的持续发展,相信未来会有更多便捷的功能加入,进一步提升开发体验。

📚 参考资料

希望这篇文章能帮助你更好地理解和使用 MyBatis-Plus 的 Lambda + Wrapper 功能!🚀

到此这篇关于MyBatis-Plus 复杂查询Lambda+Wrapper 多条件功能实现的文章就介绍到这了,更多相关mybits-plus复杂查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 原来Java接口多实现还可以这样玩

    原来Java接口多实现还可以这样玩

    JAVA中类不直接支持多继承,因为会出现调用的不确定性,所以JAVA将多继承机制进行改良,在JAVA中变成了多实现,这篇文章主要给大家介绍了关于Java接口多实现的相关资料,需要的朋友可以参考下
    2021-09-09
  • SpringCloud 中防止绕过网关请求直接访问后端服务的解决方法

    SpringCloud 中防止绕过网关请求直接访问后端服务的解决方法

    这篇文章主要介绍了SpringCloud中如何防止绕过网关请求直接访问后端服务,本文给大家分享三种解决方案,需要的朋友可以参考下
    2023-06-06
  • Java中IO多路复用技术的用法解读

    Java中IO多路复用技术的用法解读

    本文详细介绍了Java中的IO多路复用机制,包括阻塞IO、非阻塞IO(NIO)和异步IO(AIO)的不同,并重点讲解了Java NIO的核心组件:通道(Channel)、缓冲区(Buffer)和选择器(Selector),通过实际代码示例,展示了如何使用NIO实现高效的多客户端服务器
    2025-11-11
  • 通过String.intern()方法浅谈堆中常量池

    通过String.intern()方法浅谈堆中常量池

    这篇文章主要介绍了通过String.intern()方法浅谈堆中常量池,在JDK7之前,字符串常量是存在永久带Perm 区的,JDK7开始在将常量池迁移到堆中,这个变化也导致了String的新特性,下面我们慢慢进行介绍。,需要的朋友可以参考下
    2019-06-06
  • Spring @Valid @Validated实现验证

    Spring @Valid @Validated实现验证

    这篇文章主要介绍了Spring @Valid @Validated实现验证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • SpringBoot实现无限级评论回复的项目实践

    SpringBoot实现无限级评论回复的项目实践

    本文主要介绍了SpringBoot实现无限级评论回复的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Java编程实现判断网上邻居文件是否存在的方法

    Java编程实现判断网上邻居文件是否存在的方法

    这篇文章主要介绍了Java编程实现判断网上邻居文件是否存在的方法,涉及Java针对路径转换及字符串操作的相关技巧,需要的朋友可以参考下
    2015-10-10
  • Spring Boot2开发之Spring Boot整合Shiro两种详细方法

    Spring Boot2开发之Spring Boot整合Shiro两种详细方法

    这篇文章主要介绍了Spring Boot2开发之Spring Boot整合Shiro详细方法,需要的朋友可以参考下
    2020-03-03
  • Java之并行流(Parallel Stream)使用详解

    Java之并行流(Parallel Stream)使用详解

    Java并行流(ParallelStream)通过多线程并行处理集合数据,利用Fork/Join框架加速计算,适用于大规模数据集和计算密集型任务,并行流主要通过集合的parallelStream()方法或现有流的parallel()方法创建,适用于数据量大、计算复杂且无状态操作的场景
    2025-03-03
  • 解决feign接口返回泛型设置属性为null的问题

    解决feign接口返回泛型设置属性为null的问题

    这篇文章主要介绍了解决feign接口返回泛型设置属性为null的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06

最新评论