Mybatis实践——Wrapper&&三表联查&&BaseMapper和Service的功能分异

一、电商场景模型设计(Lombok)

java 复制代码
// 商品表
@Data
@TableName("product")
public class Product {
    private Long id;
    private String name;
    private BigDecimal price;
    private Integer stock;
}

// 用户表
@Data
@TableName("user")
public class User {
    private Long id;
    private String username;
    private String phone;
}

// 订单表(核心业务表)
@Data
@TableName("order")
public class Order {
    private Long id;
    private Long userId;
    private Long productId;
    private Integer quantity;
    private Integer status; // 0-待支付 1-已支付
    private LocalDateTime createTime;
}

二、Wrapper条件构造器详解

1. 常用Wrapper类型

  • QueryWrapper:普通条件构造
  • LambdaQueryWrapper:Lambda表达式写法
  • UpdateWrapper:更新条件构造

2. 复杂查询示例

java 复制代码
// 查询已支付且数量大于2的订单
LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>()
    .eq(Order::getStatus, 1)
    .gt(Order::getQuantity, 2)
    .between(Order::getCreateTime, startTime, endTime)
    .orderByDesc(Order::getCreateTime);

List<Order> orders = orderMapper.selectList(wrapper);

三、三表联查实现方案

业务场景:查询订单详情(包含用户和商品信息)

1. 自定义DTO

java 复制代码
@Data
public class OrderDetailDTO {
    private String orderNo;
    private String username;
    private String productName;
    private BigDecimal totalAmount;
    private LocalDateTime createTime;
}

2. BaseMapper实现

OrderMapper.java

java 复制代码
public interface OrderMapper extends BaseMapper<Order> {
    @Select("SELECT o.order_no, u.username, p.name as product_name, " +
            "o.quantity*p.price as total_amount, o.create_time " +
            "FROM order o " +
            "LEFT JOIN user u ON o.user_id = u.id " +
            "LEFT JOIN product p ON o.product_id = p.id " +
            "WHERE o.id = #{orderId}")
    OrderDetailDTO selectOrderDetail(@Param("orderId") Long orderId);
}

3. IService实现

OrderService.java

java 复制代码
public interface OrderService extends IService<Order> {
    OrderDetailDTO getOrderDetail(Long orderId);
}

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Override
    public OrderDetailDTO getOrderDetail(Long orderId) {
        return baseMapper.selectOrderDetail(orderId);
    }
}

四、BaseMapper vs IService对比

特性 BaseMapper IService
接口层级 Mapper层基础接口 Service层扩展接口
方法类型 基础CRUD操作 批量操作+逻辑删除扩展
实现方式 XML/注解 默认实现ServiceImpl
事务控制 需手动声明 自带事务方法
典型方法 selectById saveBatch
适用场景 简单单表操作 复杂业务逻辑处理

五、自定义Mapper方法实践

统计各状态订单数量

java 复制代码
// OrderMapper接口新增
@Select("SELECT status, COUNT(*) as count FROM order GROUP BY status")
List<Map<String, Object>> countByStatus();

// 使用示例
List<Map<String, Object>> stats = orderMapper.countByStatus();

六、开发建议

  1. Wrapper使用原则

    • 简单条件使用Lambda表达式保证类型安全
    • 复杂查询优先考虑自定义SQL
    • 避免在Wrapper中硬编码字段名
  2. 联查优化建议

    • 超过3表关联建议使用视图或冗余字段
    • 注意N+1查询问题
    • 大数据量查询使用分页插件
  3. 框架选择策略

    • 简单CRUD直接使用BaseMapper
    • 批量操作优先使用IService
    • 复杂逻辑结合MyBatis原生功能实现
相关推荐
做运维的阿瑞4 小时前
Python零基础入门:30分钟掌握核心语法与实战应用
开发语言·后端·python·算法·系统架构
猿究院-陆昱泽5 小时前
Redis 五大核心数据结构知识点梳理
redis·后端·中间件
yuriy.wang5 小时前
Spring IOC源码篇五 核心方法obtainFreshBeanFactory.doLoadBeanDefinitions
java·后端·spring
咖啡教室7 小时前
程序员应该掌握的网络命令telnet、ping和curl
运维·后端
你的人类朋友8 小时前
Let‘s Encrypt 免费获取 SSL、TLS 证书的原理
后端
老葱头蒸鸡8 小时前
(14)ASP.NET Core2.2 中的日志记录
后端·asp.net
李昊哲小课8 小时前
Spring Boot 基础教程
java·大数据·spring boot·后端
码事漫谈9 小时前
C++内存越界的幽灵:为什么代码运行正常,free时却崩溃了?
后端
Swift社区9 小时前
Spring Boot 3.x + Security + OpenFeign:如何避免内部服务调用被重复拦截?
java·spring boot·后端
90后的晨仔9 小时前
Mac 上配置多个 Gitee 账号的完整教程
前端·后端