Spring Cloud微服务项目集成MyBatis

news2024/11/13 9:25:16

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

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

前置条件

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

1.添加依赖

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

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

<!-- 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添加分页配置

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

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 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 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层创建对应的方法

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
@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 时没有什么太大的区别,这个地方对于直接使用字段注入,博主还是更推荐以构造函数的方式注入

@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 等接口测试工具中进行接口调用,就可以对我们的数据库进行操作了:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1983258.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工具】Sublime配置Anaconda的Python环境的简单方法

1 背景 Sublime Text对Python特别友好&#xff0c;自带Python编译器。只需CtrlB就能编译并控制台输出&#xff0c;特别适合小脚本的调试。 在安装了Anaconda后&#xff0c;如何使用Sublime Text调用Anaconda的Python以及Anaconda附带的众多实用的库呢&#xff1f; 也很简单。…

一个全新低代码快速开发平台,基于Activiti7和Vue3全开放式流程,简洁且强大(附源码)

前言 在当今数字化时代&#xff0c;企业面临着快速变化的市场环境和日益复杂的业务需求。现有的软件开发模式往往存在开发周期长、成-本高、迭代速度慢等问题&#xff0c;难以满足企业对快速响应市场变化的需求。此外&#xff0c;传统的开发平台往往缺乏灵活性和扩展性&#x…

servlet内存马

参考视频&#xff1a;java内存马专题1-servlet内存马 创建javaweb项目&#xff0c;勾选servlet 我们可以将idea给的注释写法&#xff0c;改到web.xml里面 <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xm…

C++详解->函数模板+类模版

文章目录 前言1、反泛型编程2、函数模板(1)、函数模板概念(2)、函数模板定义格式(3)、函数模板实例化(4)函数模板参数匹配原则 3、类模版(1)类模板实例化(2)类模板实现Stack&#xff08;压/出栈函数&#xff09; 前言 此篇主要描述函数模板的概念、格式以及实例化等&#xff1b…

AppInventor做的APP支持安卓14吗?

目前MIT最新版本也是Android13&#xff0c;我们与mit同步更新。如果官方支持14我们会第一时间跟进。不过&#xff0c;根据用户反馈&#xff0c;蓝牙相关的好像不兼容~ 有关安卓 14 的补充&#xff1a;根据反馈&#xff0c;是支持14的&#xff0c;不过需要手动开启蓝牙权限 …

【HarmonyOS】鸿蒙应用实现截屏

【HarmonyOS】鸿蒙应用实现截屏 组件截屏 通过componentSnapshot的get函数&#xff0c;将需要截图的组件设置id传进去即可。 import { componentSnapshot } from kit.ArkUI; import { image } from kit.ImageKit;/*** 截图*/ Entry Component Preview struct SnapShotPage {S…

16.2 商品秒杀场景处理

16.2 商品秒杀场景处理 1. 秒杀业务流程解析2. 限速手段************************************************************************ 1. 秒杀业务流程解析 VIP秒杀 通过前端验证码限速 2. 限速手段 ********************************************************************…

VMware虚拟机Ubuntu20.04的安装和配置

Ubuntu20.04和VMware安装 Windows系统下Ubuntu20.04镜像源下载&#xff1a;Ubuntu20.04系统下载 VMware下载 百度网盘链接&#xff1a;https://pan.baidu.com/s/1Fp6GYPDFksEGCNZ0JikfAg 提取码: 8jhs 虚拟机配置Ubuntu 打开VMware点击创建新的虚拟机 - > 典型 - …

golang Goroutine协程和Channel管道

同步/并发/并行概念 在计算机科学和软件开发中&#xff0c;同步、并发和并行是三个重要的概念&#xff0c;它们描述了程序执行的不同方式 同步 (Synchronization) 定义&#xff1a;同步指的是一种操作或任务在进行时&#xff0c;调用者需要等待该操作或任务完成才能继续执行…

SD-WAN组网技术的九大应用场景

SD-WAN组网&#xff0c;即软件定义广域网&#xff0c;为企业提供了高效、灵活且安全的网络连接。这种新兴网络技术不仅改变了传统WAN的组网方式&#xff0c;更带来了诸多应用场景和解决方案。接下来&#xff0c;我们将深入探讨SD-WAN的主要应用场景。 1、首先&#xff0c;SD-WA…

[Bugku] MISC-CTF靶场系列系列详解⑤!!!

平台为“山东安信安全技术有限公司”自研CTF/AWD一体化平台&#xff0c;部分赛题采用动态FLAG形式&#xff0c;避免直接抄袭答案。 平台有题库、赛事预告、工具库、Writeup库等模块。 ------------------------------ 社工-进阶收集 开启环境&#xff1a; --------- 下载附件…

医院AR导航系统的实现:科技助力智慧医疗构建

在快节奏的现代医疗环境中&#xff0c;患者与医护人员对高效、便捷的院内导航需求日益增长。随着科技的飞速发展&#xff0c;传统的纸质地图已难以满足复杂多变的医疗空间需求。在此背景下&#xff0c;集成AR&#xff08;增强现实&#xff09;技术的院内导航系统应运而生&#…

3.表的操作

目录 创建表 创建表案例&#xff1a; 查看表结构 修改表 1.增加新列 2.修改列的属性 3.删除列 4.修改表名 5.修改列 删除表 创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释…

华清day7 24-8-5

文章目录 使用有名管道实现&#xff0c;一个进程用于给另一个进程发消息&#xff0c;另一个进程收到消息后&#xff0c;展示到终端上&#xff0c;并且将消息保存到文件上一份使用有名管道实现两个进程间相互通信 使用有名管道实现&#xff0c;一个进程用于给另一个进程发消息&a…

WPF学习(1)-Grid控件(网格布局)

Grid控件其实是一个窗体的默认控件&#xff0c;我们创建一个WPF应用程序后&#xff0c;其主窗体里面会有一个Grid控件。 Grid有两个非常关键的属性ColumnDefinitions和RowDefinitions&#xff0c;分别表示列的数量集合和行的数量集合。 ColumnDefinitions集合中的元素类型是…

终于有人把华为认证全部说清楚了

在信息技术领域&#xff0c;华为认证好比一座金字招牌&#xff0c;吸引着无数技术专业人士的青睐。 市场上关于华为认证的声音纷繁复杂&#xff0c;存在不少争议&#xff0c;让人难以辨别真伪。 今天就来好好讲讲华为认证&#xff0c;从头到尾都帮你盘盘清楚。 01 华为认证是…

论文辅导 | 基于二次分解和BO-BiLSTM组合模型采煤工作面瓦斯涌出量预测方法研究

辅导文章 模型描述 结合变分模态分解&#xff08;VMD&#xff09;、自适应噪声完备经验模态分解&#xff08;CEEMDAN&#xff09;、贝叶斯优化算法&#xff08;BO&#xff09;和双向长短期记忆神经网络&#xff08;BiLSTM&#xff09;这4种时间序列处理方法&#xff0c;建立了…

EKMA曲线及大气O3来源解析实践技术

目前&#xff0c;大气臭氧污染成为我国“十四五”期间亟待解决的环境问题。臭氧污染不仅对气候有重要影响&#xff0c;而且对人体健康、植物生长均有严重损害。为了高效、精准地治理区域大气臭氧污染&#xff0c;首先需要了解导致臭氧生成的主要前体物。因此&#xff0c;EKMA曲…

图的DFS

LeetCode2368 受限条件下可到达节点的数目 class Solution { public:int dfs(vector<vector<int>>& g,int x,int fa){int sum1;for(int y:g[x]){if(y!fa) sumdfs(g,y,x);}return sum;}int reachableNodes(int n, vector<vector<int>>& edges, …

C#—串口和网口之间的通信详解

C#—串口和网口之间的通信 串口转网口、网口转串口&#xff0c;就是将网口发送来的数据包发送给串口设备&#xff0c;将串口设备返回的数据转发给网口客户端。 在C#中&#xff0c;将串口数据转换为网络数据并发送到网络&#xff0c;通常涉及以下步骤&#xff1a; 1. 创建一个…