Spring Cloud微服务项目集成MyBatis

在现代软件开发中,微服务架构已经成为一种流行的解决方案,它能够将应用程序拆分成多个小的、独立的服务。每个服务负责一个特定的业务功能,并可以独立部署和扩展。Spring Cloud 是一个提供各种工具和框架以支持微服务开发的开源框架,而 MyBatis 是一个流行的持久层框架,用于简化数据库操作。

Spring CloudMyBatis 结合使用,可以使你的微服务项目在处理数据持久化方面更加高效和灵活。本文将介绍如何在 Spring Cloud 微服务项目中集成 MyBatis,并提供一个基本的实现步骤。

前置条件

在开始本文前,博主希望你已经搭建了一个微服务项目:Spring Cloud微服务项目搭建

1.添加依赖

在子模块pom.xml配置文件中添加 MyBatisMyBatis-Plus依赖:

MyBatis-PlusMyBatis 的基础上,对单表操作 进行了一个加强,MyBatis 的官方也说了,希望开发者将 MyBatisMyBatis-Plus 二者相结合起来使用

XML 复制代码
<!-- MyBatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.16</version>
</dependency>

<!-- Page helper MyBatis 分页插件 -->
    <dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>6.1.0</version>
</dependency>

<!-- MyBatis Plus Plugin -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.7</version>
</dependency>

2.为MyBatis-Plus添加分页配置

java 复制代码
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }
}

3.创建Mapper层

这里结合MyBatis-Plus使用,故继承了BaseMapper

java 复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import model.order.OrderInfoModel;
import org.apache.ibatis.annotations.*;

@Mapper
public interface OrderMapper extends BaseMapper<OrderInfoModel> {

}

4.创建Mapper.xml映射文件

XML 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="order.mapper.OrderMapper">
    <!-- 博主这里直接在resources.mapper 目录下创建 OrderMapper.xml -->
    <!-- 将本段代码全部复制到OrderMapper.xml文件中后,在namespace上绑定对应的Mapper即可 -->
</mapper>

5.编写XML查询

XML 复制代码
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="order.mapper.OrderMapper">
    <!--  订单信息 分页查询  -->
    <select id="selectOrderPage" resultMap="UserOrderResultMap">
        SELECT * FROM order_info
        <if test="userId != null">
            WHERE user_id = #{userId}
        </if>
    </select>

    <!--  根据 userId 查询用户信息  -->
    <select id="selectUserListById" resultType="model.user.UserInfoModel">
        SELECT * FROM user_info WHERE user_id = #{userId}
    </select>

    <!--  订单查询结果映射  -->
    <resultMap id="UserOrderResultMap" type="model.order.OrderInfoModel">
        <result property="userId" column="user_id" />
        <collection property="userInfo" column="user_id" select="selectUserListById" />
    </resultMap>
</mapper>

6.在Mapper层创建对应的方法

java 复制代码
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import model.order.OrderInfoModel;
import org.apache.ibatis.annotations.*;

@Mapper
public interface OrderMapper extends BaseMapper<OrderInfoModel> {

    /**
     * 订单列表分页查询
     */
    Page<OrderInfoModel> selectOrderPage(Page<OrderInfoModel> pageModel, String userId);
}

7.创建Service层

博主这里直接继承ServiceImpl ,查询业务直接在Service中编写:

  • 新增删除 业务直接用 MyBatis-Plus提供的方法
  • 查询业务这里,如果只是单表简单的查询的话,建议使用 MyBatis-Plus 提供的方法,对于复杂业务的查询,还是老老实实的写在XML
java 复制代码
@Service
public class OrderService extends ServiceImpl<OrderMapper, OrderInfoModel> {

    /**
     * 新增订单
     */
    public int createOrder(String jwt, OrderInfoModel model) {
        /* 解析 Token */
        Jws<Claims> claims = JwtUtil.parseJWT(jwt);
        String userId = claims.getPayload().get("USER_ID").toString();

        /* 绑定订单创建人 */
        model.setUserId(userId);

        /* 生成 订单ID */
        String orderId = ToolsUtil.createdID("T-", 14);
        model.setOrderId(orderId);

        return baseMapper.insert(model);
    }

    /**
     * 删除订单
     */
    public int deleteOrder(String orderId) {
        return baseMapper.deleteById(orderId);
    }

    /**
     * 订单列表 分页查询
     */
    public Page<OrderInfoModel> selectOrderPage(int page, int size, OrderInfoModel model) {
        Page<OrderInfoModel> pageModel = new Page<>(page, size);
        if ((model.getUserId() != null) && (!model.getUserId().isEmpty())) {
            return baseMapper.selectOrderPage(pageModel, model.getUserId());
        }
        return baseMapper.selectOrderPage(pageModel, null);
    }

}

8.创建Controller层

对于 Controller 层来说,跟直接使用 MyBatis时没有什么太大的区别,这个地方对于直接使用字段注入,博主还是更推荐以构造函数的方式注入

java 复制代码
@RestController
@RequestMapping("/api/auth/order")
@Tag(name = "订单管理")
public class OrderController {

    private final OrderService orderService;

    @Autowired
    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping("/create")
    @Operation(summary = "新增【订单】", parameters = {
            @Parameter(
                    name = "Authorization",
                    description = "TOKEN",
                    in = ParameterIn.HEADER,
                    required = true,
                    schema = @Schema(type = "string")
            )
    })
    public int createOrder(@RequestHeader("Authorization") String token, @RequestBody OrderInfoModel model) {
        String jwt = token.substring(14);
        return orderService.createOrder(jwt, model);
    }

    @DeleteMapping("/delete/{orderId}")
    @Operation(summary = "删除【订单】", parameters = {
            @Parameter(
                    name = "Authorization",
                    description = "TOKEN",
                    in = ParameterIn.HEADER,
                    required = true,
                    schema = @Schema(type = "string")
            )
    })
    public int deleteOrder(@PathVariable("orderId") String orderId) {
        return orderService.deleteOrder(orderId);
    }

    @PostMapping("/selectOrderPage")
    @Operation(summary = "【订单】信息分页查询", parameters = {
            @Parameter(
                    name = "Authorization",
                    description = "TOKEN",
                    in = ParameterIn.HEADER,
                    required = true,
                    schema = @Schema(type = "string")
            )
    })
    public Page<OrderInfoModel> selectOrderPage(@RequestParam(defaultValue = "1") int page,
                                                @RequestParam(defaultValue = "10") int size,
                                                @RequestBody OrderInfoModel orderInfoModel) {
        return orderService.selectOrderPage(page, size, orderInfoModel);
    }
}

9.接口测试

最后,在Swagger文档中,或者ApiFox / PostMan 等接口测试工具中进行接口调用,就可以对我们的数据库进行操作了:

相关推荐
2601_962218474 小时前
万象生鲜系统区块链溯源技术帮助生鲜企业搭建食品安全数字化体系
大数据·运维·微服务·云原生·架构
2601_962055975 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
2601_961901706 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
Lost of 程序猿6 小时前
ASP.NET Core API 幂等性设计深度实战:从一次重复申领事故说起
后端·asp.net
QQ_21696290967 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
郑州光合科技余经理8 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
IT_陈寒9 小时前
Vue的嵌套组件竟然吃掉了我的事件?
前端·人工智能·后端
专注仿真9 小时前
Spring AI 实现智能对话系统项目指南
数据结构·spring·机器学习
大辉狼_音频架构10 小时前
进阶:从源码编译 SOF 固件与 topology
后端
大辉狼_音频架构10 小时前
上板:让 SOF 在 FRDM-i.MX8MP 上跑起来
后端