一、快速入门
入门案例:


常见注解:


常见配置:
条件构造器(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;
});
}