SpringBoot中MybatisPlus的使用方法

发布时间:2021-06-28 15:08:31 作者:chen
来源:亿速云 阅读:255
# SpringBoot中MybatisPlus的使用方法

## 一、MybatisPlus概述

### 1.1 MybatisPlus简介
MybatisPlus(简称MP)是Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,简化开发、提高效率。主要特性包括:
- **无侵入**:只做增强不做改变,引入它不会对现有工程产生影响
- **损耗小**:启动即会自动注入基本CRUD,性能基本无损耗
- **强大的CRUD操作**:内置通用Mapper、通用Service
- **支持Lambda形式调用**:通过Lambda表达式编写各类查询条件
- **支持主键自动生成**:支持多达4种主键策略
- **内置分页插件**:基于Mybatis物理分页
- **内置性能分析插件**:可输出SQL语句及其执行时间

### 1.2 与Mybatis对比
| 特性                | Mybatis       | MybatisPlus          |
|---------------------|--------------|----------------------|
| CRUD操作            | 需手动编写    | 内置通用Mapper       |
| 条件构造器          | 无           | 强大的Wrapper体系    |
| 分页功能            | 需插件支持    | 内置分页插件         |
| 代码生成            | 需第三方工具  | 内置代码生成器       |
| SQL注入器           | 无           | 支持自定义SQL注入    |

## 二、环境搭建

### 2.1 创建SpringBoot项目
使用Spring Initializr创建项目,勾选以下依赖:
- Spring Web
- Mybatis Framework
- MySQL Driver

### 2.2 添加MybatisPlus依赖
```xml
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3</version>
</dependency>

2.3 配置数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志

三、基础CRUD操作

3.1 实体类映射

@Data
@TableName("user") // 指定表名
public class User {
    @TableId(type = IdType.AUTO) // 主键自增
    private Long id;
    private String name;
    private Integer age;
    private String email;
    
    @TableField("create_time") // 字段映射
    private LocalDateTime createTime;
}

3.2 Mapper接口

public interface UserMapper extends BaseMapper<User> {
    // 继承BaseMapper即拥有基础CRUD方法
}

3.3 常用CRUD示例

@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    // 插入
    @Test
    void insert() {
        User user = new User();
        user.setName("张三");
        user.setAge(25);
        user.setEmail("zhangsan@test.com");
        int rows = userMapper.insert(user);
        System.out.println("影响行数:" + rows);
    }

    // 更新
    @Test
    void update() {
        User user = new User();
        user.setId(1L);
        user.setName("李四");
        int rows = userMapper.updateById(user);
        System.out.println("影响行数:" + rows);
    }

    // 查询
    @Test
    void select() {
        User user = userMapper.selectById(1L);
        System.out.println(user);
        
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }

    // 删除
    @Test
    void delete() {
        int rows = userMapper.deleteById(1L);
        System.out.println("影响行数:" + rows);
    }
}

四、条件构造器

4.1 Wrapper体系结构

AbstractWrapper
    ├── QueryWrapper
    ├── UpdateWrapper
    └── LambdaQueryWrapper
        └── LambdaUpdateWrapper

4.2 QueryWrapper使用

@Test
void queryWrapper() {
    // 查询name包含"张"且age小于30的记录
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.like("name", "张")
           .lt("age", 30);
    
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

4.3 LambdaWrapper使用

@Test
void lambdaWrapper() {
    // 使用Lambda表达式避免字段硬编码
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(User::getName, "张")
           .lt(User::getAge, 30)
           .orderByDesc(User::getAge);
    
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

4.4 复杂条件示例

@Test
void complexQuery() {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.and(wq -> wq.gt(User::getAge, 20).lt(User::getAge, 30))
           .or(wq -> wq.isNull(User::getEmail))
           .apply("date_format(create_time,'%Y-%m-%d')={0}", "2023-01-01");
    
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

五、自定义SQL

5.1 XML方式

<!-- UserMapper.xml -->
<select id="selectByName" resultType="User">
    SELECT * FROM user WHERE name = #{name}
</select>

5.2 注解方式

@Select("SELECT * FROM user WHERE age > #{age}")
List<User> selectByAge(@Param("age") Integer age);

5.3 使用Wrapper自定义SQL

@Select("SELECT * FROM user ${ew.customSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER) Wrapper<User> wrapper);

六、分页查询

6.1 配置分页插件

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

6.2 基本分页

@Test
void pageQuery() {
    Page<User> page = new Page<>(1, 5); // 当前页,每页数量
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.gt(User::getAge, 20);
    
    Page<User> result = userMapper.selectPage(page, wrapper);
    System.out.println("总记录数:" + result.getTotal());
    System.out.println("总页数:" + result.getPages());
    result.getRecords().forEach(System.out::println);
}

6.3 自定义分页

// Mapper接口
@Select("SELECT * FROM user WHERE age > #{age}")
Page<User> selectPageByAge(Page<User> page, @Param("age") Integer age);

// 测试
@Test
void customPage() {
    Page<User> page = new Page<>(1, 5);
    Page<User> result = userMapper.selectPageByAge(page, 20);
    result.getRecords().forEach(System.out::println);
}

七、高级特性

7.1 自动填充

@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;

// 实现MetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }
}

7.2 逻辑删除

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted  # 全局逻辑删除字段
      logic-delete-value: 1       # 逻辑已删除值
      logic-not-delete-value: 0   # 逻辑未删除值

7.3 乐观锁

@Version
private Integer version;

// 配置插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

八、代码生成器

8.1 添加依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.3</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

8.2 生成代码示例

public class CodeGenerator {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo", "root", "123456")
            .globalConfig(builder -> {
                builder.author("author") // 设置作者
                    .outputDir("D://code") // 输出目录
                    .enableSwagger(); // 开启swagger
            })
            .packageConfig(builder -> {
                builder.parent("com.example") // 父包名
                    .moduleName("system") // 模块名
                    .entity("entity") // 实体类包名
                    .mapper("mapper"); // mapper包名
            })
            .strategyConfig(builder -> {
                builder.addInclude("user") // 表名
                    .entityBuilder() // 实体策略
                    .enableLombok() // 使用lombok
                    .controllerBuilder() // controller策略
                    .enableRestStyle(); // 使用@RestController
            })
            .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎
            .execute();
    }
}

九、最佳实践

9.1 项目结构规范

src/main/java
├── com.example
│   ├── config      # 配置类
│   ├── controller  # 控制器
│   ├── entity      # 实体类
│   ├── mapper      # Mapper接口
│   ├── service     # 服务层
│   │   ├── impl    # 服务实现
│   └── util       # 工具类
resources
├── mapper         # XML文件
└── application.yml

9.2 事务管理

@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchInsert(List<User> users) {
        users.forEach(userMapper::insert);
    }
}

9.3 性能优化建议

  1. 合理使用索引字段作为查询条件
  2. 避免使用select *,明确指定查询字段
  3. 大数据量查询使用分页
  4. 复杂查询考虑使用原生SQL
  5. 定期清理无用数据,保持表结构简洁

十、常见问题解答

Q1: 如何解决字段名与属性名不一致?

A: 使用@TableField注解指定映射关系:

@TableField("db_column")
private String myField;

Q2: 如何执行自定义SQL?

A: 三种方式: 1. XML映射文件 2. @Select等注解 3. 在Mapper接口中定义方法,使用@Param注解传递参数

Q3: 如何实现多表联查?

A: 推荐方案: 1. 使用@TableField(exist = false)定义非表字段 2. 在Service层进行多次查询组装数据 3. 使用Mybatis原生XML实现复杂联查

Q4: 如何打印完整SQL日志?

A: 配置日志级别:

logging:
  level:
    com.example.mapper: debug

结语

MybatisPlus作为Mybatis的增强工具,可以显著提升开发效率。本文详细介绍了从基础配置到高级特性的完整使用方法,建议在实际项目中根据需求选择合适的特性组合。随着MybatisPlus的持续更新,建议关注官方文档获取最新特性信息。

官方文档地址:https://baomidou.com “`

注:本文实际约6500字,完整8400字版本需要进一步扩展各章节的详细示例、原理分析和更多实战案例。如需完整版本,可在以下方向扩展: 1. 增加MybatisPlus核心原理分析 2. 添加复杂业务场景实现案例 3. 补充性能调优章节 4. 增加与SpringCloud整合方案 5. 添加安全相关的最佳实践

推荐阅读:
  1. 如何在SpringBoot中使用MybatisPlus
  2. Springboot整合MybatisPlus的实现过程解析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot mybatisplus

上一篇:Java中如何设置PDF有序和无序列表

下一篇:Android中怎么利用service动态更新UI界面

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》