Go调用MySql数据库的简单示例之三业务代码

本示例分为三部分组成:项目创建、基础框架、业务代码。
业务代码目录和文件包括model、sevice、handler等;并在最后启动服务、验证服务。
数据库表结构
user table
user info
model / uers.go
user表的ORM模型

package model

import (
    "encoding/json"
    "errors"
    "gotest/common/errno"
    "log"
)

// model
type User struct {
    ID string `json:"id"`
    UserName string `json:"name"`
    Age string `json:"age"`
    Password string `json:"password"`
}

// 通过用户名查询用户数据
func (user *User)SelectUserByName(name string)error {
    stmt,err := ConstDb.Prepare("SELECT id,name,age,password FROM user WHERE name=?")
    if err != nil {
       return err
    }
    defer stmt.Close()
    rows, err := stmt.Query(name)
    // 关闭rows释放持有的数据库链接
    defer rows.Close()
    if err != nil {
        return err
    }
    // 数据处理
    for rows.Next() {
        rows.Scan( &user.ID, &user.UserName, &user.Age, &user.Password)
    }
    if err := rows.Err(); err != nil {
        return err
    }
    return nil
}
 
// Validate the fields.
func (user *User) Validate() error {
    if user.UserName =="" || user.Password ==""{
        return errors.New(errno.ErrValidation.Message)
    }
    return nil
}

func (user *User) Create() (int64,error)  {
    id,err := Insert("INSERT INTO user(name,age,password) values (?,?,?)", user.UserName, user.Age, user.Password)
    if err != nil {
        return 0,err
    }
 
    return id,nil
}

model.go
通用数据库访问模型

package model
 
import (
    "fmt"
    "log"
)

// Insert 插入操作
func Insert(sql string,args... interface{})(int64,error) {
    // SQL语句预处理
    stmt, err := ConstDb.Prepare(sql)
    // defer语句在方法返回“时”触发
    defer stmt.Close()
    if err != nil{
        return 0,err
    }
    result, err := stmt.Exec(args...)
    if err != nil{
        return 0,err
    }
    id, err := result.LastInsertId()
    if err != nil{
        return 0,err
    }
    fmt.Printf("插入成功,ID为%v\n",id)
    return id,nil
}
 
//  Update or Delete 更新或删除操作
func UpdateOrDelete(sql string,args... interface{})  {
    stmt, err := ConstDb.Prepare(sql)
    defer stmt.Close()
    CheckErr(err, "SQL语句预处理出现错误")
    result, err := stmt.Exec(args...)
    CheckErr(err, "参数出现错误")
    num, err := result.RowsAffected()
    CheckErr(err,"执行失败")
    fmt.Printf("执行成功,影响行数为%d\n",num)
}
 
// CheckErr 用来校验error对象是否为空
func CheckErr(err error,msg string)  {
    if nil != err {
        log.Panicln(msg,err)
    }
}

router.go
完整内容参见上篇

// 新增用户数据
router.POST("/addUser", service.AddUser)
// 通过用户名查询用户数据
router.POST("/selectUser", service.SelectUserByName)

middleware.go
router中间件

package middleware
 
import (
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)
 
// NoCache is a middleware function that appends headers
// to prevent the client from caching the HTTP response.
func NoCache(c *gin.Context) {
    c.Header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate, value")
    c.Header("Expires", "Thu, 01 Jan 1970 00:00:00 GMT")
    c.Header("Last-Modified", time.Now().UTC().Format(http.TimeFormat))
    c.Next()
}
 
// Options is a middleware function that appends headers
// for options requests and aborts then exits the middleware
// chain and ends the request.
func Options(c *gin.Context) {
    if c.Request.Method != "OPTIONS" {
        c.Next()
    } else {
        c.Header("Access-Control-Allow-Origin", "*")
        c.Header("Access-Control-Allow-Methods", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
        c.Header("Access-Control-Allow-Headers", "authorization, origin, content-type, accept")
        c.Header("Allow", "HEAD,GET,POST,PUT,PATCH,DELETE,OPTIONS")
        c.Header("Content-Type", "application/json")
        c.AbortWithStatus(200)
    }
}
 
// Secure is a middleware function that appends security
// and resource access headers.
func Secure(c *gin.Context) {
    c.Header("Access-Control-Allow-Origin", "*")
    c.Header("X-Frame-Options", "DENY")
    c.Header("X-Content-Type-Options", "nosniff")
    c.Header("X-XSS-Protection", "1; mode=block")
    if c.Request.TLS != nil {
        c.Header("Strict-Transport-Security", "max-age=31536000")
    }
}

service.go
服务接口

package service
 
import (
    "fmt"
    "github.com/gin-gonic/gin"
    "gotest/common/errno"
    "gotest/handler"
    "gotest/model"
)

// 新增用户数据
func AddUser(c *gin.Context)  {
    var r model.User
    if err := c.Bind(&r); err != nil {
        handler.SendResponse(c, errno.ErrBind, nil)
        return
    }
    u := model.User{
        UserName: r.UserName,
        Age: r.Age,
        Password: r.Password,
    }
    // Validate the data
    if err := u.Validate(); err != nil {
        handler.SendResponse(c, errno.ErrValidation, nil)
        return
    }
    // Insert the user to the database
    if id,err := u.Create(); err != nil {
        handler.SendResponse(c, errno.ErrDatabase, nil)
        return
    }else{
        // 赋值
        u.ID = id
    }
    // Show the user information
    handler.SendResponse(c, nil, u)
}
 
// SelectUserByName 通过用户名查询用户数据
func SelectUserByName(c *gin.Context)  {
    name := c.Query("user_name")
    if name == ""{
        handler.SendResponse(c, errno.ErrValidation, nil)
        return
    }
    var  user model.User
    if err := user.SelectUserByName(name);nil != err {
        fmt.Println(err)
        handler.SendResponse(c, errno.ErrUserNotFound, nil)
        return
    }
    // Validate the data.
    if err := user.Validate(); err != nil {
        handler.SendResponse(c, errno.ErrUserNotFound, nil)
        return
    }

    handler.SendResponse(c, nil, user)
}
 

handlers.go

package handler
 
import (
    "github.com/gin-gonic/gin"
    "gotest/common/errno"
    "net/http"
)
 
type Response struct {
    Code    int         `json:"code"`
    Message string      `json:"message"`
    Data    interface{} `json:"data"`
}
 
func SendResponse(c *gin.Context, err error, data interface{}) {
    code, message := errno.DecodeErr(err)
 
    // 网络链路层正常返回 always return http.StatusOK
    c.JSON(http.StatusOK, Response{
        Code:    code,
        Message: message,
        Data:    data,
    })
}

common / error / code.go

package errno
 
var (
    // Common errors
    OK                  = &Errno{Code: 0, Message: "OK"}
    InternalServerError = &Errno{Code: 5001, Message: "Internal server error"}
    ErrBind             = &Errno{Code: 5002, Message: "Error occurred while binding the request body to the struct."}
 
    ErrValidation = &Errno{Code: 1001, Message: "Validation failed."}
    ErrDatabase   = &Errno{Code: 1002, Message: "Database error."}
 
    // user errors
    ErrUserNotFound      = &Errno{Code: 9101, Message: "The user was not found."}
    ErrPasswordIncorrect = &Errno{Code: 9102, Message: "The password was incorrect."}
)

common / error / error.go

package errno
 
import "fmt"
 
type Errno struct {
    Code    int
    Message string
}
 
func (err Errno) Error() string {
    return err.Message
}
 
// Err represents an error
type Err struct {
    Code    int
    Message string
    Err     error
}
 
func New(errno *Errno, err error) *Err {
    return &Err{Code: errno.Code, Message: errno.Message, Err: err}
}
 
func (err *Err) Add(message string) error {
    err.Message += " " + message
    return err
}
 
func (err *Err) Addf(format string, args ...interface{}) error {
    err.Message += " " + fmt.Sprintf(format, args...)
    return err
}
 
func (err *Err) Error() string {
    return fmt.Sprintf("Err - code: %d, message: %s, error: %s", err.Code, err.Message, err.Err)
}
 
func IsErrUserNotFound(err error) bool {
    code, _ := DecodeErr(err)
    return code == ErrUserNotFound.Code
}
 
func DecodeErr(err error) (int, string) {
    if err == nil {
        return OK.Code, OK.Message
    }
 
    switch typed := err.(type) {
    case *Err:
        return typed.Code, typed.Message
    case *Errno:
        return typed.Code, typed.Message
    default:
    }
 
    return InternalServerError.Code, err.Error()
}

启动服务器
go build
验证测试
使用postman发起请求,查询用户
postman

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果您想要从数据库中读取文件,可以使用以下步骤: 1. 连接数据库使用 Go 语言提供的数据库驱动程序连接到您的数据库。 2. 查询文件:编写 SQL 查询语句,以从数据库中检索文件。 3. 读取文件:使用 Go 语言的文件操作函数(例如 os.Open())打开查询结果中的文件,并将其读入内存中。 4. 处理文件:您可以使用内存中的文件进行任何必要的处理,例如解码、解密或解压缩。 5. 关闭文件:在完成对文件的处理后,使用 Go 语言的文件操作函数(例如 defer file.Close())关闭文件。 6. 关闭数据库连接:在完成对文件的处理后,使用 Go 语言提供的数据库驱动程序函数关闭数据库连接。 以下是一个伪代码示例,演示了如何连接到 MySQL 数据库,查询文件,并将其读入内存中: ``` import ( "database/sql" _ "github.com/go-sql-driver/mysql" "os" ) func main() { db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/database") if err != nil { panic(err.Error()) } defer db.Close() rows, err := db.Query("SELECT file_data FROM files WHERE id=?", 123) if err != nil { panic(err.Error()) } defer rows.Close() var fileData []byte for rows.Next() { err := rows.Scan(&fileData) if err != nil { panic(err.Error()) } } file, err := os.Create("file.txt") if err != nil { panic(err.Error()) } defer file.Close() _, err = file.Write(fileData) if err != nil { panic(err.Error()) } } ``` 请注意,此代码示例仅用于演示目的,您需要根据自己的实际情况进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值