SpringCloud学习(补漏)

学习文档地址

https://b11et3un53m.feishu.cn/wiki/FJAnwOhpIihMkLkOKQocdWZ7nUc

1 MybatisPlus

https://baomidou.com/reference/annotation/

1.1 使用的基本步骤

1.2 常用注解

1.3 常用配置

1.4 核心功能

1.4.1 条件构造器

用法及建议

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

1.4.2 自定义sql

xml

  <update id="updateBalanceByIds">
        update user set balance = balance - #{amount}
        ${ew.customSqlSegment}
    </update>

mapper

void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper,@Param("amount") int amount);

逻辑

List<Long> ids = List.of(1L, 3L, 4L);
        int amount = 200;
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .in("id", ids);
        // 调用自定义
        userMapper.updateBalanceByIds(wrapper, amount);
基于wrapper的多表关联查询

1.4.3 Service接口

图示

举例:

1、创建IUserService接口并且继承IService接口

2、定义UserServiceImpl实现类,实现IUserService接口,并继承ServiceImpl实现类

3、在UserServiceImpl就可以直接调用MP(MybatisPlus)相关的方法,如getById;

UserServiceImpl中对应的mapper就是baseMapper,这个就等于是注入的userMapper=>这个是ServiceImpl已经有的,可以直接拿来用

关于Autowired注入的调整

1.4.3.1 IService中的Lambda查询
 @Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
       return lambdaQuery()
                .like(name!=null, User::getUsername, name)
                .eq(status!=null, User::getStatus, status)
                .ge(minBalance!=null, User::getBalance, minBalance)
                .le(maxBalance!=null, User::getBalance, maxBalance)
                .list();
    }
1.4.3.2 IService中的Lambda更新
  lambdaUpdate()
                .set(User::getBalance, user.getBalance() - money)
                .set(user.getBalance() - money == 0,User::getStatus, 2)
                .eq(User::getId, id)
                .eq(User::getBalance, user.getBalance()) // 乐观锁:先比较再更新
                .update();
1.4.3.3 批量新增

&rewriteBatchedStatements=true

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456

1.5 扩展功能

1.5.1 MyBatisPlus插件使用

jdbc:mysql://127.0.0.1:3306/mp?useSSL=false&serverTimezone=Asia/Shanghai

1.5.2 DB静态工具–高版本的mp才有

stream流的map提取后收集

users.stream().map(User::getId).collect(Collectors.toList());

stream流的根据某个返回值分组收集

addressVOS.stream().collect(Collectors.groupingBy(AddressVO::getUserId));

@Override
    public List<UserVO> queryUserAndAddressByIds(List<Long> ids) {
        // 查用户
        List<User> users = listByIds(ids);
        if (CollUtil.isEmpty(users)) {
            return Collections.emptyList();
        }
        // 获取用户id集合
        List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());
        // 根据id集合查所有地址
        List<Address> addressList = Db.lambdaQuery(Address.class)
                .in(Address::getUserId, userIds).list();
        // 将地址转vo
        List<AddressVO> addressVOS = BeanUtil.copyToList(addressList, AddressVO.class);
        // 所有vo地址根据id分类
        Map<Long, List<AddressVO>> AddressVOMap = new HashMap<>(0);
        if(CollUtil.isNotEmpty(addressList)) {
            AddressVOMap = addressVOS.stream()
                    .collect(Collectors.groupingBy(AddressVO::getUserId));
        }

        // 转vo返回
        List<UserVO> list = new ArrayList<>(users.size());
        for (User user : users) {
            // 转vo
            UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
            userVO.setAddresses(AddressVOMap.get(user.getId()));
            list.add(userVO);
        }

        return list;
    }

1.5.3 逻辑删除

1.5.3 枚举处理器

1.5.4 JSON处理器

(1)@TableName(autoResultMap = true)

(2)

@TableField(typeHandler = JacksonTypeHandler.class)
private UserInfo info;

1.6 分页功能

1.6.1 配置(先配置,底层是拦截器拦截)

1.6.2 通用分页实体

(1)先定义一个通用实体

(2)需要查询的实体继承(1)

 @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().setColumn(query.getSortBy()).setAsc(query.getIsAsc()));// query.getSortBy(),query.getIsAsc()
        }else{
            page.addOrder(new OrderItem().setColumn("update_time").setAsc(false));
        }
        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);

        PageDTO<UserVO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(p.getTotal()); // 条数
        pageDTO.setPages(p.getPages()); // 页面
        List<User> records = p.getRecords();
        if(CollUtil.isEmpty(records)){
            pageDTO.setList(Collections.emptyList());
        }else{
            pageDTO.setList(BeanUtil.copyToList(records, UserVO.class));
        }
        return pageDTO;
    }

1.6.3 基于分页和封装条件编写通用MP分页实体

PageQuery – 泛型

package com.itheima.mp.query;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import io.swagger.annotations.ApiModel;
import lombok.Data;

@Data
@ApiModel(value = "分页查询实体")
public class PageQuery {

    private Integer pageNo = 1;
    private Integer pageSize = 5;
    private String sortBy;
    private Boolean isAsc = true;

    public <T>Page<T> toMpPage(OrderItem...items){
        Page<T> page = Page.of(pageNo, pageSize);
        if (StrUtil.isNotBlank(sortBy)){
            page.addOrder(new OrderItem().setColumn(sortBy).setAsc(isAsc));// query.getSortBy(),query.getIsAsc()
        }else if(items != null){
            page.addOrder(items);
        }
        return page;
    }
    public <T>Page<T> toMpPage(String column, boolean isAsc){
        return toMpPage(new OrderItem().setColumn(column).setAsc(isAsc));
    }

    public <T>Page<T> toMpPageDefaultSortByCreateTime(){
       return toMpPage(new OrderItem().setColumn("create_time").setAsc(isAsc));
    }
    public <T>Page<T> toMpPageDefaultSortByUpdateTime(){
        return toMpPage(new OrderItem().setColumn("update_time").setAsc(isAsc));
    }



}

PageDTO – 泛型加函数式接口

package com.itheima.mp.domain.dto;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "分页查询结果")
public class PageDTO<T> {
    private Long total;
    private Long pages;
    private List<T> list;

    // 其他对象转PageDTO对象,使用static变为静态方法,让别人创建时就可以调用
    // <PO, VO>不可以放在static之前,是因为类的泛型参数是在类实例化时确定的,而静态方法在实例化之前就可以被调用,因此无法直接引用类的泛型参数
    public static <PO, VO> PageDTO<VO> of(Page<PO> p, Class<VO> voClass){
        PageDTO<VO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(p.getTotal()); // 条数
        pageDTO.setPages(p.getPages()); // 页面
        List<PO> records = p.getRecords();
        if(CollUtil.isEmpty(records)){
            pageDTO.setList(Collections.emptyList());
        }else{
            // 变量名一样的PO到VO的转换
            pageDTO.setList(BeanUtil.copyToList(records, voClass)); // VO是没有.class的,所以要传参进来
        }
        return pageDTO;

    }
    // 变量名不一样的PO到VO的转换
    // 那就要传行为,也就是一个行为即函数,那就要传一个函数式接口了 Function
    public static <PO, VO> PageDTO<VO> of(Page<PO> p, Function<PO, VO> convertor){
        PageDTO<VO> pageDTO = new PageDTO<>();
        pageDTO.setTotal(p.getTotal()); // 条数
        pageDTO.setPages(p.getPages()); // 页面
        List<PO> records = p.getRecords();
        if(CollUtil.isEmpty(records)<
上一篇:IP协议详解:报头格式、主机定位、转发流程、网段划分与路由机制


下一篇:美国EB1A、NIW第二季度获批情况出炉,这些职业更容易获批!