黑马商城项目(一)MybatisPlus
一、快速入门
入门案例:


常见注解:
常见配置:
条件构造器(wrapper):
案例:
@Testvoid 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
案例:
前四个:
@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到POUser 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拷贝到VOreturn 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);}
}
第五个:
@PutMapping("/{id}/deduction/{money}")@ApiOperation("根据id扣减用户余额接口")public void deductBalance(@ApiParam("用户id") @PathVariable("id") Long id,@ApiParam("扣减的金额") @PathVariable("money") Integer money){userService.deductBalance(id,money);}
public interface IUserService extends IService<User> {void deductBalance(Long id,Integer money);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic 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:
@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);}
public interface IUserService extends IService<User> {void deductBalance(Long id,Integer money);List<User> queryUsers(String name,Integer status,Integer maxBalance,Integer minBalance);
}
@Overridepublic 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:
@Override@Transactionalpublic 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:
代码生成器:
静态工具:
查询案例:
案例一:
@GetMapping("{id}")@ApiOperation("根据id查询用户接口")public UserVO getUserById(@ApiParam("用户id") @PathVariable("id") Long id){//查询用户UserVO userVO = userService.queryUserAndAddressById(id);return userVO;}
@Overridepublic 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为VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//转地址VOif(CollUtil.isNotEmpty(addresses)){userVO.setAddresses(BeanUtil.copyToList(addresses, AddressVO.class));}return userVO;}
案例二:
@GetMapping@ApiOperation("根据id批量查询用户接口")public List<UserVO> getUserById(@ApiParam("用户id集合") @RequestParam("ids") List<Long> ids){//查询用户List<UserVO> userVOList = userService.queryUserAndAddressByIds(ids);return userVOList;}
@Overridepublic 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();//转换地址VOList<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) {//用户VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);//设置地址VOuserVO.setAddresses(addressMap.get(user.getId()));list.add(userVO);}return list;}
逻辑删除:
枚举处理器:
JSON处理器:
分页插件:
分页插件的实现其实是以拦截器的形式来完成:拦截业务SQL语句的执行,实现各种各样的功能
@Testvoid 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);}
简单分页查询案例:
通用分页实体:
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));}}
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的VOList<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的VOList<VO> list = records.stream().map(convertor).collect(Collectors.toList());dto.setList(list);//返回结果return dto;}
}
@Overridepublic 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;});}