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原生功能实现
相关推荐
草捏子3 小时前
从CPU原理看:为什么你的代码会让CPU"原地爆炸"?
后端·cpu
嘟嘟MD3 小时前
程序员副业 | 2025年3月复盘
后端·创业
胡图蛋.4 小时前
Spring Boot 支持哪些日志框架?推荐和默认的日志框架是哪个?
java·spring boot·后端
无责任此方_修行中4 小时前
关于 Node.js 原生支持 TypeScript 的总结
后端·typescript·node.js
吃海鲜的骆驼4 小时前
SpringBoot详细教程(持续更新中...)
java·spring boot·后端
迷雾骑士5 小时前
SpringBoot中WebMvcConfigurer注册多个拦截器(addInterceptors)时的顺序问题(二)
java·spring boot·后端·interceptor
uhakadotcom5 小时前
Thrift2: HBase 多语言访问的利器
后端·面试·github
Asthenia04125 小时前
Java 类加载规则深度解析:从双亲委派到 JDBC 与 Tomcat 的突破
后端
方圆想当图灵6 小时前
从 Java 到 Go:面向对象的巨人与云原生的轻骑兵
后端·代码规范
Moment6 小时前
一份没有项目展示的简历,是怎样在面试里输掉的?开源项目或许是你的救命稻草 😭😭😭
前端·后端·面试