• 【MyBatisPlus】快速入门


    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

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

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    @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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    条件构造器的用法:

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

    3. 自定义SQL

    在这里插入图片描述

    在这里插入图片描述

    4. IService

    4.1 基本接口方法

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

    在这里插入图片描述

    4.1.1 新增

    在这里插入图片描述

    4.1.2 删除

    在这里插入图片描述

    4.1.3 修改

    在这里插入图片描述

    4.1.4 查找

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    4.2 开发基础业务接口

    在这里插入图片描述
    IUserService.java

    public interface IUserService extends IService<User> {
    }
    
    • 1
    • 2

    UserServiceImpl.java

    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    }
    
    • 1
    • 2
    • 3
    @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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    在这里插入图片描述

    @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 -> List
            return BeanUtil.copyToList(users, UserVO.class);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    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);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    service

    public interface IUserService extends IService<User> {
        List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
    }
    
    • 1
    • 2
    • 3
    @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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4.5 批量新增

    在这里插入图片描述

    5. 代码生成

    MyBatisPlus使用的过程如下:

    在这里插入图片描述

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

    在这里插入图片描述

    在这里插入图片描述

    配置数据库信息

    在这里插入图片描述

    配置代码生成信息

    在这里插入图片描述

    在这里插入图片描述

    6. 分页功能

    6.1 分页插件基本使用

    MyBatisPlus内置的分页插件如下:

    在这里插入图片描述
    首先,需要在配置类中注册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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    分页对象

    在这里插入图片描述

    引入依赖

    <dependency>
        <groupId>com.baomidougroupId>
        <artifactId>mybatis-plus-extensionartifactId>
        <version>3.5.3.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6.1 通用分页实体

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

    @Data
    @ApiModel(description = "分页查询实体")
    public class PageQuery {
        private Integer pageNo;
        private Integer pageSize;
        private String sortBy;
        private Boolean isAsc;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    用户条件查询实体

    @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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    返回实体PageDTO

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class PageDTO<V> {
        @ApiModelProperty("总条数")
        private Long total;
        @ApiModelProperty("总页数")
        private Long pages;
        @ApiModelProperty("结果集合")
        private List<V> list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    controller

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

    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转为List
            dto.setList(BeanUtil.copyToList(records, UserVO.class));
            return dto;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    dubbo(5):使用dubbo进行业务分离与dubbo-admin的使用
    【VM-Tools】Linux快速安装
    【Java面试小短文】Spring 如何解决循环依赖?
    将一个无向图变成一个双联通图所需添加的最小边数
    (附源码)计算机毕业设计Java巴州监控中心人事管理系统
    【源码+名师讲解】Java游戏开发_Java飞机大战1.0进阶版_Java28个功能点能力提升必备_Java初级项目_Java练手项目_Java课程设计
    从String中提取基本类型或包装类数据
    python经典百题之画圆形
    linux /proc进程文件目录介绍
    web前端 HTML5
  • 原文地址:https://blog.csdn.net/qq_42500831/article/details/134471790