Golang 连接数据库

81 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

Mysql 的教程在网上有很多了,这里就不说了,如果有docker 基础的话 可以用一下命令来创建一个 容器使用。

docker run -itd --name order_canteen -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

安装依赖

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

创建连接


import (
   "database/sql"
   _ "github.com/go-sql-driver/mysql"
)
//数据库配置
const (
    userName = "root"
    password = "123456"
    ip = "127.0.0.1"
    port = "3306"
    dbName = "serve"
)
//Db数据库连接池
var DB *sql.DB

//注意方法名大写,就是public
func InitDB()  {
    //构建连接:"用户名:密码@tcp(IP:端口)/数据库?charset=utf8"
    path := strings.Join([]string{userName, ":", password, "@tcp(",ip, ":", port, ")/", dbName, "?charset=utf8"}, "")

    //打开数据库,前者是驱动名,所以要导入: _ "github.com/go-sql-driver/mysql"
    DB, _ = sql.Open("mysql", path)
    //设置数据库最大连接数
    DB.SetConnMaxLifetime(100)
    //设置上数据库最大闲置连接数
    DB.SetMaxIdleConns(10)
    //验证连接
    if err := DB.Ping(); err != nil{
        fmt.Println("opon database fail")
        return
    }
    fmt.Println("connnect success")
}

import 下划线(如:import _ github/demo)的作用:当导入一个包时,该包下的文件里所有init()函数都会被执行,然而,有些时候我们并不需要把整个包都导入进来,仅仅是是希望它执行init()函数而已。这个时候就可以使用 import _ 引用该包。

数据库的增删改查

insert

insert 分为 4 个步骤

graph TD
开启事务 --> 拼接SQL语句 --> 提交执行SQL语句 --> 提交事务
func InsertUser(user bean.User) (bool){
    //开启事务
    transaction, err := DB.Begin()
    if err != nil{
        fmt.Println("transaction open fail")
        return false
    }
    //准备sql语句
    stmt, err := transaction.Prepare("INSERT INTO nk_user (`name`, `password`) VALUES (?, ?)")
    if err != nil{
        fmt.Println("Prepare fail")
        return false
    }
    //将参数传递到sql语句中并且执行
    res, err := stmt.Exec(user.UserName, user.Password)
    if err != nil{
        fmt.Println("Exec fail")
        return false
    }
    //将事务提交
    transaction.Commit()
    //获得上一个插入自增的id
    fmt.Println(res.LastInsertId())
    return true
}

delete

删除的过程同上

graph TD
开启事务 --> 拼接SQL语句 --> 提交执行SQL语句 --> 提交事务
func DeleteUser(user bean.User) (bool) {
    //开启事务
    transaction, err := DB.Begin()
    if err != nil{
        fmt.Println("transaction fail")
    }
    //准备sql语句
    stmt, err := transaction.Prepare("DELETE FROM user WHERE id = ?")
    if err != nil{
        fmt.Println("Prepare fail")
        return false
    }
    //设置参数以及执行sql语句
    res, err := stmt.Exec(user.Id)
    if err != nil{
        fmt.Println("sql Exec fail")
        return false
    }
    //提交事务
    transaction.Commit()
    //获得上一个insert的id
    fmt.Println(res.LastInsertId())
    return true
}

更新数据

同样的步骤

graph TD
开启事务 --> 拼接SQL语句 --> 提交执行SQL语句 --> 提交事务
func UpdateUser(user bean.User) (bool) {
    //开启事务
    transaction, err := DB.Begin()
    if err != nil{
        fmt.Println("transaction connect fail")
    }
    //准备sql语句
    stmt, err := transaction.Prepare("UPDATE nk_user SET name = ?, password = ? WHERE id = ?")
    if err != nil{
        fmt.Println("Prepare fail")
        return false
    }
    //设置参数以及执行sql语句
    res, err := stmt.Exec(user.UserName, user.Password, user.Id)
    if err != nil{
        fmt.Println("Exec fail")
        return false
    }
    //提交事务
    transaction.Commit()
    fmt.Println(res.LastInsertId())
    return true
}

查询

查询会有些许不同

  • 查询一行数据 QueryRow
func SelectUserById(id int) (bean.User) {
    var user bean.User
    err := DB.QueryRow("SELECT * FROM nk_user WHERE id = ?", id).Scan(&user.Id, &user.UserName, &user.Password)
    if err != nil{
        fmt.Println("查询出错了")
    }
    return user
}
  • 查询多行数据 Next

func SelectAllUser() ([]bean.User) {
    //执行查询语句
    rows, err := DB.Query("SELECT * from user")
    if err != nil{
        fmt.Println("查询出错了")    
    }
    var users []bean.User
    //循环读取结果
    for rows.Next(){
        var user bean.User
        //将每一行的结果都赋值到一个user对象中
        err := rows.Scan(&user.Id, &user.UserName, &user.Password)
        if err != nil {
            fmt.Println("rows fail")
        }
        //将user追加到users的这个数组中
        users = append(users, user)
    }
    return users
}