golang mysql demo

Go操作Mysql数据库

使用Go操作MySQL等数据库,一般有两种方式:一是使用database/sql接口,直接在代码里硬编码sql语句;二是使用gorm,即对象关系映射的方式在代码里抽象的操作数据库。一般推荐使用第二种方式。

使用database/sql接口

Go没有内置的驱动支持任何数据库,但是Go定义了database/sql接口,用户可以基于驱动接口开发相应数据库的驱动。但缺点是,直接用 github.com/go-sql-driver/mysql 访问数据库都是直接写 sql,取出结果然后自己拼成对象,使用上面不是很方便,可读性也不好。

下载包

go get github.com/go-sql-driver/mysql

源码如下:

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "time"
)

//数据库连接信息
const (
    USERNAME = "root"
    PASSWORD = "123qwe"
    NETWORK  = "tcp"
    SERVER   = "127.0.0.1"
    PORT     = 3306
    DATABASE = "test"
)

//user表结构体定义
type User struct {
    Id         int    `json:"id" form:"id"`
    Username   string `json:"username" form:"username"`
    Password   string `json:"password" form:"password"`
    Status     int    `json:"status" form:"status"` // 0 正常状态, 1删除
    Createtime int64  `json:"createtime" form:"createtime"`
}

func CreateTable(DB *sql.DB) {
    sql := `CREATE TABLE IF NOT EXISTS users(
        id INT(4) PRIMARY KEY AUTO_INCREMENT NOT NULL,
        username VARCHAR(64),
        password VARCHAR(64),
        status INT(4),
        createtime INT(10)
    ); `

    if _, err := DB.Exec(sql); err != nil {
        fmt.Println("create table failed:", err)
        return
    }
    fmt.Println("create table successd")
}

//插入数据
func InsertData(DB *sql.DB) {
    result, err := DB.Exec("insert INTO users(username,password) values(?,?)", "demo", "123qwe")
    if err != nil {
        fmt.Printf("Insert data failed,err:%v", err)
        return
    }
    lastInsertID, err := result.LastInsertId() //获取插入数据的自增ID
    if err != nil {
        fmt.Printf("Get insert id failed,err:%v", err)
        return
    }
    fmt.Println("Insert data id:", lastInsertID)

    rowsaffected, err := result.RowsAffected() //通过RowsAffected获取受影响的行数
    if err != nil {
        fmt.Printf("Get RowsAffected failed,err:%v", err)
        return
    }
    fmt.Println("Affected rows:", rowsaffected)
}

//查询单行
func QueryOne(DB *sql.DB) {
    user := new(User) //用new()函数初始化一个结构体对象
    row := DB.QueryRow("select id,username,password from users where id=?", 1)
    //row.scan中的字段必须是按照数据库存入字段的顺序,否则报错
    if err := row.Scan(&user.Id, &user.Username, &user.Password); err != nil {
        fmt.Printf("scan failed, err:%v\n", err)
        return
    }
    fmt.Println("Single row data:", *user)
}

//查询多行
func QueryMulti(DB *sql.DB) {
    user := new(User)
    rows, err := DB.Query("select id,username,password from users where id = ?", 2)

    defer func() {
        if rows != nil {
            rows.Close() //关闭掉未scan的sql连接
        }
    }()
    if err != nil {
        fmt.Printf("Query failed,err:%v\n", err)
        return
    }
    for rows.Next() {
        err = rows.Scan(&user.Id, &user.Username, &user.Password) //不scan会导致连接不释放
        if err != nil {
            fmt.Printf("Scan failed,err:%v\n", err)
            return
        }
        fmt.Println("scan successd:", *user)
    }
}

//更新数据
func UpdateData(DB *sql.DB) {
    result, err := DB.Exec("UPDATE users set password=? where id=?", "111111", 1)
    if err != nil {
        fmt.Printf("Insert failed,err:%v\n", err)
        return
    }
    fmt.Println("update data successd:", result)

    rowsaffected, err := result.RowsAffected()
    if err != nil {
        fmt.Printf("Get RowsAffected failed,err:%v\n", err)
        return
    }
    fmt.Println("Affected rows:", rowsaffected)
}

//删除数据
func DeleteData(DB *sql.DB) {
    result, err := DB.Exec("delete from users where id=?", 1)
    if err != nil {
        fmt.Printf("Insert failed,err:%v\n", err)
        return
    }
    fmt.Println("delete data successd:", result)

    rowsaffected, err := result.RowsAffected()
    if err != nil {
        fmt.Printf("Get RowsAffected failed,err:%v\n", err)
        return
    }
    fmt.Println("Affected rows:", rowsaffected)
}

func main() {
    conn := fmt.Sprintf("%s:%s@%s(%s:%d)/%s", USERNAME, PASSWORD, NETWORK, SERVER, PORT, DATABASE)
    fmt.Println("conn: ", conn)
    DB, err := sql.Open("mysql", conn)
    if err != nil {
        fmt.Println("connection to mysql failed:", err)
        return
    }

    DB.SetConnMaxLifetime(100 * time.Second) //最大连接周期,超时的连接就close
    DB.SetMaxOpenConns(100)                  //设置最大连接数
    CreateTable(DB)
    InsertData(DB)
    QueryOne(DB)
    QueryMulti(DB)
    UpdateData(DB)
    DeleteData(DB)
}

运行结果如下:

[root@localhost mysql]# go run main.go 
conn:  root:123qwe@tcp(127.0.0.1:3306)/test
create table successd
Insert data id: 2
Affected rows: 1
scan failed, err:sql: no rows in result set
scan successd: {2 demo 123qwe 0 0}
update data successd: {0xc0000d8000 0xc0000d60b0}
Affected rows: 0
delete data successd: {0xc0000d8000 0xc000016330}
Affected rows: 0

 

转载于:https://www.cnblogs.com/wangjq19920210/p/11577314.html

### 使用 Golang 和 Gin 框架连接 MySQL 创建 API 接口 #### 创建并配置项目结构 为了构建一个基于Gin框架的应用程序,首先需要初始化一个新的Go模块: ```bash go mod init example.com/gin-mysql-api ``` 接着安装必要的依赖包: ```bash go get -u github.com/gin-gonic/gin go get -u gorm.io/gorm go get -u gorm.io/driver/mysql ``` #### 初始化数据库连接 在 `main.go` 文件中设置MySQL数据库的连接字符串,并利用GORM建立与数据库之间的会话。 ```go package main import ( "fmt" "gorm.io/driver/mysql" "gorm.io/gorm" ) var db *gorm.DB var err error func InitDB() { dsn := "user:password@tcp(127.0.0.1:3306)/gin_demo?charset=utf8mb4&parseTime=True&loc=Local" db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { fmt.Println("Failed to connect database:", err) panic(err) } } ``` 这段代码展示了如何打开到名为 `gin_demo` 的MySQL数据库的连接[^1]。请注意替换DSN中的用户名、密码和其他参数以匹配实际环境下的配置。 #### 定义模型层 (Model Layer) 假设要管理成员(`Member`)的数据,则可以在应用里定义相应的结构体来映射表字段。 ```go type Member struct { ID uint `json:"id"` Name string `json:"name" gorm:"not null"` Email string `json:"email" gorm:"uniqueIndex;not null"` CreatedAt time.Time UpdatedAt time.Time } ``` 此部分描述了实体类的设计原则及其属性约束条件[^2]。 #### 实现业务逻辑服务 (Service Layer) 编写服务于具体功能的服务函数,比如新增会员记录: ```go // CreateMember creates a new member record. func CreateMember(m *Member) (*Member, error) { result := db.Create(&m) if result.Error != nil { return nil, result.Error } return m, nil } ``` 上述片段说明了怎样封装基本的操作以便于后续调用。 #### 构建控制器 (Controller Layer) 最后一步是在HTTP请求处理器内实现对外暴露的功能端点。下面的例子实现了POST /members 路由用来接收客户端提交的新用户资料并保存至数据库。 ```go package controllers import ( "net/http" "github.com/gin-gonic/gin" ) func AddMember(c *gin.Context) { var input Member if err := c.ShouldBindJSON(&input); err == nil { createdMember, _ := service.CreateMember(&input) c.JSON(http.StatusOK, gin.H{"data": createdMember}) } else { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) } } func SetupRoutes(engine *gin.Engine) { v1 := engine.Group("/api/v1") { members := v1.Group("/members") { members.POST("", AddMember) } } } ``` 以上内容解释了如何通过组合先前各层次组件完成一次完整的API交互过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值