springboot3集成mybatis-plus

1.在pom.xml引入依赖

我的springboot版本是3.5.7,所以引入下面的不然报错(org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'userMapper' defined in file

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.14</version>
</dependency>

2.创建entity包,创建User.java

package com.yuhuan.hellomp.entity;

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

@Data
@TableName("user")
public class User {

    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @TableField("name")
    private String name;

    @TableField("age")
    private Integer age;

    @TableField("email")
    private String email;
}

实体类中的三个注解的含义如下(需要引入Lombok依赖)

@TableName:表名注解,用于标识实体类所对应的表
  value:用于声明表名

@TableId:主键注解,用于标识主键字段
  value:用于声明主键的字段名
  type:用于声明主键的生成策略,常用的策略有`AUTO`、`ASSIGN_UUID`、`INPUT`等等

@TableField:普通字段注解,用于标识属性所对应的表字段
  value:用于声明普通字段的字段名

3.创建mapper包,已经接口UserMapper.java

package com.yuhuan.hellomp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yuhuan.hellomp.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
}

4.配置application.yml文件

spring:
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: Server@123
      url: jdbc:mysql://192.168.200.128:3306/hello_mp?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  # 注意是 StdOutImpl(O 是字母)
    
#启动项目后,当代码执行数据库操作(查询、新增、修改、删除)时,控制台会输出类似这样的日志:
#==>  Preparing: SELECT id, name, age FROM user WHERE id = ?
#==> Parameters: 1(Integer)
#<==    Columns: id, name, age
#<==        Row: 1, 张三, 25
#<==      Total: 1

​

5.创建测试文件

右击UserMapper转到测试,完成测试类

@SpringBootTest
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testList(){
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

    @Test
    public void testSelectById(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }

    @Test
    public void testInsert(){
        User user = new User();
        user.setAge(10);
        user.setName("大水牛");
        user.setEmail("dashuiniu@123.com");
        userMapper.insert(user);
    }

    @Test
    public void testUpdateById(){
        User user = userMapper.selectById(1);
        user.setName("小明");
        userMapper.updateById(user);
    }

    @Test
    public void testDeleteById(){
        userMapper.deleteById(1);
    }
}

6.通用service

创建接口UserService.java

public interface UserService extends IService<User> {
}

在 MyBatis-Plus(MP)中,IService 是 MP 提供的一套通用 Service 层接口,封装了常见的 CRUD 业务逻辑(如新增、删除、修改、查询、分页等),目的是 简化 Service 层代码编写,避免重复开发基础业务逻辑,同时与 MP 的 BaseMapper(DAO 层通用接口)深度配合,形成「DAO+Service」完整的通用架构。

总结

IService 是 MP 对 Service 层的「通用封装」,核心价值是 减少重复代码、提高开发效率,尤其适合常规 CRUD 业务。使用时只需「接口继承 IService + 实现类继承 ServiceImpl」,就能快速获得完整的 CRUD + 批量 + 分页能力,同时支持自定义扩展,是 MP 中非常实用的核心组件。

创建类UserServiceImpl.java

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

ServiceImpl 是 MyBatis-Plus(MP)中 IService 接口的通用实现类,是 IService 的「落地载体」—— 它已经帮我们实现了 IService 中所有通用 CRUD、批量操作、分页等方法,开发者的 Service 实现类只需继承 ServiceImpl<Mapper, Entity>,就能直接复用这些实现,无需自己编写重复的 Service 层逻辑。

ServiceImpl 核心价值总结

  • 「少写代码」:无需手动实现 CRUD、批量、分页等基础逻辑,专注业务核心;
  • 「降低风险」:统一的实现模板,减少手动编码出错(如批量操作的批次处理、条件构造的语法错误);
  • 「无缝衔接」:与 MP 的 BaseMapperQueryWrapper、分页插件等组件深度整合,形成完整生态;
  • 「灵活扩展」:支持自定义方法、覆盖父类方法,满足复杂业务场景。

简单说,ServiceImpl 是 MP 给 Service 层的「懒人工具」—— 能复用的都帮你写好了,你只需要关注业务逻辑,不用再做重复工作!

使用案例

@SpringBootTest
class UserServiceImplTest {
    @Autowired
    private UserService userService;
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testList(){
        List<User> users  = userService.list();
        for (User user : users) {
            System.out.println("User: " + user);
        }
    }
    @Test
    public void testGetById(){
        User byId = userService.getById(2);
        System.out.println(byId);
    }

    @Test
    public void testSave(){
        User user = new User();
        user.setName("宋江");
        user.setAge(40);
        user.setEmail("songjiang@123.com");
        boolean save = userService.save(user);
        System.out.println(save);
    }

    @Test
    public void testUpdateById(){
        User user = userService.getById(3);
        user.setName("豹子头林冲");
        boolean b = userService.updateById(user);
    }

    @Test
    public void testRemoveById(){
        boolean b = userService.removeById(2);
    }

    @Test
    public void testSaveOrUpdate(){
        //没有id就新增
        User user1 = new User();
        user1.setName("鲁智深");
        user1.setEmail("luzhishen@123.com");
        user1.setAge(40);
        userService.saveOrUpdate(user1);
        //存在id就修改
        User user2 = userService.getById(4);
        user2.setName("武松");
        userService.saveOrUpdate(user2);
    }

    @Test
    public void testSaveBatch(){
        User user1 = new User();
        user1.setName("李逵");
        user1.setEmail("likui@123.com");
        user1.setAge(40);
        User user2 = new User();
        user2.setName("杨志");
        user2.setEmail("杨志@123.com");
        user2.setAge(40);
        List<User> user3 = List.of(user1, user2);
        userService.saveBatch(user3);
    }
}

7.条件构造器

MyBatis-Plus(MP)的 条件构造器 是一套用于「动态构建 SQL 条件」的工具,核心价值是 无需手动拼接 SQL 字符串,通过 Java 链式调用的方式构造查询 / 更新条件,避免 SQL 注入风险,同时简化代码。

MP 提供了两类核心条件构造器,适配不同场景:

  • QueryWrapper:用于 查询条件 构造(如 WHERE name = ? AND age > ?);
  • UpdateWrapper:用于 更新条件 构造(如 SET name = ? WHERE id = ?);
  • 衍生的 LambdaQueryWrapper/LambdaUpdateWrapper:通过 Lambda 表达式引用实体类字段,避免硬编码字段名(推荐使用,减少字段名写错风险)。

创建WrapperTest.java文件

@SpringBootTest
public class WrapperTest {
    @Autowired
    private UserService userService;
    @Test
    public void testQueryWrapper(){
        //查询name=宋江的所有用户
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("name","宋江");
        List<User> userList = userService.list(userQueryWrapper);
        userList.forEach(user -> System.out.println("用户名称:"+user.getName()+" "+"年龄:"+user.getAge()));
        System.out.println("=========================");
        //查询邮箱包含为baomidou.com的所有用户
        QueryWrapper<User> userQueryWrapper2 = new QueryWrapper<>();
        userQueryWrapper2.like("email","baomidou.com");
        List<User> userList2 = userService.list(userQueryWrapper2);
        userList2.forEach(System.out::println);
        System.out.println("=========================");
        //查询所有用户信息并按照age字段降序排序
        QueryWrapper<User> userQueryWrapper3 = new QueryWrapper<>();
        userQueryWrapper3.orderByDesc("age");
        List<User> userList3 = userService.list(userQueryWrapper3);
        userList3.forEach(System.out::println);
        System.out.println("=========================");
        //查询age介于[20,30]的所有用户
        QueryWrapper<User> userQueryWrapper4 = new QueryWrapper<>();
        userQueryWrapper4.between("age",20,30);
        List<User> userList4 = userService.list(userQueryWrapper4);
        userList4.forEach(System.out::println);
        System.out.println("=========================");
        //查询age小于20或大于30的用户
        QueryWrapper<User> userQueryWrapper5 = new QueryWrapper<>();
        userQueryWrapper5.lt("age", 20).or().gt("age", 30);
        List<User> userList5 = userService.list(userQueryWrapper5);
        userList5.forEach(System.out::println);
        System.out.println("=========================");
        //邮箱域名为baomidou.com且年龄小于30或大于40且的用户
        QueryWrapper<User> userQueryWrapper6= new QueryWrapper<>();
        userQueryWrapper6.like("email","baomidou.com").and(user->{
            user.lt("age",30).or().gt("age",40);
        });
        List<User> userList6 = userService.list(userQueryWrapper6);
        userList6.forEach(System.out::println);
    }

    @Test
    public void testUpdateWrapper(){
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("name","鲁智深");
        userUpdateWrapper.set("email","lzs@234.com");
        userService.update(userUpdateWrapper);
    }
}

LambdaWrapperTest

上述的QueryWrapper和UpdateWrapper均有一个Lambda版本,也就是LambdaQueryWrapper和LambdaUpdateWrapper,Lambda版本的优势在于,可以省去字段名的硬编码,具体案例如下:

@SpringBootTest
public class LambdaWrapperTest {
    @Autowired
    private UserService userService;

    @Test
    public void testLambdaQueryWrapper(){
        //查询name=宋江的所有用户
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getName,"宋江");
        List<User> list = userService.list(userLambdaQueryWrapper);
        list.forEach(System.out::println);
    }

    @Test
    public void testLambdaUpdateWrapper(){
        //将name=豹子头林冲的用户的邮箱改为lc@123.com
        LambdaUpdateWrapper<User> userLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        userLambdaUpdateWrapper.eq(User::getName,"豹子头林冲").set(User::getEmail,"lc@123.com");
        userService.update(userLambdaUpdateWrapper);
    }
}

8.分页插件

MyBatis-Plus 的分页插件 PaginationInnerInterceptor 提供了强大的分页功能,支持多种数据库,使得分页查询变得简单高效。

配置方法

在 Spring Boot 项目中,你可以通过 Java 配置来添加分页插件:

@Configuration
@MapperScan("scan.your.mapper.package")
public class MybatisPlusConfig {

    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加
        // 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
        return interceptor;
    }
}

分页对象包含了分页的各项信息,其核心属性如下:

属性名类型默认值描述
recordsListemptyList查询数据列表
totalLong0查询列表总记录数
sizeLong10每页显示条数,默认10​
currentLong1当前页

分页对象既作为分页查询的参数,也作为分页查询的返回结果,当作为查询参数时,通常只需提供current​和size​属性,如下

IPage<T> page = new Page<>(current, size);

注:IPage​为分页接口,Page​为IPage​接口的一个实现类。

  • 分页查询

    Mybatis Plus的BaseMapper​和ServiceImpl​均提供了常用的分页查询的方法,例如:

    • ​BaseMapper​的分页查询:

      IPage<T> selectPage(IPage<T> page,Wrapper<T> queryWrapper);
      
    • ​ServiceImpl​的分页查询:

      // 无条件分页查询
      IPage<T> page(IPage<T> page);
      // 条件分页查询
      IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
      
    • 自定义Mapper

      对于自定义SQL,也可以十分方便的完成分页查询,如下

      ​Mapper​接口:

      //定义一个自定义查询分页的方法
      IPage<User> selectUserPage(IPage<User> page);
      

      ​Mapper.xml​:

      <mapper namespace="com.yuhuan.book.mapper.UserMapper">
          <select id="selectUserPage" resultType="com.yuhuan.book.entity.User">
              select *
              from user
          </select>
      </mapper>
      

      注意:Mapper.xml​中的SQL只需实现查询list​的逻辑即可,无需关注分页的逻辑。

示例如下:

package com.yuhuan.book.page;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuhuan.book.entity.User;
import com.yuhuan.book.mapper.UserMapper;
import com.yuhuan.book.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;
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testPageService(){
        Page<User> userPage = new Page<>(1,3);
        Page<User> result = userService.page(userPage);
        result.getRecords().forEach(System.out::println);

    }
    @Test
    public void testPageMapper(){
        Page<User> userPage = new Page<>(1,3);
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lt("age",40);
        Page<User> userPage1 = userMapper.selectPage(userPage, userQueryWrapper);
        userPage1.getRecords().forEach(System.out::println);
    }
    @Test
    //自定义SQL分页查询
    public void testCustomMapper(){
        Page<User> userPage = new Page<>(1,3);
        IPage<User> userIPage = userMapper.selectUserPage(userPage);
        userIPage.getRecords().forEach(System.out::println);
    }
}

9.MyBatisX插件

MyBatis Plus提供了一个IDEA插件——MybatisX​,使用它可根据数据库快速生成Entity​、Mapper​、Mapper.xml​、Service​、ServiceImpl​等代码,使用户更专注于业务。

1.安装插件

2. 配置数据库连接

根据上面的操作完成后,就会自动生成 entity、service、mapper下面的文件还有 UserMapper.xml文件

注意事项:

通过mybatisX下面生成的Mapper文件下面文件,都要增加@Mapper注解,自定义的方法要alt+enter生成出来,xml里面的sql语句也要自己重新写一下

在若依框架中集成 MyBatis-Plus 可以显著提升 Spring Boot 3 项目的开发效率,尤其是在数据访问层的简化和功能扩展方面。以下是详细的集成步骤和配置方法: ### 添加依赖 首先,在项目的 `pom.xml` 文件中添加 MyBatis-Plus 的依赖。确保使用与 Spring Boot 3 兼容的版本,例如 `3.5.1` 或更高版本。 ```xml <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency> ``` 此外,若依框架通常集成了 Druid 数据源,因此也需要确保 `mybatis-plus-extension` 被引入,以便支持更多高级功能。 ### 配置 MyBatis-Plus 在 `application.yml` 中添加 MyBatis-Plus 的相关配置,包括分页插件、乐观锁插件等。 ```yaml mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath*:mapper/**/*.xml ``` 若依框架通常使用 `@Configuration` 类来管理配置。可以通过创建一个 `MyBatisPlusConfig` 类来注册插件,例如乐观锁插件。 ```java @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } } ``` 该配置类使用 `MybatisPlusInterceptor` 来注册 `OptimisticLockerInnerInterceptor` 插件,以支持乐观锁功能[^3]。 ### 使用 MyBatis-Plus 的基础功能 在若依框架中,通常会定义一个 `IService` 接口来封装数据访问逻辑。可以通过继承 `IService` 接口并使用 `ServiceImpl` 实现类来简化开发。 ```java public interface ISubCompanyService extends IService<SubCompany> { SubCompany findById(Integer id); } ``` 对应的实现类可以如下定义: ```java @Service public class SubCompanyServiceImpl extends ServiceImpl<SubCompanyMapper, SubCompany> implements ISubCompanyService { @Override public SubCompany findById(Integer id) { return this.getById(id); } } ``` 通过继承 `ServiceImpl`,可以直接使用 `getById` 等方法,无需手动编写 SQL 语句[^4]。 ### 分页查询 若依框架通常需要支持分页查询功能,MyBatis-Plus 提供了内置的分页插件支持。 ```java public interface SubCompanyMapper extends BaseMapper<SubCompany> { IPage<SubCompany> selectPage(IPage<SubCompany> page); } ``` 在服务层调用分页查询方法: ```java public IPage<SubCompany> getSubCompanyPage(int pageNum, int pageSize) { IPage<SubCompany> page = new Page<>(pageNum, pageSize); return subCompanyMapper.selectPage(page, null); } ``` ### 乐观锁处理 在数据更新时,乐观锁可以有效避免并发修改问题。实体类中需要使用 `@Version` 注解标识版本字段。 ```java public class SubCompany { private Integer id; @Version private Integer version; // 其他字段和 getter/setter 方法 } ``` 更新操作时,MyBatis-Plus 会自动处理版本号的递增和验证。 ### 总结 通过上述步骤,可以在若依框架中成功集成 MyBatis-Plus,实现数据访问层的简化和功能增强。具体包括依赖配置、插件注册、基础功能使用、分页查询以及乐观锁处理等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值