go语言操作数据库——yaml

433 阅读5分钟

0. 操作思路

  1. 下载需要的对应依赖

    "github.com/go-sql-driver/mysql"
    
  2. 数据库初始化操作

    • 用户名密码等其他配置操作
  3. 创建数据库表结构体

  4. 编写对应数据库操作方法

  5. 测试运行

1. 直接代码操作

  1. 注意点

    1. 要创建数据库连接池对象*sql.DB
    2. 要创建数据库表接受的对象struct
  2. 代码

    package main
    ​
    import (
        "database/sql"
        "fmt"
        _ "github.com/go-sql-driver/mysql"
    )
    var db *sql.DB //连接池对象func initDB() (err error) {
        // DSN:Data Source Name
        dsn := "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True"
        db, err = sql.Open("mysql", dsn) //open不会校验用户名和密码是否正确
        if err != nil {
            return
        }
        err = db.Ping()
        if err != nil {
            return
        }
    ​
        db.SetMaxOpenConns(10) //设置数据库连接池的最大连接数 10
        db.SetMaxIdleConns(5)  //设置最大空闲连接数
        return
    }
    type user struct { //结构体
        user_id   int
        role_id int
    }
    ​
    func queryOne(id int) {
        var u1 user
        // 1.写查询单条记录的sql语句
        sqlStr := "select user_id,role_id from sys_user_role where user_id =?;"
        //2.执行并拿到结果
        //必须对row对象调用scan方法,该方法会释放数据库连接
        db.QueryRow(sqlStr, id).Scan(&u1.user_id, &u1.role_id) //从连接池拿一个连接出去数据库查询单条记录
        //打印结果
        fmt.Println(u1)
    }
    func main() {
        err := initDB()
        if err != nil {
            fmt.Printf("init DB failed err:%v\n", err)
        }
        fmt.Println("连接数据库成功")
        queryOne(2)
    }
    

2. 配置文件抽取

2.0 数据库建表

CREATE TABLE `sys_user_role` (
  `user_id` varchar(64) NOT NULL COMMENT '用户编号',
  `role_id` varchar(64) NOT NULL COMMENT '角色编号',
  PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户-角色';

2.1 下载依赖

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

2.2 编写配置文件

mysql:
  user : root
  password : root
  host : 127.0.0.1
  port : 3306
  dbname : dns_manager

2.3 配置文件读取

  1. 配置文件对应结构体

    type Sqls struct {
        Mysql struct {// todo 配置文件里面是结构体 结构体名称要大写 不要名称冲突
            User string `yaml:"user"`
            Passwd string `yaml:"password"`
            Host string `yaml:"host"`
            Port int `yaml:"port"`
            Name string `yaml:"dbname"`
        }
    }
    
  2. 操作文件读取

    func ReadYaml(initFile string) (*os.File,error){
        // 打开文件
        //dbConfig, err := os.Open("B:\code\go\workspace\go_mysql\db.yml")
        dbConfig, err := os.Open(initFile)
        if err != nil{
            log.Fatalf("os.Open() failed with `%s` \n",err)
            return nil,err
        }
        return dbConfig,nil
    }
    

2.4 初始化链接

2.4.1 mysql驱动链接介绍

  1. 使用方法

    func Open(driverName, driverName string) (*DB, error)
    
  2. 字段介绍

    • driverName:指定数据库
    • driverName:指定数据源
  3. 作用:sql.Open打开一个指定源头的数据库

    import (
        "database/sql"
        _ "github.com/go-sql-driver/mysql"
    )
    ​
    func main() {
        dsn := "user:password@tcp(127.0.0.1:3306)/dbname"
        db, err := sql.Open("mysql", dsn)
        if err != nil {
            panic(err)
        }
        defer db.Close()  
    }
    

2.4.2 初始化函数封装

  1. 注意点

    1. 导入的依赖要空值接受
    2. *sql.DB数据库连接对象
    3. 配置文件读取
    4. 数据库url字符串链接
    5. 非查询需要启用事务
  2. 代码

    // 初始化数据库配置
    func initSql(initFile string) (*sql.DB, error ) {
        file, err := ReadYaml(initFile)
        // 操作文件
        defer file.Close()
        // 读取文件流
        decoder := yaml.NewDecoder(file)
        // 创建变量并赋值
        var sqls Sqls
        err = decoder.Decode(&sqls)// 解码
        if err != nil{
            log.Fatalf("dec.Decode() failed with `%s` \n",err)
            return nil,err
        }
        // mysql中封装了对应的数据库配置
        //"root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True"
        url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", sqls.Mysql.User,  sqls.Mysql.Passwd,
            sqls.Mysql.Host,  sqls.Mysql.Port,// TODO 拼接url
            sqls.Mysql.Name)
        open, err := sql.Open("mysql", url)
        //open, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True")
        if err != nil{
            log.Fatalf("配置文件出错,原因为 %s\n",err)
            return nil,err
        }
        err = open.Ping()
        if err != nil {
            log.Fatalf("数据库连接失败,错误为%s\n",err)
            return nil,err
        }
        return open,nil
    }
    ​
    

2.5 插入

  1. 代码

    // 插入角色
    func InsertUser(userRole UserRole ,db *sql.DB) bool{
        // 增加事务
        begin, err2 := db.Begin()
        if err2 != nil{
            log.Fatalf("err:%s",err2)
            return false
        }
        // sql
        prepare, err2 := begin.Prepare("INSERT INTO sys_user_role (`user_id`,`role_id`) value (?,?)")
        if err2 != nil  {
            fmt.Println("Prepare fail")
            return false
        }
        // 执行
        res, err2 := prepare.Exec(userRole.userId, userRole.roleId)
        fmt.Println(res)
        if err2 != nil{
            fmt.Println("Exec fail")
            return false
        }
        // 事务
        begin.Commit()
        return true
    }
    ​
    

2.6 修改

  1. 代码

    func DeleteByUid(uid string,db *sql.DB) bool{
        // 增加事务
        begin, err := db.Begin()
        if err != nil{
            log.Fatalf("err:%s",err)
            return false
        }
        // sql
        prepare, err2 := begin.Prepare("delete from sys_user_role where user_id = ?")
        if err2 != nil  {
            fmt.Println("Prepare fail")
            return false
        }
        // 执行
        res, err2 := prepare.Exec(uid)
        fmt.Println(res)
        if err2 != nil{
            fmt.Println("Exec fail")
            return false
        }
        // 事务
        begin.Commit()
        return true
    }
    

2.7 删除

  1. 代码

    func UpdateUser(user UserRole,db *sql.DB) (bool) {
        //开启事务
        tx, err := db.Begin()
        if err != nil{
            fmt.Println("tx fail")
        }
        //准备sql语句
        stmt, err := tx.Prepare("UPDATE sys_user_role SET  user_id = ? WHERE role_id = ?")
        if err != nil{
            fmt.Println("Prepare fail")
            return false
        }
        //设置参数以及执行sql语句
        res, err := stmt.Exec(user.userId, user.roleId)
        fmt.Println(res)
        if err != nil{
            fmt.Println("Exec fail")
            return false
        }
        //提交事务
        tx.Commit()
        return true
    }
    ​
    

2.8 查询

  1. 代码

    func SelectUserById(uid string,db *sql.DB)  UserRole {
        var user UserRole
        err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId)
        if err != nil{
            fmt.Println("查询出错了")
        }
        return user
    }
    

2.9 调用

  1. 代码

    func SelectUserById(uid string,db *sql.DB)  UserRole {
        var user UserRole
        err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId)
        if err != nil{
            fmt.Println("查询出错了")
        }
        return user
    }
    

3. 完整代码

package main
​
import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"// todo 需要这样导入
    "gopkg.in/yaml.v3"
    "log"
    "os"
)
​
type UserRole struct {
    userId string
    roleId string
}
type Sqls struct {
    Mysql struct {// todo 配置文件里面是结构体 结构体名称要大写 不要名称冲突
        User string `yaml:"user"`
        Passwd string `yaml:"password"`
        Host string `yaml:"host"`
        Port int `yaml:"port"`
        Name string `yaml:"dbname"`
    }
}
​
func main() {
        filePath := "B:\code\go\workspace\go_mysql\db.yml"
        open,_ := initSql(filePath)
        var userRole UserRole
        userRole.roleId = "23324"
        userRole.userId = "23234"
        //todo 非查询需要添加事务 插入
        insertUser := InsertUser(userRole, open)
        if insertUser {
            log.Fatal("插入成功\n")
        }
        //
        //// 删除
        //uid := DeleteByUid("23", open)
        //if uid {
        //  log.Fatal("删除成功\n")
        //}
        //var userRole2 UserRole
        //userRole2.roleId = "23"
        //userRole2.userId = "23"
        //// 修改
        //updateUser := UpdateUser(userRole2, open)
        //if updateUser {
        //  log.Fatal("修改成功\n")
        //}
        //
        ////查询
        //id := SelectUserById("2", open)
        //fmt.Println(1,id.roleId)
}
func ReadYaml(initFile string) (*os.File,error){
    // 打开文件
    //dbConfig, err := os.Open("B:\code\go\workspace\go_mysql\db.yml")
    dbConfig, err := os.Open(initFile)
    if err != nil{
        log.Fatalf("os.Open() failed with `%s` \n",err)
        return nil,err
    }
    return dbConfig,nil
}
// 初始化数据库配置
func initSql(initFile string) (*sql.DB, error ) {
    file, err := ReadYaml(initFile)
    // 操作文件
    defer file.Close()
    // 读取文件流
    decoder := yaml.NewDecoder(file)
    // 创建变量并赋值
    var sqls Sqls
    err = decoder.Decode(&sqls)// 解码
    if err != nil{
        log.Fatalf("dec.Decode() failed with `%s` \n",err)
        return nil,err
    }
    // mysql中封装了对应的数据库配置
    //"root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True"
    url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", sqls.Mysql.User,  sqls.Mysql.Passwd,
        sqls.Mysql.Host,  sqls.Mysql.Port,// TODO 拼接url
        sqls.Mysql.Name)
    open, err := sql.Open("mysql", url)
    //open, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True")
    if err != nil{
        log.Fatalf("配置文件出错,原因为 %s\n",err)
        return nil,err
    }
    err = open.Ping()
    if err != nil {
        log.Fatalf("数据库连接失败,错误为%s\n",err)
        return nil,err
    }
    return open,nil
}
​
​
// 插入角色
func InsertUser(userRole UserRole ,db *sql.DB) bool{
    // 增加事务
    begin, err2 := db.Begin()
    if err2 != nil{
        log.Fatalf("err:%s",err2)
        return false
    }
    // sql
    prepare, err2 := begin.Prepare("INSERT INTO sys_user_role (`user_id`,`role_id`) value (?,?)")
    if err2 != nil  {
        fmt.Println("Prepare fail")
        return false
    }
    // 执行
    res, err2 := prepare.Exec(userRole.userId, userRole.roleId)
    fmt.Println(res)
    if err2 != nil{
        fmt.Println("Exec fail")
        return false
    }
    // 事务
    begin.Commit()
    return true
}
​
func DeleteByUid(uid string,db *sql.DB) bool{
    // 增加事务
    begin, err := db.Begin()
    if err != nil{
        log.Fatalf("err:%s",err)
        return false
    }
    // sql
    prepare, err2 := begin.Prepare("delete from sys_user_role where user_id = ?")
    if err2 != nil  {
        fmt.Println("Prepare fail")
        return false
    }
    // 执行
    res, err2 := prepare.Exec(uid)
    fmt.Println(res)
    if err2 != nil{
        fmt.Println("Exec fail")
        return false
    }
    // 事务
    begin.Commit()
    return true
}
​
​
func UpdateUser(user UserRole,db *sql.DB) (bool) {
    //开启事务
    tx, err := db.Begin()
    if err != nil{
        fmt.Println("tx fail")
    }
    //准备sql语句
    stmt, err := tx.Prepare("UPDATE sys_user_role SET  user_id = ? WHERE role_id = ?")
    if err != nil{
        fmt.Println("Prepare fail")
        return false
    }
    //设置参数以及执行sql语句
    res, err := stmt.Exec(user.userId, user.roleId)
    fmt.Println(res)
    if err != nil{
        fmt.Println("Exec fail")
        return false
    }
    //提交事务
    tx.Commit()
    return true
}
​
func SelectUserById(uid string,db *sql.DB)  UserRole {
    var user UserRole
    err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId)
    if err != nil{
        fmt.Println("查询出错了")
    }
    return user
}