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();
    }

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud是一个用于构建分布式系统的开发工具集合。它提供了一些常用的组件和框架,包括服务注册和发现、负载均衡、断路器、分布式配置等等。在使用Spring Cloud时,有一些常见的错误和注意事项需要注意。 首先,关于Spring BootSpring Cloud版本对应错误。在使用Spring Cloud时,需要确保Spring BootSpring Cloud的版本兼容。不同版本之间可能存在依赖冲突或不兼容的情况,因此需要根据官方文档或者相关文档来选择合适的版本。 另外,Spring Cloud Config是一个用于集管理和动态获取配置的工具。它支持从Git、SVN或本地文件系统获取配置文件,并提供了服务器和客户端支持。你可以通过官方使用说明文档了解更多关于Spring Cloud Config的详细信息。 此外,关于选择使用Nacos还是Eureka作为服务注册和发现组件的问题。Nacos是一个功能更强大的服务注册和发现组件,它整合了Spring Cloud Eureka、Spring Cloud Config和Spring Cloud Bus的功能。使用Nacos可以实现配置的心动态刷新,而不需要为配置心新增集群或使用消息队列。另一方面,Eureka是Spring Cloud原生全家桶的一部分,相对来说更加稳定一些。选择使用哪个组件需要根据具体的需求和项目特点来决定。 综上所述,Spring Cloud是一个用于构建分布式系统的开发工具集合,它提供了一些常用的组件和框架。在使用Spring Cloud时,需要注意Spring BootSpring Cloud版本的兼容性,并可以使用Spring Cloud Config来动态获取配置。同时,可以选择使用Nacos或Eureka作为服务注册和发现组件,具体选择需要根据项目需求来决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值