SpringCloud

一、MyBatisPlus

(1)使用MyBatisPlus的基本操作步骤

①引入MybatisPlus依赖,代替Mybatis依赖

复制代码
       <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

②定义Mapper接口并继承BaseMapper

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

}

(2)常见注解

①MybatisPlus是如何获取实现CRUD的数据库表信息的?

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

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

②常用注解:

@TableName:用来指定表名。

@TableId:用来指定表中的主键字段信息

@TableField:用来指定表中的普通字段信息

③IdType(枚举)的常见类型:

AUTO:数据库自增长

ASSIGN_ID:分配ID,接口IdentifierGenerator的方法nextId来生成id,默认实现类为DefaultIdentifierGenerator雪花算法

INPUT:通过set方法自行输入

④使用@TableField的常见场景:

成员变量名与数据库字段名不一致。

成员变量名以is开头,且为布尔值。

成员变量名与数据库关键字冲突。

成员变量不是数据库字段。

(3)常见配置

复制代码
mybatis-plus:  

 type-aliases-package: com.itheima.mp.domain.po # 别名扫描包  

  mapper-locations: "classpath*:/mapper/**/*.xml" # Mapper.xml文件地址,默认值  

  configuration:     
   map-underscore-to-camel-case: true # 是否开启下划线和驼峰的映射    

   cache-enabled: false # 是否开启二级缓存  

  global-config:    

    db-config:      

     id-type: assign_id # id为雪花算法生成      

     update-strategy: not_null # 更新策略:只更新非空字段

二、核心功能

(1)条件构造器

①QueryWrapper和LambdaQueryWrapper通常用来构建select、delete、update的where条件部分。

复制代码
@Test
    void testQueryWrapper(){
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .select("id","username","info","balance")
                .like("username","o")
                .ge("balance",1000);
        //2.查询
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

②UpdateWrapper和LambdaUpdateWrapper通常只有在set语句比较特殊才使用。

复制代码
    @Test
    void testUpdateWrapper() {
        List<Long>ids=new ArrayList<Long>();
        ids.add(1L);
        ids.add(2L);
        ids.add(4L);
        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                .setSql("balance=balance-200")
                .in("id",ids);
        userMapper.update(null, wrapper);
    }

③尽量使用LambdaQueryWrapper和LambdaUpdateWrapper,避免硬编码。

复制代码
  @Test
    void testLambdaQueryWrapper(){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .select(User::getId,User::getUsername,User::getInfo,User::getBalance)
                .like(User::getUsername,"o")
                .ge(User::getBalance,1000);
        //2.查询
        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

(2)自定义SQL

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

①基于Wrapper构建where条件

复制代码
   @Test
    void testCustomSqlUpdate(){
//        1.更新条件
        List<Long>ids=new ArrayList();
        ids.add(1L);
        ids.add(2L);
        ids.add(4L);
        int amount=200;
//       2.定义条件
QueryWrapper<User>wrapper=new QueryWrapper<User>().in("id" ,ids);
//       3.调用自定义的SQL方法
        userMapper.updateBalanceByIds(wrapper,amount);

    }

②在Mapper方法参数中用Param注解声明Wrapper变量名称,必须是ew

复制代码
    void updateBalanceByIds(@Param("ew") QueryWrapper<User> wrapper,@Param("amount") int amount);

③自定义SQL,并使用Wrapper条件

复制代码
<update id="updateBalanceByIds">
        update tb_user set balance=balance-#{amount} ${ew.customSqlSegment}</update>

(3)MP的Service接口使用流程

①自定义Service接口继承IService接口

复制代码
public interface IUserService extends IService<User> {}

②自定义Service实现类,实现自定义接口并继承ServiceImpl类

复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService{}

(4)iService开发基础业务接口

复制代码
@Api(tags = "用户管理接口")
@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
    private final IUserService userService;
//    新增
    @ApiOperation("新增用户接口")
    @PostMapping
    public void save(@RequestBody UserFormDTO userDTO){
//        1.将DTO拷贝到PO
        User user = BeanUtil.copyProperties(userDTO, User.class);
//        2.新增
        userService.save(user);
    }

(5)iService开发复杂业务接口

①控制层:

复制代码
  @ApiOperation("扣减用户余额接口")
    @PutMapping("/{id}/deduction/{money}")
    public void deductBalance(
            @ApiParam("用户id") @PathVariable("id")Long id,
            @ApiParam("扣减的金额") @PathVariable("money")Integer money) {
        userService.deductBalance(id,money);
    }

②业务层:

复制代码
    void deductBalance(Long id, Integer money);



 @Override
    public void deductBalance(Long id, Integer money) {
//        1.查询用户
        User user = getById(id);
//        2.校验用户状态
        if (user==null||user.getStatus()==2){
            throw new RuntimeException("用户状态异常!");
        }
//        3.校验余额是否充足
        if(user.getBalance()<money){
            throw new RuntimeException("用户余额不足!");
        }
//        4.扣减余额
        baseMapper.deductBalance(id,money);
    }

③数据层:

复制代码
    @Update("update tb_user set balance=balance-#{money} where id=#{id}")
    void deductBalance(@Param("id") Long id, @Param("money") Integer money);

(6)IService的Lambda查询

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


    List<User> queryUsers(String name, Integer status, Integer maxBalance, Integer minBalance);


   @Override
    public List<User> queryUsers(String name, Integer status, Integer maxBalance, Integer minBalance) {
        List<User> users = lambdaQuery().like(name != null, User::getUsername, name)
                .like(status != null, User::getStatus, status)
                .ge(minBalance != null, User::getBalance, minBalance)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .list();
        return users;
    }

(7)IService的Lambda更新

复制代码
    @ApiOperation("扣减用户余额接口")
    @PutMapping("/{id}/deduction/{money}")
    public void deductBalance(
            @ApiParam("用户id") @PathVariable("id")Long id,
            @ApiParam("扣减的金额") @PathVariable("money")Integer money) {
        userService.deductBalance(id,money);
    }

    void deductBalance(Long id, Integer money);


  @Override
    @Transactional
    public void deductBalance(Long id, Integer money) {
//        1.查询用户
        User user = getById(id);
//        2.校验用户状态
        if (user==null||user.getStatus()==2){
            throw new RuntimeException("用户状态异常!");
        }
//        3.校验余额是否充足
        if(user.getBalance()<money){
            throw new RuntimeException("用户余额不足!");
        }
//        4.扣减余额
//        baseMapper.deductBalance(id,money);
        int remainBalance=user.getBalance()-money;
        lambdaUpdate().set(User::getBalance,remainBalance)
                .set(remainBalance==0,User::getStatus,2)
                .eq(User::getId,id)
                .eq(User::getBalance,user.getBalance())//乐观锁,避免多线程操作
                .update();
    }
相关推荐
开开心心就好14 分钟前
本地文件搜索工具,双击Ctrl就能呼出搜索
java·服务器·前端·支持向量机·ffmpeg·音视频·模拟退火算法
独隅18 分钟前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
ByteCoder.26 分钟前
班前十分钟的清单,按体检引导单来写
java·服务器·前端·助播虾
海的透彻28 分钟前
如何让docker容器启动时用自定义的用户
java·docker·dubbo
疯狂学习GIS32 分钟前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
GG.WinGel44 分钟前
质数数目(蓝桥杯练习题)
java·数据结构·算法·青少年编程·蓝桥杯
泡泡糖的中文规格书1 小时前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui1 小时前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu
秋天的怀念_David1 小时前
算法一千零一夜 · 第十七夜 长街点灯
java·程序人生·算法
不吃鱼的羊1 小时前
如何应对恐惧
java