黑马商城项目(一)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;
        });
    }
相关推荐
AOwhisky18 分钟前
Python 学习笔记(第十四期)——运维自动化(下·中篇):远程文件传输——paramiko进阶篇
运维·python·学习·云原生·自动化·文件传输·paramiko
imc.111 小时前
linux基础IO
linux·运维·服务器
躺不平的理查德1 小时前
让Ubuntu 的第二块网卡 ens37 永久固定为 192.168.30.111
运维·服务器
bitbrowser1 小时前
Facebook 验证反复回到原页面,应该从哪里排查
运维·服务器·facebook
Land03292 小时前
AI网页元素变化无法自动修复?自带元素自愈的自动化解决方案
运维·人工智能·ai·自动化·rpa
fengyehongWorld2 小时前
Jenkins 安装与简单配置
运维·jenkins
云智慧AIOps社区2 小时前
2026 国产化 ITSM 替代指南:横向测评 ServiceNow、轻帆云、Jira等五款主流IT服务管理平台
运维·人工智能·运维开发·it服务管理·itsm平台
糖果店的幽灵2 小时前
langgraph的分支结构之 - 静态分支详解
java·服务器·数据库·langgraph
虹科网络安全2 小时前
艾体宝新闻|从 SQL 注入到服务器接管:CVE-2026-57517 暴露 Web 管理面板的供应链与安全编码风险
服务器·前端·sql
Urbano2 小时前
针织卫衣全流程生产工序科普:自动化替代、产能优化与设备选型实战方案
运维·自动化