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原生功能实现
相关推荐
秋千码途23 分钟前
小架构step系列07:查找日志配置文件
spring boot·后端·架构
蓝倾40 分钟前
京东批量获取商品SKU操作指南
前端·后端·api
开心就好20251 小时前
WebView远程调试全景指南:实战对比主流工具优劣与适配场景
后端
用户21411832636022 小时前
AI 一键搞定!中医药科普短视频制作全流程
后端
SimonKing2 小时前
告别传统读写!RandomAccessFile让你的Java程序快人一步
java·后端·程序员
蓝倾3 小时前
如何使用Python通过API接口批量抓取小红书笔记评论?
前端·后端·api
aloha_4 小时前
Flowable 引擎在启动时没办法找到AsyncListenableTaskExecutor类型的 bean
后端
保持学习ing4 小时前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
超级小忍4 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
字节跳跃者4 小时前
为什么Java已经不推荐使用Stack了?
javascript·后端