文章目录

  • 1. 简单使用
  • 2. 条件构造器 —— 针对于复杂查询
  • 3. 自定义SQL
  • 4. IService
  • 4.1 基本接口方法
  • 4.1.1 新增
  • 4.1.2 删除
  • 4.1.3 修改
  • 4.1.4 查找
  • 4.2 开发基础业务接口
  • 4.3 开发复杂业务接口
  • 4.4 Lambda方法
  • 4.5 批量新增
  • 5. 代码生成
  • 6. 分页功能
  • 6.1 分页插件基本使用
  • 6.1 通用分页实体


1. 简单使用

public interface UserMapper extends BaseMapper<User> {

}

class UserMapperTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setUsername("xiaowang");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userMapper.insert(user);
    }

    @Test
    void testSelectById() {
        User user = userMapper.selectById(5L);
        System.out.println("user = " + user);
    }


    @Test
    void testQueryByIds() {
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }

    @Test
    void testUpdateById() {
        User user = new User();
        user.setId(5L);
        user.setBalance(20000);
        userMapper.updateById(user);
    }

    @Test
    void testDeleteUser() {
        userMapper.deleteById(5L);
    }
}

2. 条件构造器 —— 针对于复杂查询

【MyBatisPlus】快速入门_List


【MyBatisPlus】快速入门_User_02

【MyBatisPlus】快速入门_服务器_03


【MyBatisPlus】快速入门_服务器_04

【MyBatisPlus】快速入门_java_05

@Test
public void testQueryWrapper(){
    // select id, username, info, balance from user where username like %o% and balance = 1000;
    QueryWrapper<User> wrapper = new QueryWrapper<User>()
            .select("id", "username", "info", "balance")
            .like("username", "o")
            .ge("balance", 1000);
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

@Test
public void testUpdateByQueryWrapper(){
    // update user set balance = 2000 where username = "jack";
    User user = new User();
    user.setBalance(2000);
    QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");
    userMapper.update(user, wrapper);
}

@Test
public void testUpdateWrapper(){
    // update user set balance = balance - 200 where id in (1,2,4);
    List<Long> ids = Arrays.asList(1L, 2L, 4L);
    UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                        .setSql("balance = balance - 200")
                        .in("id", ids);
    userMapper.update(null, wrapper);
}

lambdaQueryWrapper解决上述testQueryWrapper硬编码问题

@Test
public void testLambdaQueryWrapper(){
	// select id, username, info, balance from user where username like %o% and balance = 1000;
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
            .select(User::getId, User::getUsername, User::getInfo, User::getBalance)
            .like(User::getUsername, "o")
            .ge(User::getBalance, 1000);
    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

条件构造器的用法:

  • QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的where条件部分
  • UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用
  • 尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码

3. 自定义SQL

【MyBatisPlus】快速入门_List_06

【MyBatisPlus】快速入门_User_07

4. IService

4.1 基本接口方法

IService底层操作数据库,用的还是mapper

【MyBatisPlus】快速入门_windows_08

4.1.1 新增

【MyBatisPlus】快速入门_windows_09

4.1.2 删除

【MyBatisPlus】快速入门_User_10

4.1.3 修改

【MyBatisPlus】快速入门_User_11

4.1.4 查找

【MyBatisPlus】快速入门_java_12


【MyBatisPlus】快速入门_服务器_13

【MyBatisPlus】快速入门_windows_14


【MyBatisPlus】快速入门_User_15

【MyBatisPlus】快速入门_windows_16

4.2 开发基础业务接口

【MyBatisPlus】快速入门_User_17


IUserService.java

public interface IUserService extends IService<User> {
}

UserServiceImpl.java

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
@SpringBootTest
public class IUserServiceTest {
    @Autowired
    private IUserService userService;

    @Test
    void testSaveUser() {
        User user = new User();
        user.setUsername("LiLei");
        user.setPassword("123");
        user.setPhone("18688990011");
        user.setBalance(200);
        user.setInfo("{\"age\": 24, \"intro\": \"英文老师\", \"gender\": \"female\"}");
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        userService.save(user);
    }

    @Test
    void testQueryByIds() {
        List<User> users = userService.listByIds(Arrays.asList(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }
}

【MyBatisPlus】快速入门_java_18

【MyBatisPlus】快速入门_windows_19

@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {
    // final配合@RequiredArgsConstructor,可以通过构造函数注入
    private final IUserService userService;

    @ApiOperation("用户新增接口")
    @PostMapping
    public void saveUser(@RequestBody UserFormDTO userDTO){
        // 使用BeanUtil,将UserFormDTO对象的属性拷贝到User.class
        User user = BeanUtil.copyProperties(userDTO, User.class);
        userService.save(user);
    }

    @ApiOperation("删除用户接口")
    @DeleteMapping("{id}")
    // @PathVariable用于RESTFUL风格,从路径中获取参数
    public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        userService.removeById(id);
    }

    @ApiOperation("根据id查询用户接口")
    @GetMapping("{id}")
    public UserVO queryUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        User user = userService.getById(id);
        return BeanUtil.copyProperties(user, UserVO.class);
    }

    @ApiOperation("根据id批量查询用户接口")
    @GetMapping
    // @RequestParam用于从路径中获取参数,比如ids=1,2,4
    public List<UserVO> queryUserByIds(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){
        List<User> users = userService.listByIds(ids);
        // List<PO> -> List<VO>
        return BeanUtil.copyToList(users, UserVO.class);
    }
}

4.3 开发复杂业务接口

Controller

@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {
	@ApiOperation("扣减用户余额接口")
    @PutMapping("/{id}/deduction/{money}")
    public void deductMoneyById(
            @ApiParam("用户id") @PathVariable("id") Long id,
            @ApiParam("用户money") @PathVariable("money") Integer money){
        userService.deductBalance(id, money);
    }
}

service

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

    private final UserMapper userMapper;

    @Override
    public void deductBalance(Long id, Long money) {
        User user = getById(id);
        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户状态异常!");
        }
        if(user.getBalance() < money){
            throw new RuntimeException("用户余额不足!");
        }
        userMapper.deductBalance(id, money);
    }
}

mapper

public interface UserMapper extends BaseMapper<User> {
    void updateBalanceByIds(@Param(Constants.WRAPPER) UpdateWrapper<User> wrapper, @Param("amount") int amount);

    @Update("UPDATE user SET balance = balance - #{money} WHERE id = #{id}")
    void deductBalance(@Param("id") Long id, @Param("money") Long money);

}

4.4 Lambda方法

controller

@Api(tags = "用户管理接口")
@RequestMapping("/users")
@RestController
@RequiredArgsConstructor
public class UserController {
    // final配合@RequiredArgsConstructor,可以通过构造函数注入
    private final IUserService userService;

    @ApiOperation("根据复杂条件查询用户接口")
    @GetMapping("/list")
    public List<UserVO> queryUsers(UserQuery query){
        List<User> users = userService.queryUsers(query.getName(), query.getStatus(), query.getMinBalance(), query.getMaxBalance());
        return BeanUtil.copyToList(users, UserVO.class);
    }
}

service

public interface IUserService extends IService<User> {
    List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
    	// select * from user where name = ? ans status = ? and balance >= minBalance and balance <= maxBalance;
        return lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .gt(minBalance != null, User::getBalance, minBalance)
                .lt(maxBalance != null, User::getBalance, maxBalance)
                .list();
    }
}

4.5 批量新增

【MyBatisPlus】快速入门_服务器_20

5. 代码生成

MyBatisPlus使用的过程如下:

【MyBatisPlus】快速入门_java_21

这些代码都比较固定,只是类名不同,我们可以用插件自动生成这些比较固定的代码

【MyBatisPlus】快速入门_服务器_22

【MyBatisPlus】快速入门_服务器_23

配置数据库信息

【MyBatisPlus】快速入门_服务器_24

配置代码生成信息

【MyBatisPlus】快速入门_java_25

【MyBatisPlus】快速入门_windows_26

6. 分页功能

6.1 分页插件基本使用

MyBatisPlus内置的分页插件如下:

【MyBatisPlus】快速入门_windows_27


首先,需要在配置类中注册MyBatisPlus的核心插件,同时添加分页插件

@Configuration
public class MybatisConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        // 1 初始化核心插件
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 2 添加分页插件
        PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        pageInterceptor.setMaxLimit(1000L); // 设置分页上限
        interceptor.addInnerInterceptor(pageInterceptor);
        return interceptor;
    }
}

分页对象

【MyBatisPlus】快速入门_windows_28

引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-extension</artifactId>
    <version>3.5.3.1</version>
</dependency>
@Test
public void testPageQuery(){
    // 创建Page对象,设置分页参数
    int pageNo = 2, pageSize = 2;
    Page<User> page = Page.of(pageNo, pageSize);
    // 排序条件
    page.addOrder(new OrderItem("balance", true));
    page.addOrder(new OrderItem("id", true));
    // 分页查询
    Page<User> p = userService.page(page);
    long total = p.getTotal();  // 数据总条数
    long pages = p.getPages();  // 总页数
    List<User> users = p.getRecords();  // 第pageNo页数据,pageSize条
    users.forEach(System.out::println);
}

6.1 通用分页实体

统一的分页查询条件,包括页码、页大小、排序方式、是否升序

@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
    private Integer pageNo;
    private Integer pageSize;
    private String sortBy;
    private Boolean isAsc;
}

用户条件查询实体

@Data
@ApiModel(description = "用户条件查询实体")
public class UserQuery extends PageQuery{
    @ApiModelProperty("用户名关键字")
    private String name;
    @ApiModelProperty("用户状态:1-正常,2-冻结")
    private Integer status;
    @ApiModelProperty("余额最小值")
    private Integer minBalance;
    @ApiModelProperty("余额最大值")
    private Integer maxBalance;
}

返回实体PageDTO

@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageDTO<V> {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总页数")
    private Long pages;
    @ApiModelProperty("结果集合")
    private List<V> list;
}

controller

@ApiOperation("根据复杂条件分页查询用户接口")
@GetMapping("/page")
public PageDTO<UserVO> queryUsersPage(UserQuery query){
    return userService.queryUsersPage(query);
}

service

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    private final UserMapper userMapper;

    @Override
    public PageDTO<UserVO> queryUsersPage(UserQuery query) {
        String name = query.getName();
        Integer status = query.getStatus();
        // 分页参数
        Page<User> page = Page.of(query.getPageNo(), query.getPageSize());
        // 排序条件
        if(StrUtil.isNotBlank(query.getSortBy())){
            page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));
        }else{
            // 排序条件为空,按更新时间排序
            page.addOrder(new OrderItem("update_time", false));
        }

        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);

        PageDTO<UserVO> dto = new PageDTO<>();
        dto.setTotal(p.getTotal());
        dto.setPages(p.getPages());
        List<User> records = p.getRecords();
        
        // 查询结果为空,PageDTO的结果设置为空集合
        if(CollUtil.isEmpty(records)){
            dto.setList(Collections.emptyList());
            return dto;
        }
        // 工具包直接将List<User>转为List<UserVO>
        dto.setList(BeanUtil.copyToList(records, UserVO.class));
        return dto;
    }
}