圖文結合手把手教你建立SpringCloud專案

旧歌發表於2024-04-25

前言

什麼是SpringCloud?

Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、閘道器、路由、鏈路追蹤等。Spring Cloud 並不是重複造輪子,而是將市面上開發得比較好的模組整合進去,進行封裝,從而減少了各模組的開發成本。也可以說Spring Cloud 提供了構建分散式系統所需的“全家桶”。

SpringCloud的優缺點:

優點:

  1. 簡化開發: 提供了豐富的元件和模式,可以快速開發分散式系統。

  2. 微服務支援: 支援微服務架構,提供了服務註冊與發現、負載均衡等功能。

  3. 分散式配置管理: 提供了分散式配置管理的能力,可以動態管理配置資訊。

  4. 監控與管理: 提供了監控、管理和調優的工具,方便運維管理和故障排查。

  5. 生態系統: 有龐大的社群支援和活躍的開發,生態系統完善。

缺點:

配置繁多且複雜,體量越大,部署治理成本越高,不利於維護,對團隊挑戰大

版本相容性:需要注意 Spring Cloud 各個元件的版本相容性,不同版本之間可能存在不相容的情況。

1.SpringCloud版本選型

確定使用SpringCloud-alibaba的版本,這裡選擇(2021.0.4.0)

2.選擇SpringCloud、SpringBoot版本

https://github.com/alibaba/spring-cloud-alibaba/wiki/版本說明  
從上邊網頁中找到 Springcloud-alibaba 2021.0.4.0 所對應的版本 ,如下圖:
這裡使用的JDK 為 11.0.18
Spring Cloud Version 對應的版本為 Spring Cloud 2021.0.4    
Spring Boot Version  對應的版本為 2.6.11

3.選好版本,開始搭建SpringCloud專案

最好的練習就是動手實踐,接下來我們要建立一個父工程,管理下邊的不同服務(不同業務放到不同的服務中去,各個服務相互呼叫)。全程使用Maven進行搭建。

一. 構建父工程

構建父工程, 點選 File -> New -> Project

二. 建立專案

選擇建立Maven專案,選擇JDK ,點選Next

三. 填寫相關名稱

填寫 Name、 GroupId、ArtifactId、Version ,填寫完成,點選Finish

四. 配置父工程pom.xml

專案的父工程已經建好了,根據我們前邊選擇的版本依賴配置父工程pom.xml

父工程不需要寫業務程式碼,可以刪除src檔案目錄和沒用的檔案。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.waves</groupId>
    <artifactId>wavesservice</artifactId>
    <version>1.0-SNAPSHOT</version>


    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>2.6.11</spring-boot.version>
        <spring-cloud.version>2021.0.4</spring-cloud.version>
        <spring-dloud-alibaba.version>2021.0.4.0</spring-dloud-alibaba.version>
        <lombok.version>1.18.10</lombok.version>
        <log4j.version>1.2.17</log4j.version>
        <mysql.version>8.0.29</mysql.version>
        <druid.version>1.2.11</druid.version>
        <mybatisPlus.spring.boot.version>3.5.3</mybatisPlus.spring.boot.version>
        <amqp.version>2.3.9.RELEASE</amqp.version>
        <junit.version>4.12</junit.version>
        <test-version>2.3.9.RELEASE</test-version>
        <jackson-version>2.11.4</jackson-version>
        <aop.version>2.4.5</aop.version>
        <commons-collections.version>3.2.2</commons-collections.version>
        <fastjson.version>2.0.12</fastjson.version>
        <pagehelper.boot.version>1.4.3</pagehelper.boot.version>
        <lombok.version>1.18.24</lombok.version>
        <hutool.core.version>5.8.20</hutool.core.version>
        <hutool.all.version>5.8.20</hutool.all.version>
        <bootstrap.version>3.0.1</bootstrap.version>
    </properties>

    <!--  因為是總專案,所以用dependencyManagement來管理,子專案不用管理版本了,可以直接引用 子模組繼承之後,提供作用:鎖定版本+子module不用寫groupId和version -->
    <dependencyManagement>
        <dependencies>

            <!-- SpringCloud 依賴 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- SpringBoot 依賴 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- SpringCloud-Alibaba 依賴 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-dloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
                <scope>runtime</scope>
            </dependency>

            <!-- druid-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!-- MybatisPlus -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatisPlus.spring.boot.version}</version>
            </dependency>

            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!--log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>

            <!--單元測試-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${test-version}</version>
            </dependency>

            <!-- Collection 增強Java集合框架 -->
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons-collections.version}</version>
            </dependency>

            <!-- JSON 解析器和生成器 -->
            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <!-- pagehelper 分頁外掛 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>

            <!-- Spring boot aop 攔截器 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
                <version>${aop.version}</version>
            </dependency>

            <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-core</artifactId>
                <version>${hutool.core.version}</version>
            </dependency>

            <!-- hutool 工具 -->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.all.version}</version>
            </dependency>

            <!--bootstrap 啟動器載入上下文-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-bootstrap</artifactId>
                <version>${bootstrap.version}</version>
            </dependency>

        </dependencies>
    </dependencyManagement>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <release>11</release>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

五. 建立子模組(服務)

完成上述步驟,我們的父工程就已經搭建完成了。接下來就可以繼續搭建其他的微服務工程了。首先搭建一個公共模組,為其他服務提供公共服務。

選中父工程,右鍵點選 New -> Module

六. 選擇Maven ,JDK

這裡與構建父工程一致,選擇Maven,選擇自己本機安裝的JDK ,點選Next

七. 填寫模組服務名稱

填寫子模組服務名稱, 點選Finish 。

到這裡我們就建立好一個common父服務了。

八. 新建 cloud-common-core模組

在common下邊新建cloud-common-core模組

和上述建立模組一樣 New -> Module

選擇Maven ,JDK

填寫模組名稱,父模組為cloud-common

將父工程(四. 配置父工程pom.xml)宣告的依賴新增到cloud-common-core的pom.xml中

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud-common</artifactId>
        <groupId>com.waves</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-common-core</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- Spring Context Support -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>

        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>

        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>

        <!-- MybatisPlus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!--log4j-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </dependency>

        <!-- Collection 增強Java集合框架 -->
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>

        <!-- JSON 解析器和生成器 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
        </dependency>

        <!-- pagehelper 分頁外掛 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>

        <!-- Spring boot aop 攔截器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-core -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
        </dependency>

        <!-- hutool 工具 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>

        <!--bootstrap 啟動器載入上下文-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

    </dependencies>

</project>

九. 增加MybatisPlusConfig配置

專案中使用的是MybatisPlus,所以在cloud-common-core增加MybatisPlusConfig配置

package com.waves.core.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author waves
 * @date 2024/4/24 17:06
 */
@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 新增分頁外掛
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 新增執行分析外掛
        interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        // 新增樂觀鎖外掛
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }

}

十. 封裝公共響應體

在cloud-common-core封裝公共響應體,

建立響應碼常量

/**
 * 返回狀態碼
 *
 * @author waves
 * @date 2024/4/24 17:06
 */
public class HttpStatus {

    /** 操作成功 */
    public static int SUCCESS = 100;

    /** 警告訊息 */
    public static int WARM = 101;

    /** 操作失敗 */
    public static int ERROR = 103;

}

建立ResponseResult

package com.waves.core.web.domain;

import com.waves.core.constant.HttpStatus;

import java.util.HashMap;
import java.util.Objects;

/**
 * @author waves
 * @date 2024/4/24 17:28
 */
public class ResponseResult extends HashMap<String, Object> {

    private static final long serialVersionUID = 1L;

    /** 狀態碼 */
    public static final String CODE_TAG = "code";

    /** 返回內容 */
    public static final String MSG_TAG = "message";

    /** 資料物件 */
    public static final String DATA_TAG = "data";

    /** 無參構造物件 初始化一個物件,表示一個空訊息 */
    public ResponseResult(){
    }

    /**
     * 初始化一個新建立的 ResponseResult 物件
     *
     * @param code 狀態碼
     * @param msg 返回內容
     */
    public ResponseResult(int code, String msg)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }

    /**
     * 初始化一個新建立的 ResponseResult 物件
     *
     * @param code 狀態碼
     * @param msg 返回內容
     * @param data 資料物件
     */
    public ResponseResult(int code, String msg, Object data)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (Objects.nonNull(data))
        {
            super.put(DATA_TAG, data);
        }
    }

    /**
     * 返回成功訊息
     *
     * @return 成功訊息
     */
    public static ResponseResult success()
    {
        return ResponseResult.success("操作成功");
    }

    /**
     * 返回成功資料
     *
     * @return 成功訊息
     */
    public static ResponseResult success(Object data)
    {
        return ResponseResult.success("操作成功", data);
    }

    /**
     * 返回成功訊息
     *
     * @param msg 返回內容
     * @return 成功訊息
     */
    public static ResponseResult success(String msg)
    {
        return ResponseResult.success(msg, null);
    }

    /**
     * 返回成功訊息
     *
     * @param msg 返回內容
     * @param data 資料物件
     * @return 成功訊息
     */
    public static ResponseResult success(String msg, Object data)
    {
        return new ResponseResult(HttpStatus.SUCCESS, msg, data);
    }

    /**
     * 返回警告訊息
     *
     * @param msg 返回內容
     * @return 警告訊息
     */
    public static ResponseResult warn(String msg)
    {
        return ResponseResult.warn(msg, null);
    }

    /**
     * 返回警告訊息
     *
     * @param msg 返回內容
     * @param data 資料物件
     * @return 警告訊息
     */
    public static ResponseResult warn(String msg, Object data)
    {
        return new ResponseResult(HttpStatus.WARN, msg, data);
    }

    /**
     * 返回錯誤訊息
     *
     * @return 錯誤訊息
     */
    public static ResponseResult error()
    {
        return ResponseResult.error("操作失敗");
    }

    /**
     * 返回錯誤訊息
     *
     * @param msg 返回內容
     * @return 錯誤訊息
     */
    public static ResponseResult error(String msg)
    {
        return ResponseResult.error(msg, null);
    }

    /**
     * 返回錯誤訊息
     *
     * @param msg 返回內容
     * @param data 資料物件
     * @return 錯誤訊息
     */
    public static ResponseResult error(String msg, Object data)
    {
        return new ResponseResult(HttpStatus.ERROR, msg, data);
    }

    /**
     * 返回錯誤訊息
     *
     * @param code 狀態碼
     * @param msg 返回內容
     * @return 錯誤訊息
     */
    public static ResponseResult error(int code, String msg)
    {
        return new ResponseResult(code, msg, null);
    }

    /**
     * 是否為成功訊息
     *
     * @return 結果
     */
    public boolean isSuccess()
    {
        return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
    }

    /**
     * 是否為警告訊息
     *
     * @return 結果
     */
    public boolean isWarn()
    {
        return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
    }

    /**
     * 是否為錯誤訊息
     *
     * @return 結果
     */
    public boolean isError()
    {
        return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
    }

    /**
     * 方便鏈式呼叫
     *
     * @param key
     * @param value
     * @return
     */
    @Override
    public ResponseResult put(String key, Object value)
    {
        super.put(key, value);
        return this;
    }
}

十一. 建立支付服務

與建立cloud-common同理建立cloud-provider-payment服務

在cloud-provider-payment模組的pom.xml中引入cloud-common-core,spring-boot-starter-web 的依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>wavesservice</artifactId>
        <groupId>com.waves</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-payment</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>

        <!-- 內嵌web伺服器(tomcat),不引入就需要引入spring-boot-starter-tomcat,否則專案會啟動後自動關閉 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 引入公共核心模組 -->
        <dependency>
            <groupId>com.waves</groupId>
            <artifactId>cloud-common-core</artifactId>
        </dependency>
    </dependencies>

</project>

十二.編寫支付程式碼和介面

1. 編寫bootstrap.yml配置檔案

因為使用的時MybatisPlus,只MybatisPlus配置,不需要配置Mybatis

# 服務埠
server:
  port: 8088
  servlet:
    # 服務訪問路徑
    context-path: /paymentservice

spring:
  application:
    # 服務名稱
    name: paymentservice

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      url: jdbc:mysql://localhost:3306/waves_cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
      username: root
      password: root

  #mybatis:
  #配置mapper的掃描,找到所有的mapper:xml對映檔案:
  #  mapper-locations: classpath:mapper/*.xml
  # 搜尋指定包別名
#  type-aliases-package: com.waves.**.domain
mybatis-plus:
  # 不支援多包, 如有需要可在註解配置 或 提升掃包等級
  # 例如 com.**.**.mapper
  mapperPackage: com.waves.**.mapper
  # 對應的 XML 檔案位置
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # 實體掃描,多個package用逗號或者分號分隔
  typeAliasesPackage: com.waves.**.domain
  # 啟動時是否檢查 MyBatis XML 檔案的存在,預設不檢查
  checkConfigLocation: false
  configuration:
    # 自動駝峰命名規則(camel case)對映
    mapUnderscoreToCamelCase: false
    # MyBatis 自動對映策略
    # NONE:不啟用 PARTIAL:只對非巢狀 resultMap 自動對映 FULL:對所有 resultMap 自動對映
    autoMappingBehavior: PARTIAL
    # MyBatis 自動對映時未知列或未知屬性處理策
    # NONE:不做處理 WARNING:列印相關警告 FAILING:丟擲異常和詳細資訊
    autoMappingUnknownColumnBehavior: NONE
    # 更詳細的日誌輸出 會有效能損耗 org.apache.ibatis.logging.stdout.StdOutImpl
    # 關閉日誌記錄 (可單純使用 p6spy 分析) org.apache.ibatis.logging.nologging.NoLoggingImpl
    # 預設日誌輸出 org.apache.ibatis.logging.slf4j.Slf4jImpl
    logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
  global-config:
    # 是否列印 Logo banner
    banner: true
    dbConfig:
      # 主鍵型別
      # AUTO 自增 NONE 空 INPUT 使用者輸入 ASSIGN_ID 雪花 ASSIGN_UUID 唯一 UUID
      idType: ASSIGN_ID
      # 邏輯已刪除值
      logicDeleteValue: 2
      # 邏輯未刪除值
      logicNotDeleteValue: 0
      # 欄位驗證策略之 insert,在 insert 的時候的欄位驗證策略
      # IGNORED 忽略 NOT_NULL 非NULL NOT_EMPTY 非空 DEFAULT 預設 NEVER 不加入 SQL
      insertStrategy: NOT_NULL
      # 欄位驗證策略之 update,在 update 的時候的欄位驗證策略
      updateStrategy: NOT_NULL
      # 欄位驗證策略之 select,在 select 的時候的欄位驗證策略既 wrapper 根據內部 entity 生成的 where 條件
      where-strategy: NOT_NULL


# 日誌配置
logging:
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS
  level:
    com.waves: debug
    org.springframework: warn

2.編寫Payment支付服務的啟動類

package com.waves.payment;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

/**
 * @author waves
 * @date 2024/4/24 22:39
 */
@SpringBootApplication
@MapperScan("${mybatis-plus.mapperPackage}") // 配置要掃描的包
//@ComponentScan(basePackages = {"com.waves.core", "com.waves.payment"}) //配置要掃描的元件和配置
@ComponentScan("com.waves")
public class PaymentApplication {
    public static void main(String[] args) {
        SpringApplication.run(PaymentApplication.class,args);
        System.out.println("支付服務啟動成功 (^-^)V。。。。");
    }
}

3.建表

#建立sys_payment_type 支付型別表
CREATE TABLE `sys_payment_type`  (
  `pay_id` bigint(20) NOT NULL COMMENT '支付型別主鍵',
  `pay_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '支付型別名稱',
  `remark` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '備註',
  PRIMARY KEY (`pay_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;

#插入資料
INSERT INTO `sys_payment_type` (`pay_id`, `pay_name`, `remark`) VALUES (1, '支付寶', '使用支付寶進行支付');
INSERT INTO `sys_payment_type` (`pay_id`, `pay_name`, `remark`) VALUES (2, '微信支付', '使用微信支付進行支付');
INSERT INTO `sys_payment_type` (`pay_id`, `pay_name`, `remark`) VALUES (3, '銀行轉賬', '透過銀行轉賬進行支付');

4.編寫介面

  1. 實體類

  在cloud-common-core 中編寫 payment實體類

package com.waves.core.web.domain.entities;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * 支付型別實體 如果進行網路通訊 一定要實現序列化
 * @author waves
 * @date 2024/4/25 9:44
 */
@Data //: 該註解會自動生成類的 getter、setter、equals、hashCode 和 toString 方法,從而減少樣板程式碼。
@NoArgsConstructor //: 自動生成一個無參構造方法,用於建立物件例項時不需要傳入任何引數。
@AllArgsConstructor //: 自動生成一個包含所有引數的構造方法,用於建立物件例項時需要傳入所有欄位的值。
@Accessors(chain = true) //: 啟用方法鏈(method chaining),允許在物件例項上連續呼叫多個 setter 方法,可以使程式碼更加簡潔。
@TableName("sys_payment_type") //:對應資料庫表的名稱
public class SysPaymentType implements Serializable {

    /**
     * 支付Id
     * TableId 加在表主鍵上面 value 對應 欄位名 ,type 為資料庫ID自增
     */
    @TableId(value = "pay_id", type = IdType.AUTO)
    private Long payId;

    /**
     * 支付型別名稱
     * TableField value 對應 欄位名 
     */
    @TableField(value = "pay_name")
    private String payName;

    /**
     * 備註
     */
    @TableField(value = "remark")
    private String remark;

}

mapper

SysPaymentMapper繼承MybatisPlus 的 BaseMapper

package com.waves.payment.web.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.waves.core.web.domain.entities.SysPaymentType;

/**
 * @author waves
 * @date 2024/4/25 9:44
 */
@Mapper
public interface SysPaymentMapper extends BaseMapper<SysPaymentType> {
}
Service

ISysPaymentService 繼承MybatisPlus 的 IService

package com.waves.payment.web.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.waves.core.web.domain.entities.SysPaymentType;

/**
 * @author waves
 * @date 2024/4/25 9:44
 */
@Service
public interface ISysPaymentService extends IService<SysPaymentType> {
}
ServiceImpl

SysPaymentServiceImpl繼承 繼承MybatisPlus 的 IService 的 ServiceImpl 同時實現 我們自己的ISysPaymentService

package com.waves.payment.web.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.waves.core.web.domain.entities.SysPaymentType;
import com.waves.payment.web.mapper.SysPaymentMapper;
import com.waves.payment.web.service.ISysPaymentService;
import org.springframework.stereotype.Service;

/**
 * @author waves
 * @date 2024/4/25 9:44
 */
@Service
public class SysPaymentServiceImpl extends ServiceImpl<SysPaymentMapper,SysPaymentType> implements ISysPaymentService {
}
Controller
package com.waves.payment.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.waves.core.web.domain.entities.SysPaymentType;
import com.waves.payment.web.service.ISysPaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * @author waves
 * @date 2024/4/25 9:44
 */
@RestController
@RequestMapping("/payment")
public class SysPaymentController {

    @Autowired
    private ISysPaymentService paymentService;

    /**
     * 分頁查詢PaymentType,條件 payId ,payName
     * @return
     */
    @GetMapping("/listPage/{pageNum}/{pageSize}")
    public IPage<SysPaymentType> list(@PathVariable("pageNum") Integer pageNum
            , @PathVariable("pageSize") Integer pageSize
            , SysPaymentType paymentType){

        QueryWrapper<SysPaymentType> queryWrapper = new QueryWrapper<>();
        //判斷支付型別名稱 不為空,則進行條件查詢
        queryWrapper.lambda()
                .like(Objects.nonNull(paymentType.getPayName()),SysPaymentType::getPayName,paymentType.getPayName())
                .eq(Objects.nonNull(paymentType.getPayId()),SysPaymentType::getPayId,paymentType.getPayId());
        return paymentService.page(new Page<>(pageNum,pageSize),queryWrapper);

    }

    /**
     * 根據支付Id查詢支付型別
     * @param payId
     * @return
     */
    @GetMapping("/findById/{payId}")
    public SysPaymentType findById(@PathVariable("payId") Long payId){
        return paymentService.getById(payId);
    }

}

測試介面

  1. 測試獲取列表介面

    http://localhost:8088/paymentservice/payment/listPage/1/10

    返回資料如下圖

測試根據ID查詢

http://localhost:8088/paymentservice/payment/findById/1

返回資料如下圖

到這裡我們的專案就搭建完成了,下為專案結構圖

相關文章