Go微服务实践之增删改查

Wesley13
• 阅读 981

从此篇文章开始,我们来陆续介绍 go-zero 开发一个项目所需要的组件和开发实践。

首先我们从 model 层开始,来说说go-zero 的API以及封装细节。首先 model 层连接的API集中在core/stores。我们先来看看操作 mysql 这类数据库,API方法我们来到 core/stores/sqlx,所以接下来用几篇的文章总体介绍一下 sqlx 的使用和设计思想。

快速使用

func main() {
  // 1
  const datasource = "user:password@/dbname"
  mysqlDB := sqlx.NewMysql(datasource)
  // 2
  um := model.NewUserModel(mysqlDB,"User")
  // 3
  ul := logic.NewUserLogic(um)
  // 4
  engine.AddRoutes(nginxApi(ul))
  engine.Start()
}

// NewUserModel,NewUserLogic 类似
func NewUserModel(conn sqlx.SqlConn, table string) *UserModel {
    return &UserModel{conn: conn, table: table}
}

// nginxApi将logic注入到handle,同时绑定路由和handler
func nginxApi(ul *logic.UserLogic) []rest.Route {
    return []rest.Route{
        {
            Method:  http.MethodGet,
            Path:    "/user/:id", // /user/54er6;
            Handler: handler.NewUserHandler(ul).GetUserById,
    }
}

总结一下:

  1. NewMysql 创建数据库连接
  2. 创建相应的 model,并将连接传入「相应的 NewModel 需要开发者编写」
  3. model 是为上一层 logic 提供服务
  4. logic 注入到 handler 中,同时 handler 与路由绑定,开启 Server

这样 model-logic-handler 最简单的结构就出来了。然后来看看在 model 层如何进行数据操作:

var userBuilderQueryRows = strings.Join(builderx.FieldNames(&User{}), ",")

type User struct {
  Avatar string `db:"avatar"` // 头像
  UserName string `db:"user_name"` // 姓名
  Sex int `db:"sex"` // 1男,2女
  MobilePhone string `db:"mobile_phone"` // 手机号
}

func (um *UserModel) Insert(user *User) (int64, error) {
  const insertsql = `insert into `+um.table+` (`+userBuilderQueryRows+`) values(?, ?, ?)`
  // insert「delete使用方式一致」
  res, err := um.conn.Exec(insertsql, user.Avatar, user.UserName, user.Sex, user.MobilePhone)
  if err != nil {
    logx.Errorf("insert User Position Model Model err, err=%v", err)
    return -1, err
  }
  id, err := res.LastInsertId()
    if err != nil {
        logx.Errorf("insert User Model to Id  parse id err,err=%v", err)
        return -1, err
    }
    return id, nil
}

func (um *UserModel) FindOne(uid int64) (*User, error) {
  var user User
  // query
  const querysql = `select `+userBuilderQueryRows+` from `+um.table+` where id=? limit 1`
    err := um.conn.QueryRow(&user, querysql, uid)
    if err != nil {
        logx.Errorf("userModile.findOne error ,id=%d,err=%s", uid, err.Error())
        if err == sqlx.ErrNotFound {
            return nil, ErrNotFound
        }
        return nil, err
    }
    return &user, nil
}
  • insert/update/deleteconn.Exec(insertsql/updatesql/deletesql, args...)
  • queryconn.QueryRow(&model, querysql, args...)

上述就是最简单的 crud 的结构:首先是构建 model ,然后操作 model 进行操作。

代码结构

文件名

作用

bulkinserter.go

批量插入

mysql.go

NewMysql

orm.go

解析,序列化model的操作

sqlconn.go

抽象crud操作的接口

tx.go

事务操作

sqlconn.go 的相互接口关系:

Go微服务实践之增删改查

可以看出:commonSqlConntxSession 是真正实现的地方。先从 API 的功能整体介绍一下:

API

参数

作用

Exec(query, args...)

sql, sql参数

insert/update/delete

Prepare(query)

sql

预编译sql

QueryRow(&model, query, args...)

model, sql, sql参数

查询一行数据同时赋值给「model」

QueryRowPartial(&model, query, args...)

model, sql, sql参数

功能同上,但是select sql可以只选取model的部分column「映衬Partial」

QueryRows/QueryRowsPartial

同上

查询多行API

Transact(func(session Session) error)

事务操作

将参数中的操作用事务包裹,开发者只需专注参数中的函数编写

总结

go-zerosqlx 屏蔽了go原生的sql操作,开发者只需关注sql编写和业务封装的数据对象,不需要像原生开发中需要手动prepare,赋值数据时Scan。

本节只是简略介绍了接口的相互关系以及开发者平时关注的API,下节将着重分析go-zero是怎么帮你赋值数据,同时在并发大的情况下,如何不让流量直接把你的数据库打死

参考

欢迎大家使用 go-zero

项目地址:

https://github.com/tal-tech/go-zero

https://gitee.com/kevwan/go-zero

如果觉得文章不错,欢迎 github 点个 star 🤝

点赞
收藏
评论区
推荐文章
Irene181 Irene181
3年前
手机自动化测试IDE-----Airtest实战篇
大家好,我是IT共享者,人称皮皮。上篇文章我们介绍了,这篇我们来讲讲Airtest实际操作方法,一起来看看吧。前言前面我们讲到了Airtest的基础知识,,,今天我们就来说说Airtest的具体操作方法吧,让我们轻松实现软件自动化,真正解放我们的双手吧。基本操作我们就是用我们说的跨平台API模块中的方法来操作我们的APK,下面来看下吧。我们先点击To
Python进阶者 Python进阶者
3年前
手机自动化测试IDE-----Airtest实战篇
大家好,我是IT共享者,人称皮皮。上篇文章我们介绍了,这篇我们来讲讲Airtest实际操作方法,一起来看看吧。前言前面我们讲到了Airtest的基础知识,,,今天我们就来说说Airtest的具体操作方法吧,让我们轻松实现软件自动化,真正解放我们的双手吧。基本操作我们就是用我们说的跨平台API模块中的方法来操作我们的APK,下面来看下吧。我们先点击Touc
kenx kenx
3年前
个人博客开发之blog-api项目统一结果集api封装
前言由于返回jsonapi格式接口,所以我们需要通过javabean封装一个统一数据返回格式,便于和前端约定交互,状态码枚举ResultCodejavapackagecn.soboys.core.ret;importlombok.Getter;/@authorkenx@version1.0@date2021/6/1715:35
Wesley13 Wesley13
3年前
go
本文有『Go开源说』第三期gozero直播内容修改整理而成,视频内容较长,拆分成上下篇,本文内容有所删减和重构。大家好,很高兴来到“GO开源说”跟大家分享开源项目背后的一些故事、设计思想以及使用方法,今天分享的项目是gozero,一个集成了各种工程实践的web和rpc框架。我是Kevin,gozero作者,我的github
Stella981 Stella981
3年前
Python之路【第十七篇】:Django【进阶篇 】(转自银角大王博客)
Model到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:创建数据库,设计表结构和字段使用MySQLdb来连接数据库,并编写数据访问层代码业务逻辑层去调用数据访问层执行数据库操作!(https://oscimg.oschina.net/oscnet/2f863fee384e3d877
Stella981 Stella981
3年前
Go orm框架gorm学习
之前咱们学习过原生的Go连接MYSQL的方法,使用Go自带的"database/sql"数据库连接api,"github.com/gosqldriver/mysql"MYSQL驱动,通过比较原生的写法去写sql和处理事务。目前开源界也有很多封装好的orm操作框架,帮我们简省一些重复的操作,提高代码可读性。gorm就是这样的一款作品,我们来学习
API 小达人 API 小达人
1年前
如何开发 RESTful、GraphQL 和 SOAP 等不同类型的 API ?
本指南将详尽探讨API开发的基本要素,包括涉及的概念、类型和协议,以及可用的最佳实践和工具。我们将从揭示API在现代软件开发中的作用开始,阐明它们如何促进不同软件组件之间的无缝通信。之后,我们将深入研究各种API类型,如RESTful、GraphQL和SOAP,并分析它们独特的特点和理想用例。接下来将讨论API设计的关键方面,重点关注API安全性、可扩展性和可维护性。我们将讨论常见的身份验证和授权机制、速率限制以及API版本控制等其他基本主题。最后,我们将介绍领先的API开发工具和框架以及文档和测试的价值,确保你具备开发高质量、高效且安全API所需的知识和资源。
liam liam
6个月前
API 设计:基础知识与最佳实践指南
在这篇深入探讨中,我们将从基础开始,逐步介绍API设计,并探讨定义卓越API的最佳实践。作为一名开发者,你可能已经熟悉了许多这些概念,但我将提供详细解释,以加深你的理解。API设计:电子商务示例让我们考虑一个像这样的电子商务平台的API,如果你不熟悉,Sh