• 【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
  • 相关阅读:
    没有基础可以转行ICT行业吗?
    webrtc 的Bundle group 和RTCP-MUX
    数据结构 编程1年新手视角的平衡二叉树AVL从C与C++实现②
    【基础算法】滑动窗口
    shiro会话管理
    今日睡眠质量记录78分
    解决input事件监听拼音输入法导致高频事件
    SQL 基本命令
    iOS 开发代码规范
    Docker_搭建跨服务器网络通讯(swarm 集群)
  • 原文地址:https://blog.csdn.net/qq_42500831/article/details/134471790