IT自学第三十八天

多线程


1、MybatisPlus简介

MybatisPlus

MyBatisPlus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。

2、入门案例环境准备

入门案例

需求:基于资料中提供的mp-demo项目;改造为使用MP实现下列功能:

导入需要的项目,导入需要的数据库表,修改yaml文件的数据库连接信息。

3、快速入门

  • MyBatisPlus官方提供了starter,其中继承了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。

代码演示:

XML 复制代码
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.3</version>
        </dependency>
  • 自定义的Mapper继承MybatisPlus提供的BaseMapper接口:

代码演示:

java 复制代码
public interface UserMapper extends BaseMapper<User> {

}

代码演示:

java 复制代码
@SpringBootTest
class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    void testInsert() {
        User user = new User();
        user.setId(5L);
        user.setUsername("Lucy");
        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(List.of(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);
    }
}

对于多表查询,与复杂查询,利用手动写SQL执行。

4、常见注解

常见注解

MyBatisPlus通过扫描实体类,并基于反射获取实体类信息作为数据库表信息。

  • 类名驼峰转下划线作为表名;
  • 名为id的字段作为主键;
  • 变量名驼峰转下划线作为表的字段名。

MybatisPlus中比较常见的几个注解如下:

5、常见配置

常见配置

MyBatisPlus的配置继承了MyBatis原生配置和一些自己特有的配置。例如:

6、条件构造器-QueryWrapper

条件构造器

MyBatisPlus支持各种复杂的where条件,可以满足日常开发的所有需求。

sql 复制代码
SELECT * FROM products;
UPDATE products SET price=99.9 WHERE id = 3
INSERT INTO products VALUES(3,12,1.2);
DELETE FROM name where ID = 4;

代码演示:

java 复制代码
    //查询user表的id,username,info,balance信息,且username带有o,balance>= 1000的信息
    @Test
    public void testQueryWrapper1(){
        //创建条件构造器
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //查询的列
        queryWrapper.select("id","username","info","balance");
        //查询条件:名字带"o"的
        queryWrapper.like("username","o");
        //查询条件:balance >= 1000
        queryWrapper.ge("balance","1000");
        //查询
        List<User> userList = userMapper.selectList(queryWrapper);
        //输出
        for (User user : userList) {
            System.out.println(user);
        }
    }

    //更新用户名为jack的用户的余额为2000
    @Test
    public void testQueryWrapperUpdate(){
        User user = new User();
        user.setBalance(2000);
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username","jack");
        userMapper.update(user,queryWrapper);
    }

7、条件构造器-UpdateWrapper&LambdaQueryWrapper

基于UpdateWrapper的更新

需求:更新id为1,2,4的用户的余额,扣200.

代码演示:

java 复制代码
//    需求:更新id为1,2,4的用户的余额,扣200.
    @Test
    public void testUpdateWrapper(){
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        //自定义更新的语句,设置的是set
        updateWrapper.setSql("balance = balance - 200");
        //id为1,2,4的用户
        updateWrapper.in("id",1,2,4);

        userMapper.update(null,updateWrapper);
    }

代码演示:

java 复制代码
    @Test
    public void testLambdaQueryWrapper1(){
        //创建条件构造器
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //查询的列
        lambdaQueryWrapper.select(User::getId,User::getUsername,User::getInfo,User::getBalance);
        //查询条件:名字带"o"的
        lambdaQueryWrapper.like(User::getUsername,"o");
        //查询条件:balance >= 1000
        lambdaQueryWrapper.ge(User::getBalance,1000);
        //查询
        List<User> userList = userMapper.selectList(lambdaQueryWrapper);
        //输出
        for (User user : userList) {
            System.out.println(user);
        }
    }

8、自定义Sql

自定义SQL

我们可以利用MyBatisPlus的Wrapper来构建复杂的Where条件,然后自己定义SQL语句中剩下的部分。

需求:将id在指定范围的用户(例如1、2、4)的余额扣减指定值

代码演示:

java 复制代码
    //自定义拼接SQL
    @Test
    public void testCustomSqlSeqment(){
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(User::getId,1L,2L,4L);
        userMapper.updateBalanceByWrapper(200,lambdaQueryWrapper);
    }
java 复制代码
public interface UserMapper extends BaseMapper<User> {

    @Update("update user set balance = balance - ${amount} ${ew.customSqlSegment}")
    void updateBalanceByWrapper(@Param("amount") int amount, @Param("ew") LambdaQueryWrapper<User> queryWrapper);
}

9、Service接口-接口与类编写

Service接口

10、Service接口-案例基础

案例 基于Restful风格实现下列接口

需求:基于Restful风格实现下面的接口:

步骤:

  • 引入起步依赖
  • 定义UserController
  • 新增业务方法

特殊的业务方法,mybatisPlus中没有提供的;则可以自定义编写。

代码演示:

java 复制代码
@Api("用户接口管理")
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor       //添加注释,不用添加@Autowired
public class UserController {

    private final IUserService userService;

    @ApiOperation("新增用户")
    @PutMapping
    public void saveUser(@RequestBody UserFormDTO userFormDto){
        //将userFormDto转换为User
        User user = BeanUtil.copyProperties(userFormDto, User.class);
        userService.save(user);
    }

    @ApiOperation("删除用户")
    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable("id") Long id){
        userService.removeById(id);
    }
}

11、Service接口-扣减余额

代码演示:

java 复制代码
    /**
     * 根据id扣减余额
     * @param id 用户id
     * @param amount  扣减的金额多少
     */
    @ApiOperation("根据id扣减余额")
    @PutMapping("/{id}/deduction/{amount}")
    public void updateBalanceById(@PathVariable Long id, @PathVariable Integer amount){
        userService.deductBalanceById(id,amount);
    }

    private final UserMapper userMapper;
    @Override
    public void deductBalanceById(Long id, Integer amount) {
        //1、判断用户是否存在
        User user = this.getById(id);
        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户有问题");
        }
        //2、判断余额是否充足 ,当前用户的余额是否大于等于要扣除的金额
        if(user.getBalance() < amount){
            throw new RuntimeException("余额不足");
        }
        //3、扣减金额
        //update user set balance = balance - #{amount} where id = #{id}
        userMapper.deduceBalanceById(amount,id);
    }

    @Update("update user set balance = balance - #{amount} where id = #{id}")
    void deduceBalanceById(Integer amount, Long id);

12、IService的LambdaQuery方法应用

需求:

代码演示:

java 复制代码
    @ApiOperation("根据条件查询用户列表")
    @PostMapping("/list")
    public List<UserVO> queryList(@RequestBody UserQuery userQuery){
        String username = userQuery.getName();
        Integer status = userQuery.getStatus();
        Integer maxBalance = userQuery.getMaxBalance();
        Integer minBalance = userQuery.getMinBalance();
        List<User> userList = userService.lambdaQuery()
                .like(StrUtil.isNotBlank(username), User::getUsername, username)
                .eq(status != null, User::getStatus, status)
                .ge(minBalance != null, User::getBalance, minBalance)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .list();  //最终进行查询
        return BeanUtil.copyToList(userList, UserVO.class);
    }

13、IService的LambdaUpdate方法应用

案例IService的Lambda更新

代码演示:

java 复制代码
        //3、扣减金额
        //update user set balance = balance - #{amount} [,status = 2] where id = #{id}
        int remainBalance = user.getBalance() - amount;
        this.lambdaUpdate()
                .set(User::getBalance, remainBalance)
                .set(remainBalance == 0, User::getStatus, 2)
                .eq(User::getId, id)
                .update();

14、批量插入数据的优化

案例:IService批量新增

代码演示:

java 复制代码
    //批量新增十万条数据
    @Test
    public void testBatch(){
        //记录开始时间与结束时间
        long start = System.currentTimeMillis();
        List<User> list = new ArrayList<>(1000);
        for(int i = 1; i <= 100000; i++) {
            list.add(buildUser(i));
            if(i % 1000 == 0){
                userService.saveBatch(list);
                list.clear();
            }
        }
        //记录技术时间
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
相关推荐
JQLvopkk2 小时前
C#实现的简单的漏洞扫描器
开发语言·c#
Lyyaoo.2 小时前
【JAVA基础面经】JMM(Java内存模型)
java·开发语言
一定要AK2 小时前
SSM 整合实战—— IDEA 版
java·ide·intellij-idea
XMYX-02 小时前
05 - Go 的循环与判断:语法、用法与最佳实践
开发语言·golang
fengci.2 小时前
php反序列化(复习)(第三章)
android·开发语言·学习·php
echome8882 小时前
Python 装饰器详解:从入门到精通的 7 个实用案例
开发语言·python
子木HAPPY阳VIP2 小时前
【无标题】
java·python·mysql
砍材农夫2 小时前
spring-ai 第七模型介绍-向量模型
java·人工智能·spring
竹之却2 小时前
【Agent-阿程】openclaw v2026.4.9更新内容介绍
开发语言·php·openclaw·openclaw 更新