本文目录


    Go 操作 MySql 数据库的方式

    原文地址: Go 操作 MySql 数据库的方式

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

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

    package main  
    
    import (  
        "database/sql"  
        "fmt"  
        \_ "github.com/go-sql-driver/mysql"  
        "time"  
    )  
    
    //数据库连接信息  
    const (  
     USERNAME = "root"  
     PASSWORD = "123456"  
     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 main() {  
     conn := fmt.Sprintf("%s:%s@%s(%s:%d)/%s",USERNAME, PASSWORD, NETWORK, SERVER, PORT, DATABASE)  
     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)  
    }  
    
    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(?,?)","test","123456")  
        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)  
    }  

    GORM(Object Relation Mapping),即 Go 语言中的对象关系映射,实际上就是对数据库的操作进行封装,对上层开发人员屏蔽数据操作的细节,开发人员看到的就是一个个对象,大大简化了开发工作,提高了生产效率。如 GORM 结合 Gin 等服务端框架使用可以开发出丰富的 Rest API 等。

    通过非常简短的代码, 就可以实现功能强大的 restful 接口, go 语言的优势也是非常明显的. 关于 gin 和 gorm 还有更加深入的内容. 掌握好这两个工具可以轻松的构建 web 应用。

    文章作者:  BigYoung
    版权声明:  本网站所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BigYoung !