黑马商城项目(一)MybatisPlus

一、快速入门

入门案例:

常见注解:

常见配置:

条件构造器(wrapper):

案例:

java 复制代码
    @Test
    void testUpdateByWrapper(){

        List<Long> ids= List.of(1L,2L,3L);
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<User>()
                .setSql("balance = balance - 200")
                .in("id",ids);
        //执行更新
        userMapper.update(null,userUpdateWrapper);
    }

自定义SQL:

IService接口:

父类:IService

案例:

前四个:

java 复制代码
@RestController
@RequestMapping("/users")
@Slf4j
@Api(tags = "用户管理接口")
@RequiredArgsConstructor  //只会对一些必要的提供构造函数 实现构造函数注入  如 final
public class UserController {

  //  @Autowired //不推荐
    private final IUserService userService;

    @PostMapping
    @ApiOperation("新增用户接口")
    public void saveUser(@RequestBody UserFormDTO userDTO){
        //拷贝DTO到PO
        User user=new User();
        BeanUtils.copyProperties(userDTO,user);
       // User user = BeanUtil.copyProperties(userDTO, User.class);
        userService.save(user);
    }

    @DeleteMapping("{id}")
    @ApiOperation("删除用户接口")
    public void deleteUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        userService.removeById(id);
    }

    @GetMapping("{id}")
    @ApiOperation("根据id查询用户接口")
    public UserVO getUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        //查询用户
        User user = userService.getById(id);
        //把PO拷贝到VO
        return BeanUtil.copyProperties(user,UserVO.class);
    }

    @GetMapping
    @ApiOperation("根据id批量查询用户接口")
    public List<UserVO> getUserById(@ApiParam("用户id集合") @PathVariable("ids") List<Long> ids){
        //查询用户
        List<User> users = userService.listByIds(ids);
        //把PO集合拷贝到VO集合
        return BeanUtil.copyToList(users,UserVO.class);
    }
}

第五个:

java 复制代码
    @PutMapping("/{id}/deduction/{money}")
    @ApiOperation("根据id扣减用户余额接口")
    public void deductBalance(@ApiParam("用户id") @PathVariable("id") Long id,
                              @ApiParam("扣减的金额") @PathVariable("money") Integer money){
        userService.deductBalance(id,money);
    }
java 复制代码
public interface IUserService extends IService<User>  {
    void deductBalance(Long id,Integer money);
}
java 复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

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

    }
}

baseMapper等价于UserMapper:

IService的Lambda查询案例:

案例1:
java 复制代码
    @GetMapping("/list")
    @ApiOperation("根据复杂条件查询用户接口")
    public List<UserVO> queryUsers(UserQuery query){
        //查询用户
        List<User> users = userService.queryUsers(query.getName(),query.getStatus(),query.getMaxBalance(),query.getMinBalance());
        //把PO集合拷贝到VO集合
        return BeanUtil.copyToList(users,UserVO.class);
    }
java 复制代码
public interface IUserService extends IService<User>  {
    void deductBalance(Long id,Integer money);

    List<User> queryUsers(String name,Integer status,Integer maxBalance,Integer minBalance);
}
java 复制代码
    @Override
    public List<User> queryUsers(String name, Integer status, Integer maxBalance, Integer minBalance) {

        List<User> list = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .ge(minBalance != null, User::getBalance, minBalance)
                .list();
        return list;
    }
案例2:
java 复制代码
    @Override
    @Transactional
    public void deductBalance(Long id, Integer money) {
        //查询用户
        User user = getById(id);
        //校验用户状态
        if(user == null || user.getStatus()==2){
            throw new RuntimeException("用户状态异常!");
        }
        //校验余额
        if(user.getBalance()<money){
            throw new RuntimeException("用户余额不足!");
        }
        //扣减  update user set balance = balance - ?
       // baseMapper.deductBalance(id,money);

        int remainbalacen=user.getBalance()-money;
        lambdaUpdate()
                .set(User::getBalance,remainbalacen)
                .set(remainbalacen==0,User::getStatus, 2)
                .eq(User::getId,id)
                .eq(User::getBalance,user.getBalance()) //乐观锁:检查当前的balance是否和数据库中一致
                .update(); //执行
    }
案例3:

for:

批量插入:

开启rewriteBatchedStatements=true:

代码生成器:

静态工具:

查询案例:

案例一:
java 复制代码
    @GetMapping("{id}")
    @ApiOperation("根据id查询用户接口")
    public UserVO getUserById(@ApiParam("用户id") @PathVariable("id") Long id){
        //查询用户
        UserVO userVO = userService.queryUserAndAddressById(id);
        return userVO;
    }
java 复制代码
    @Override
    public UserVO queryUserAndAddressById(Long id) {
        //查询用户
        User user = getById(id);
        if(user == null || user.getStatus()==2){
            throw new RuntimeException("用户状态异常!");
        }
        //查询地址
        List<Address> addresses = Db.lambdaQuery(Address.class)
                .eq(Address::getUserId, id)
                .list();
        //封装VO
        //转User的PO为VO
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
        //转地址VO
        if(CollUtil.isNotEmpty(addresses)){
            userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class));
        }
        return userVO;
    }
案例二:
java 复制代码
    @GetMapping
    @ApiOperation("根据id批量查询用户接口")
    public List<UserVO> getUserById(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){
        //查询用户
        List<UserVO> userVOList = userService.queryUserAndAddressByIds(ids);
        return userVOList;
    }
java 复制代码
@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> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();
        //转换地址VO
        List<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);
        //根据用户id将地址集合分组
        Map<Long, List<AddressVO>> addressMap=new HashMap<>();
        if(CollUtil.isNotEmpty(addressVOList)) {
             addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));
        }
        //转化VO返回
        List<UserVO> list=new ArrayList<>();
        for (User user : users) {
            //用户VO
            UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
            //设置地址VO
            userVO.setAddresses(addressMap.get(user.getId()));

            list.add(userVO);
        }
        return list;
    }

逻辑删除:

枚举处理器:

JSON处理器:

分页插件:

分页插件的实现其实是以拦截器的形式来完成:拦截业务SQL语句的执行,实现各种各样的功能

java 复制代码
 @Test
    void testPageQuery(){
        int pageNo=1,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();
        System.out.println("total: "+total);
        long pages = p.getPages();
        System.out.println("pages: "+pages);
        List<User> users=p.getRecords();
        users.forEach(System.out::println);
    }

简单分页查询案例:

通用分页实体:

java 复制代码
package com.itheima.mp.query;

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 io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(description = "分页查询实体")
public class PageQuery {
    @ApiModelProperty("页码")
    private Integer pageNo =1;
    @ApiModelProperty("页码")
    private Integer pageSize =5;
    @ApiModelProperty("排序字段")
    private String sortBy;
    @ApiModelProperty("是否升序")
    private Boolean isAsc = true;

    public <T> Page<T> ToMpPage(OrderItem ... orderItem){
        //构建分页条件
        Page<T> page = Page.of(pageNo,pageSize);
        //排序条件
        if (sortBy!=null){
            //条件不为空
            page.addOrder(new OrderItem(sortBy,isAsc));
        }else if(orderItem != null){
            //为空则默认按更新时间排序
            page.addOrder(orderItem);
        }
        return page;
    }

    public <T> Page<T> ToMpPageDefaultSortByUpdateTime(){
        return ToMpPage(new OrderItem("update_time",false));
    }

    public <T> Page<T> ToMpPageDefaultSortByCreateTime(){
        return ToMpPage(new OrderItem("create_time",false));
    }


}
java 复制代码
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 io.swagger.annotations.ApiModelProperty;
import lombok.Data;

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

@Data
@ApiModel(description = "分页结果")
public class PageDTO <T>{

    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总页数")
    private Long pages;
    @ApiModelProperty("集合")
    private List<T> list;


    public static <PO,VO>  PageDTO<VO> of(Page<PO> p,Class<VO> clazz){
        PageDTO<VO> dto=new PageDTO<>();
        //总条数+总页数
        dto.setTotal(p.getTotal());
        dto.setPages(p.getPages());
        //当前页数据
        List<PO> records=p.getRecords();
        if(CollUtil.isEmpty(records)){
            //为空 放一个空集合
            dto.setList(Collections.emptyList());
            return dto;
        }
        //拷贝user的VO
        List<VO> vos = BeanUtil.copyToList(records, clazz);
        dto.setList(vos);
        //返回结果
        return dto;
    }

    public static <PO,VO>  PageDTO<VO> of(Page<PO> p, Function<PO,VO> convertor){
        PageDTO<VO> dto=new PageDTO<>();
        //总条数+总页数
        dto.setTotal(p.getTotal());
        dto.setPages(p.getPages());
        //当前页数据
        List<PO> records=p.getRecords();
        if(CollUtil.isEmpty(records)){
            //为空 放一个空集合
            dto.setList(Collections.emptyList());
            return dto;
        }
        //拷贝user的VO
        List<VO> list = records.stream().map(convertor).collect(Collectors.toList());
        dto.setList(list);
        //返回结果
        return dto;
    }
}
java 复制代码
    @Override
    public PageDTO<UserVO> queryUsersPage(UserQuery query) {
        //构建查询条件
        String name=query.getName();
        Integer status=query.getStatus();
        //构建分页条件
        Page<User> page = query.ToMpPageDefaultSortByUpdateTime();

        //分页查询
        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);
        //封装VO结果
        return PageDTO.of(p,user -> {
            //拷贝基础属性
            UserVO vo=BeanUtil.copyProperties(user,UserVO.class);
            //处理特殊逻辑

            return vo;
        });
    }
相关推荐
may_一一5 分钟前
Jenkins插件下载慢解决办法
运维·jenkins
爱的叹息6 分钟前
AI应用开发平台 和 通用自动化工作流工具 的详细对比,涵盖定义、核心功能、典型工具、适用场景及优缺点分析
运维·人工智能·自动化
事业运财运爆棚37 分钟前
ssh 三级跳
服务器·web安全·ssh
Pseudo…44 分钟前
linux Shell编程之函数与数组(四)
linux·运维·服务器
杰瑞学AI1 小时前
Devops之GitOps:什么是Gitops,以及它有什么优势
运维·git·云原生·kubernetes·devops·argocd
写代码的小阿帆1 小时前
内网Windows挂载目录到公网服务器
运维·服务器
日日行不惧千万里1 小时前
远程登录一个Linux系统,如何用命令快速知道该系统属于Linux的哪个发行版,以及该服务器的各种配置参数,运行状态?
linux·运维·服务器
F36_9_1 小时前
质量问题频发,如何提升源头把控
大数据·运维
云原生应用市场2 小时前
一键私有化部署Dify,轻松搞定 AI 智能客服机器人
运维·前端·后端
刘哥测评技术zcwz6262 小时前
美客多自养号测评技术解析:如何低成本打造安全稳定的测评体系
服务器·网络·经验分享·安全