欢迎光临
我们一直在努力

第38课-MyBatis-Plus

第38课:MyBatis-Plus

本课目标:掌握MyBatis-Plus的使用,包括BaseMapper、条件构造器、分页查询,提升开发效率。


一、概念讲解

1.1 什么是MyBatis-Plus

MyBatis-Plus是MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,简化开发、提高效率。

┌─────────────────────────────────────────────────────────────┐
│ MyBatis-Plus特性 │
├─────────────────────────────────────────────────────────────┤
│ – 通用CRUD,无需编写SQL │
│ – 条件构造器,链式调用 │
│ – 分页插件,开箱即用 │
│ – 代码生成器 │
│ – 逻辑删除 │
│ – 自动填充 │
└─────────────────────────────────────────────────────────────┘

1.2 架构关系

┌─────────────────────────────────────────┐
│ MyBatis-Plus │
├─────────────────────────────────────────┤
│ IService Service层增强 │
│ BaseMapper Mapper层增强 │
│ Wrapper 条件构造器 │
├─────────────────────────────────────────┤
│ MyBatis │
├─────────────────────────────────────────┤
│ SqlSession 会话 │
│ Mapper 映射器 │
│ XML 映射文件 │
└─────────────────────────────────────────┘


二、语法格式

2.1 BaseMapper方法

// 插入
int insert(T entity);

// 删除
int deleteById(Serializable id);
int deleteByMap(Map<String, Object> map);
int delete(Wrapper<T> wrapper);
int deleteBatchIds(Collection<? extends Serializable> idList);

// 更新
int updateById(T entity);
int update(T entity, Wrapper<T> wrapper);

// 查询
T selectById(Serializable id);
List<T> selectList(Wrapper<T> wrapper);
T selectOne(Wrapper<T> wrapper);
int selectCount(Wrapper<T> wrapper);
List<T> selectPage(Page<T> page, Wrapper<T> wrapper);

2.2 条件构造器

// QueryWrapper
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
.like("email", "@example.com")
.orderByDesc("create_time");

// LambdaQueryWrapper (推荐)
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.eq(User::getName, "张三")
.like(User::getEmail, "@example.com");

// LambdaUpdateWrapper
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(User::getName, "李四")
.eq(User::getId, 1);


三、代码案例

3.1 Maven依赖

<dependencies>
<!– MyBatis-Plus –>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>

<!– MySQL驱动 –>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
</dependency>

<!– Lombok (可选) –>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>

3.2 实体类

package com.example.entity;

import com.baomidou.mybatisplus.annotation.*;
import java.util.Date;

@TableName("user")
public class User {

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

private String name;

private String email;

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

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

@TableLogic
private Integer deleted;

public User() {}

public User(String name, String email) {
this.name = name;
this.email = email;
}

// getter/setter
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public Date getCreateTime() { return createTime; }
public void setCreateTime(Date createTime) { this.createTime = createTime; }
public Date getUpdateTime() { return updateTime; }
public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; }
public Integer getDeleted() { return deleted; }
public void setDeleted(Integer deleted) { this.deleted = deleted; }
}

3.3 Mapper接口

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.User;

public interface UserMapper extends BaseMapper<User> {
// MyBatis-Plus已经提供通用CRUD,无需编写基础方法
}

3.4 Service接口和实现

package com.example.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.example.entity.User;
import java.util.List;

public interface UserService extends IService<User> {
List<User> findByName(String name);
}

package com.example.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import com.example.service.UserService;
import org.springframework.stereotype.Service;
import java.util.List;

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

@Override
public List<User> findByName(String name) {
return lambdaQuery()
.like(User::getName, name)
.list();
}
}

3.5 条件构造器使用

package com.example;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.entity.User;
import com.example.mapper.UserMapper;
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 UserMapperTest {

@Autowired
private UserMapper userMapper;

@Test
public void testInsert() {
User user = new User("张三", "zhangsan@example.com");
int rows = userMapper.insert(user);
System.out.println("插入行数: " + rows);
System.out.println("生成ID: " + user.getId());
}

@Test
public void testSelectById() {
User user = userMapper.selectById(1L);
System.out.println("用户: " + user);
}

@Test
public void testSelectList() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}

@Test
public void testSelectByWrapper() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "张")
.orderByDesc(User::getCreateTime);

List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}

@Test
public void testUpdate() {
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.set(User::getName, "李四")
.eq(User::getId, 1);

int rows = userMapper.update(null, wrapper);
System.out.println("更新行数: " + rows);
}

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

@Test
public void testPage() {
Page<User> page = new Page<>(1, 10);
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.orderByDesc(User::getCreateTime);

Page<User> result = userMapper.selectPage(page, wrapper);
System.out.println("总数: " + result.getTotal());
System.out.println("当前页数据: " + result.getRecords());
}

@Test
public void testCount() {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getName, "张");

int count = userMapper.selectCount(wrapper);
System.out.println("数量: " + count);
}
}

▶ 运行结果:

// testInsert
插入行数: 1
生成ID: 1

// testSelectById
用户: User{id=1, name='张三', email='zhangsan@example.com'}

// testSelectList
User{id=1, name='张三', email='zhangsan@example.com'}
User{id=2, name='李四', email='lisi@example.com'}

// testUpdate
更新行数: 1

// testDelete
删除行数: 1

// testPage
总数: 10
当前页数据: [User{id=1, name='李四', email='lisi@example.com'}, …]

// testCount
数量: 3

3.6 分页配置

package com.example.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 {

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

3.7 代码生成器

package com.example.generator;

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create(
"jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8",
"root", "123456")
.globalConfig(builder -> {
builder.author("example")
.outputDir("F:\\\\code\\\\output")
.disableOpenDir();
})
.packageConfig(builder -> {
builder.parent("com.example")
.moduleName("demo")
.entity("entity")
.mapper("mapper")
.service("service")
.controller("controller");
})
.strategyConfig(builder -> {
builder.addInclude("user", "order")
.entityBuilder()
.naming(NamingStrategy.underline_to_camel)
.columnNaming(NamingStrategy.underline_to_camel)
.enableLombok()
.controllerBuilder()
.enableRestStyle();
})
.execute();
}
}


四、常见错误

错误原因解决方案
Invalid bound statement Mapper方法未找到 检查接口方法名和XML
字段映射错误 命名不匹配 使用@TableField或开启驼峰映射
分页不生效 未配置分页插件 添加PaginationInnerInterceptor
逻辑删除无效 未配置@TableLogic 添加@TableLogic注解
自动填充不触发 未实现MetaObjectHandler 实现填充处理器

五、课后练习

  • 使用BaseMapper实现用户的完整CRUD
  • 使用LambdaQueryWrapper进行复杂条件查询
  • 实现分页查询功能
  • 配置自动填充创建时间和更新时间

  • 六、本课小结

    知识点说明
    BaseMapper 通用Mapper,提供基础CRUD
    IService 通用Service,提供业务方法
    LambdaWrapper 类型安全的条件构造器
    分页插件 PaginationInnerInterceptor
    代码生成器 自动生成Controller/Service/Mapper

    本课程持续更新中,欢迎关注!

    赞(0)
    未经允许不得转载:171主机测评 » 第38课-MyBatis-Plus
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址