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原生功能实现
相关推荐
XMYX-02 小时前
Spring Boot + Prometheus 实现应用监控(基于 Actuator 和 Micrometer)
spring boot·后端·prometheus
@yanyu6664 小时前
springboot实现查询学生
java·spring boot·后端
酷爱码4 小时前
Spring Boot项目中JSON解析库的深度解析与应用实践
spring boot·后端·json
AI小智5 小时前
Google刀刃向内,开源“深度研究Agent”:Gemini 2.5 + LangGraph 打造搜索终结者!
后端
java干货5 小时前
虚拟线程与消息队列:Spring Boot 3.5 中异步架构的演进与选择
spring boot·后端·架构
一只叫煤球的猫5 小时前
MySQL 8.0 SQL优化黑科技,面试官都不一定知道!
后端·sql·mysql
写bug写bug6 小时前
如何正确地对接口进行防御式编程
java·后端·代码规范
不超限6 小时前
Asp.net core 使用EntityFrame Work
后端·asp.net
豌豆花下猫7 小时前
Python 潮流周刊#105:Dify突破10万星、2025全栈开发的最佳实践
后端·python·ai