[golang 微服务] 9.go-micro + gorm实现商品微服务的分页查询

news2024/11/25 0:52:38

一.引入

上一节讲解 go-micro的负载均衡操作,go Web框(Gin,Beego)调用go-micro微服务等技术,这一节来看看 go-micro + gorm实现 商品微服务分页查询操作,go-micro微服务中使用GORM和go web框架gin、beego中使用 GORM都是一样的

二.创建goodsinfo服务端,以及启动consul服务发现

  1. 启动consul服务发现

这里以前面goodsinfo微服务为案例,参考前几节步骤,这里就不再讲解了
启动consul服务发现命令 :consul agent -dev
  1. 创建goodsinfo服务端

参考前面案例,启动服务端,测试看看是否启动启动

启动成功,下面对proto/goodsinfo.proto代码进行完善

因为需要进行grom分页查询,故完善 message GoodsModel 中代:增加需要展示的字段( 一般和数据模型中对应,见下面步骤5 ),以及message GetGoodsRequest 代码:增加请求参数 page(页码数),pageSize(页大小),如下:
syntax = "proto3";

package goodsinfo;

option go_package = "./proto;goodsinfo";

//商品相关方法
service Goodsinfo {
    //AddGoods: 定义增加商品的微服务, 这里的写法和gRPC中的写法一致
    rpc AddGoods(AddGoodsRequest) returns (AddGoodsResponse) {}
    //获取分页商品数据
    rpc GetGoods(GetGoodsRequest) returns (GetGoodsResponse) {}
}

//定义GoodsModel结构体,以便增加商品,获取商品数据时使用,该内容可以和models/goods.go保持一致
message GoodsModel{
    string title = 1;
    double price = 2;
    string content = 3;
}

//增加商品请求: 和gRPC中的写法一致
message AddGoodsRequest {
    GoodsModel parame = 1;
}

//增加商品响应:和gRPC中的写法一致
message AddGoodsResponse {
    string message = 1;
    bool success = 2;
}

//获取商品请求
message GetGoodsRequest {
    //请求参数
    int64 page = 1;
    int64 pageSize = 2;
}
//获取商品响应
message GetGoodsResponse {
    repeated GoodsModel GoodsList = 1;
}

然后运行命令:protoc --proto_path=. --micro_out=. --go_out=:. proto/goodsinfo.proto,生成.pb.micro.go,以及pb.go文件

  1. 生成conf/app.ini配置文件

该配置文件里面保存数据库,以及其他云服务相关账号等数据,具体.ini配置见:
[golang gin框架] 9.Gin GORM 中使用事务以及go-ini加载.ini配置文件章节
app_name  = app测试
# 错误级别: DEBUG,INFO,WARNING,ERROR,FATAL
log_level = DEBUG
app_mode  = production

[mysql]
ip       = 127.0.0.1
port     = 3306
user     = root
password = 123456
database = ginshop

[redis]
ip       = 127.0.0.1
port     = 9376
database = 1
  1. 创建models下面文件

要通过gorm连接数据库,就要有goods.go结构体,以及连接数据库核心代码,创建models/goods.go以及models/mysqlCore.go文件,具体可参考 [golang gin框架] 20.Gin 商城项目-商品模块功能

goods.go

package models

//商品表

type Goods struct {
    Id            int
    Title         string  //商品标题
    SubTitle      string  //附属标题
    GoodsSn       string  //商品编号
    CateId        int     //商品分类id: goods_cate.id
    ClickCount    int     //商品点击数量
    GoodsNumber   int     //商品库存
    Price         float64 //价格
    MarketPrice   float64 //商品市场价(原价)
    RelationGoods string  //关联商品id,如: 1, 23,55 ,商品id以逗号隔开
    GoodsAttr     string  //商品更多属性
    GoodsVersion  string  //商品版本
    GoodsImg      string  //图片
    GoodsGift     string  //商品赠品
    GoodsFitting  string  //商品配件
    GoodsColor    string  //颜色
    GoodsKeywords string  //SEO关键字
    GoodsDesc     string  //SEO商品描述
    GoodsContent  string  //商品详情
    IsDelete      int     //是否删除
    IsHot         int     //是否热销
    IsBest        int     //是否精品
    IsNew         int     //是否新品
    GoodsTypeId   int     //商品类型id,关联GoodsType.Id
    Sort          int     //排序
    Status        int     //状态
    AddTime       int     //添加时间
}

func (Goods) TableName() string {
    return "goods"
}

mysqlCore.go

package models

//gorm文档: https://gorm.io/zh_CN/docs/index.html
//连接数据库核心代码

import (
    "fmt"
    "gopkg.in/ini.v1"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "os"
)

//全局使用DB,就需要把DB定义成公有的
var DB *gorm.DB
var err error

//自动初始化数据库
func init() {
    //演示gopkg.in/ini.v1模块的使用
    cfg, err := ini.Load("./conf/app.ini")
    if err != nil {
        fmt.Printf("Fail to read file: %v", err)
        os.Exit(1)
    }
    ip := cfg.Section("mysql").Key("ip").String()
    port := cfg.Section("mysql").Key("port").String()
    user := cfg.Section("mysql").Key("user").String()
    password := cfg.Section("mysql").Key("password").String()
    database := cfg.Section("mysql").Key("database").String()

    // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
    //dsn := "root:123456@tcp(127.0.0.1:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"
    dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, database)
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
        //SkipDefaultTransaction : true, //禁用事物
        QueryFields: true, // 打印sql
    })
    if err != nil {
        fmt.Println(err)
    }
}
然后通过go mod tidy加载需要的包
  1. 完善handler/goods.go代码

完善方法 GetGoods(),在这里面获取请求的分页参数,构建通过GORM获取分页数据的逻辑代码
package handler

import (
    "context"
    "go-micro.dev/v4/logger"
    "goodsinfo/models"
    pb "goodsinfo/proto"
)

//微服务里面操作数据库的建议:一个微服务对应一个数据库,一个数据库里面可能只有1个或者2个表

type Goodsinfo struct{}

//增加商品
func (e *Goodsinfo) AddGoods(ctx context.Context, req *pb.AddGoodsRequest, rsp *pb.AddGoodsResponse) error {
    logger.Infof("request: %v", req)
    //书写返回的逻辑结果
    rsp.Message = "增加成功"
    rsp.Success = true
    return nil
}

//获取商品
func (e *Goodsinfo) GetGoods(ctx context.Context, req *pb.GetGoodsRequest, rsp *pb.GetGoodsResponse) error {
    //获取page和pageSize
    page := req.Page
    pageSize := req.PageSize
    //查询数据库
    goodsList := []models.Goods{}
    models.DB.Offset(int((page - 1) * pageSize)).Limit(int(pageSize)).Find(&goodsList)
    //定义一个临时的切片
    var tempList []*pb.GoodsModel
    for _, v := range goodsList {
        tempList = append(tempList, &pb.GoodsModel{
            Title:    v.Title,
            Price:    v.Price,
            Content:    v.GoodsContent,
        })
    }
    rsp.GoodsList = tempList
    return nil
}
  1. 通过gorm操作数据库

gorm操作数据库请看: [golang gin框架] 6.Gin GORM简介以及安装相关文章,这里就不再讲解
,然后 通过go run main.go命令启动微服务端

三.创建gin项目客户端代码

这里 以Gin框架为例,在Gin项目中编写访问微服务服务端的客户端分页功能,功能接 上一节
  1. 生成proto相关文件

把服务端中的proto文件复制到client/gindemo下,这样就可以使用相关.proto功能了(当然,也可以只复制goods.proto,详细的见 前面的小节
  1. 完善frontend.GoodsController.Index方法

该控制器中的index方法,就是通过访问微服务分页查询的方法
package frontend

import (
    "context"
    "gindemo/models"
    pb "gindemo/proto"
    "github.com/gin-gonic/gin"
    log "go-micro.dev/v4/logger"
    "strconv"
)

type GoodsController struct{}

//获取商品列表
func (con GoodsController) Index(c *gin.Context) {
    //第几页
    page, _ := strconv.Atoi(c.Query("page"))
    if page == 0 {
        page = 1
    }
    //页大小
    pageSize := 5

    // Create client: 这里的服务名称需要和服务端注册的名称一致
    microClient := pb.NewGoodsinfoService("goodsinfo", models.MicroClient)
    // Call service: 创建连接goodsinfo 微服务的连接,并传递参数,
    //该方法最终是请求server端handler中的gooodsinfo.go中的GetGoodsf方法
    rsp, err := microClient.GetGoods(context.Background(), &pb.GetGoodsRequest{
        Page:     int64(page),
        PageSize: int64(pageSize),
    })
    //判断是否获取商品成功: 这里会调用服务端handler/goodsinfo.go中的方法GetGoods()
    if err != nil {
        log.Fatal(err)
    }
    //记录log
    log.Info(rsp)
    //返回
    c.JSON(200, gin.H{
        "result": rsp.GoodsList,
    })
}

//添加商品
func (con GoodsController) Add(c *gin.Context) {
    // Create client
    microClient := pb.NewGoodsinfoService("goodsinfo", models.MicroClient)
    // Call service
    rsp, err := microClient.AddGoods(context.Background(), &pb.AddGoodsRequest{
        Parame: &pb.GoodsModel{
            Title:   "我是一个商品",  //这里的商品数据是模拟数据, 一般项目中是从前端获取
            Price:   12.0,
            Content: "我是一个内容",
        },
    })
    //判断是否增加成功
    if err != nil {
        log.Fatal(err)
    }
    //记录log
    log.Info(rsp)
    //返回
    c.JSON(200, gin.H{
        "message": rsp.Message,
        "success": rsp.Success,
    })
}

然后启动客户端: go run main.go

  1. 通过浏览器访问,看看是否成功

好了,通过使用go-micro + gorm在这里就实现了商品微服务的分页查询

[上一节][golang 微服务] 8.go-micro的负载均衡操作,go Web框(Gin,Beego)调用go-micro微服务

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

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

相关文章

git学习使用技巧

目录 关于版本控制 本地版本控制系统 集中化的版本控制系统 分布式版本控制系统 Git 是什么 直接记录快照,而非差异比较 近乎所有操作都是本地执行 Git 保证完整性 Git 一般只添加数据 三种状态 起步 - 初次运行 Git 前的配置 初次运行 Git 前的配置 用户…

2023年7月1日【青书学堂】考试 统计学(高起专)

2023年7月1日【青书学堂】考试 统计学(高起专) 注意:答案仅供参考 成绩:84.34 分 第1题 单选题 下列哪两个变量之间的相关程度高 ( ) A: 商品销售额和商品销售量的相关系数是0.9 B: 商品销售额与商业利润率的相关系数是0.84 C: 平均流通费用率与商业利润率的相关系数是-0…

ACL2023 | Multi-CLS BERT:传统集成的有效替代方案

进NLP群—>加入NLP交流群 在本文中,介绍了 Multi-CLS BERT,这是传统集成方法的有效替代方案。 这种基于 CLS 的预测任务的新颖方法旨在提高准确性,同时最大限度地减少计算和内存需求。 通过利用具有不同参数化和目标的多个 CLS token&…

数据结构-查找

数据结构-查找 1 知识框架2 顺序查找和折半查找2.1 顺序查找2.2折半查找2.3 分块查找 3 树型查找3.1 二叉排序树3.2 平衡二叉树3.3 B树和B树3.3.1 B树3.3.2 B树 4 散列表4.1 构造方法4.2 处理冲突的办法4.3性能分析 1 知识框架 2 顺序查找和折半查找 2.1 顺序查找 1.一般线性…

vue 基础入门

目录 vue 简介 vue 的特性 数据驱动视图 双向数据绑定 MVVM vue 的基本使用 vue 的调试工具 vue 的指令 1、内容渲染指令 2、属性绑定指令 3、事件绑定 4、双向绑定指令 v-model 5、 条件渲染指令 6 、列表渲染指令 vue过滤器 定义过滤器基本使用 私有过滤器和全…

web安全php基础_phpstudy pro安装

phpstudy pro是什么 phpstudy是一个php运行环境的集成包,用户不需要去配置运行环境,就可以使用,phpstudy不仅是一款比较好用的php调试环境工具,并且还包括了开发工具和常用手册,对于新手是有很大帮助的 windows下ph…

基于LLAMA-7B的lora中文指令微调

目录 1. 选用工程2. 中文llama-7b预训练模型下载3. 数据准备4. 开始指令微调5. 模型测试 前言: 系统:ubuntu18.04显卡:GTX3090 - 24G (惨呀,上次还是A100,现在只有3090了~) (本文旨在…

I.MX RT1170之FlexSPI(3):NOR Flash手册分析和参数配置详解

在上一节中,我们分析了FlexSPI的相关参数:LUT表格的组成和FlexSPI结构体配置,这一节就以WINBOND的W25Q256JV NOR Flash为例,看一下如何根据这个NOR Flash的数据手册配置FlexSPI接口。 文章目录 1 SDK代码2 NOR Flash配置流程2.1 时…

java.lang.IllegalArgumentException: 找到多个名为spring_web的片段。这是不合法的相对排序。

问题 java.lang.IllegalArgumentException: 找到多个名为spring_web的片段。这是不合法的相对排序。 详细问题 笔者使用ServletJSP技术框架进行项目开发,对于项目进行国际化(即i18n,实现中英文页面转换),需要引入 下…

【C语言初阶(9)】函数2

文章目录 1. 函数的嵌套调用和链式访问1.1 嵌套调用1.2 链式访问 2. 函数的声明和定义2.1 函数定义2.2 函数声明2.3 函数的实际应用 3. 函数递归3.1 什么是递归?3.2 递归使用条件3.3 递归的案例3.4 递归的优缺点 4. 递归练习题 1. 函数的嵌套调用和链式访问 函数和函…

悟道·天鹰 Aquila + 天秤 FlagEval,打造大模型能力与评测标准双标杆

为推动大模型在产业落地和技术创新,智源研究院发布“开源商用许可语言大模型系列开放评测平台” 2 大重磅成果,打造“大模型进化流水线”,持续迭代、持续开源开放。 开源商用许可语言大模型系列 悟道天鹰(Aquila) 语…

教师资格证考试(高中数学)-考什么

目录 考什么 及格线 科一-综合素质 ​编辑 科二-教育知识与能力 科三-学科知识与教学能力(数学) 题型 考什么 及格线 大家要明确3个分数: ✅卷面分数:满分为150分,也就是大家平时拿到的试卷及真题卷面分数。 ✅报告分数:…

React 之 组件化开发

本文主讲解类组件,函数组件会在后续文章中学习 一、组件化开发 1. 概念 组件化是一种分而治之的思想: 如果将一个页面中所有的处理逻辑放在一起,处理起来会变得非常复杂,不利于后续的管理以及扩展 但如果讲一个页面拆分成一个个小…

Web安全-AntSword(中国蚁剑)Webshell管理工具使用

为方便您的阅读,可点击下方蓝色字体,进行跳转↓↓↓ 01 工具下载地址02 工具介绍03 使用案例04 参考资料 01 工具下载地址 https://github.com/AntSwordProject/蚂剑工具的下载分为两个部分,一个是项目核心源码antSword,另一个是…

【算法】树形DP ①(树的直径)

文章目录 知识准备例题543. 二叉树的直径124. 二叉树中的最大路径和2246. 相邻字符不同的最长路径 相关题目练习687. 最长同值路径 https://leetcode.cn/problems/longest-univalue-path/solution/shi-pin-che-di-zhang-wo-zhi-jing-dpcong-524j4/1617. 统计子树中城市之间最大…

测试的流程,jira工具的使用

目录: 测试流程价值与体系测试计划业务架构分析思路bug基本概念bug处理流程测试总结业务架构分析工具plantuml测试流程管理jira系统-测试流程定制测试流程管理 jira 系统-Bug管理流程定制 1.测试流程价值与体系 软件测试流程 完成软件测试工作的必要步骤 测试流…

用图计算解密大脑,蚂蚁技术研究院与复旦联手启动类脑研究

大脑为什么会产生意识?我们为什么会失眠?帕金森、阿尔兹海默等神经性疾病如何有效治疗?这一切谜题的背后都绕不开脑科学。可以说脑科学问题是人类面临的基础科学问题之一,是我们解密人类自身的“终极疆域”。 我们的大脑由大约86…

第十二章线程池

文章目录 享元模式手写数据库连接池 为什么需要线程池自定义线程池自定义拒绝策略接口自定义任务队列自定义线程池 JDK中的线程池常用的线程池的类和接口的之间的关系线程池状态构造方法线程池的工作流程拒绝策略 ExecuctorsnewFixedThreadPoolnewCachedThreadPoolnewSingleThr…

【Matlab】智能优化算法_平衡优化器算法EO

【Matlab】智能优化算法_平衡优化器算法EO 1.背景介绍2.数学模型2.1 初始化和功能评估2.2 平衡池和候选者(Ceq)2.3 指数项(F)2.3 生成率(G) 3.文件结构4.伪代码5.详细代码及注释5.1 EO.m5.2 Get_Functions_…

Linux基础服务7——lamp架构

文章目录 一、基本了解二、单机部署LAMP2.1 安装httpd2.2 安装mysql2.3 安装php环境2.4 配置apache 三、分离部署四、脚本单机部署 一、基本了解 LAMP架构介绍: lamp是由LinuxApacheMysql/MariaDBPhp/Perl/Python的一组动态网站或者服务器的开源软件。LAMP指Linux&a…