zoukankan      html  css  js  c++  java
  • go database/sql sql-driver/mysql 操作

    这里使用的是github.com/Go-SQL-Driver/MySQL,

    所以需要下载一个github.com/Go-SQL-Driver/MySQL

    引入 database/sql 和 github.com/Go-SQL-Driver/MySQL

    这里实现了对数据库的 增、删、改、查、事务

    这里直接上代码,代码中有详细的解释。并且这些操作都经过我实际操作

    引入需要的包

    import(
        "database/sql"
        _"github.com/Go-SQL-Driver/MySQL"
        "log"
        "strconv"
        //"reflect"    //获取变量类型用
    )

    增:

    func main (){
        //insert 
        name := "name"
        pwd := "password"
        nickname := "nickname"
        db,err := sql.Open("mysql","go_mysql_user:go_mysql_pwd@tcp(localhost:3306)/go_mysql?charset=utf8")
    defer db.Close()  //只有在前面用了 panic[抛出异常] 这时defer才能起作用,如果链接数据的时候出问题,他会往err写数据。defer:延迟,这里立刻申请了一个关闭sql 链接的草错,defer 后的方法,或延迟执行。在函数抛出异常一会被执行
    if err != nil{ panic(err.Error()) log.Println(err) return } insert_sql := "insert into users (name,pwd,nickname) value (?,?,?),(?,?,?),(?,?,?),(?,?,?)" stmt,err := db.Prepare(insert_sql) //准备一个sql操作,返回一个*Stmt,用户后面的执行,这个Stmt可以被多次执行,或者并发执行 /* * 这个stmt的主要方法:Exec、Query、QueryRow、Close */ if err != nil { log.Println(err) return } res,err := stmt.Exec(name,pwd,nickname,name,pwd,nickname,name,pwd,nickname,name,pwd,nickname) if err != nil { log.Println(err) return } lastInsertId,err := res.LastInsertId() //批量插入的时候LastInserId返回的是第一条id,单条插入则返回这条的id //lastInsertId,err := res.RowsAffected() //插入的是后RowsAffected 返回的是插入的条数 if err != nil { log.Println(err) return } //log.Println(reflect.TypeOf(lastInsertId)) //打印变量类型 last_insert_id_string := strconv.FormatInt(lastInsertId,10) //int64 转string 需要引入 strconv包 log.Println("lastInsertId = " + last_insert_id_string) }

    删:

    func main (){
        //delete
        del_sql := "delete from users where id=?"
        del_stmt,del_err := db.Prepare(del_sql)
        del_stmt.Exec(6)//不返回任何结果
    }

    改:

    func main (){
        //update
        update_sql := "update users set name=? where id=?"
        update_stmt,update_err := db.Prepare(update_sql)
        if update_err != nil {
                log.Println(update_err)
                return;
        }
        update_res,update_err := update_stmt.Exec("username",9)
        if update_err != nil {
                log.Printf("%v",update_err)
                return
        }
        affect_count,_ := update_res.RowsAffected()    //返回影响的条数,注意有两个返回值
        log.Printf("%v",affect_count)
    }

    查一条:

    type User struct{
        id int
        name string
        pwd string
        nickname string
    }
    
    func main (){
        //select
        var user User
        select_sql := "select * from users where id > ?"
        select_err := db.QueryRow(select_sql,11).Scan(&user.id,&user.name,&user.pwd,&user.nickname)//查询一条,返回一条结果。并赋值到user这个结构体类型的变量中,就算查询到的是多条,单返回的还是一条
        if select_err != nil {//如果没有查询到任何数据就进入if中err:no rows in result set
                log.Println(select_err)
                return
        }
        log.Println(user)
    }

    查多条:

    func main (){
        //查询多条
        select_rows,select_err := db.Query(select_sql,16)
        if select_err != nil {
                log.Println(select_err)
                return
        }
        defer select_rows.Close()
        for select_rows.Next(){
            var id int
            var name string
            var pwd string
            var nickname string
            if err := select_rows.Scan(&id,&name,&pwd,&nickname); err != nil {
                    log.Println(err)
                    return
            }
            log.Printf("id=%v,name=%v,pwd=%v,nickname=%v",id,name,pwd,nickname)
        }
    
    }

    事务:

    func main (){
    
        //事务
        tx,err := db.Begin()        //声明一个事务的开始
        if err != nil {
                log.Println(err)
                return
        }
        insert_sql := "insert into users (name,pwd,nickname) value(?,?,?)"
        insert_stmt,insert_err := tx.Prepare(insert_sql)
        if insert_err != nil {
                log.Println(insert_err)
                return
        }
        insert_res,insert_err := insert_stmt.Exec("tx_name","tx_pwd","tx_nickname")
        last_insert_id,_ := insert_res.LastInsertId()
        log.Println(last_insert_id)
        defer tx.Rollback()            //回滚之前上面的last_login_id是有的,但在回滚后该操作没有被提交,被回滚了,所以上面打印的Last_login_id的这条数据是不存在与数据库表中的
        //tx.Commit()                        //这里提交了上面的操作,所以上面的执行的sql 会在数据库中产生一条数据
    
    }

    知识点总结和注意事项:

    db,err := sql.Open("mysql","数据库登录名:数据库密码@tcp(服务器:端口)/数据库名?charset=utf8") 对应修改;
    defer db.Close()  defer 是延迟或异常或者该方法结束时执行的操作。这里表示有异常就关闭db 可与 panic(err.Error())=》抛出异常。配合使用。一种情况不可执行=》你的方法进入了死循环,该方法不会结束与异常则不可执行。
    LastInsertId()  获取插入第一条的id  有用
    RowsAffected()  获取影响/插入的条数  有用
    reflect.TypeOf(i)  reflect包中TypeOf 返回的是变量i的类型
    strconv.FormatInt(int64位变量,10)  strconv包中FormatInt将int64位的变量转为string 具体是用另一篇文章中有总结
    其他都在代码中一些返回值 和使用。

    mymysql与GO-MYSQL_DRIVER对比

    1 go-mysql-driver是实现了golang标准库database/sql的产物。底层实现比较有保证

    2 go-mysql-driver虽然每个命令的运行时间比mymysql长,但是内存使用少得非常明显,这点两方算打平。

    3 go-mysql-driver实现了database/sql,如果数据库换成其他的话,不需要更改应用逻辑的代码。

    4 go-mysql-driver实现了database/sql,这个接口的设计也是非常好的,基本和php中的pdo一样,上手和学习成本低。



    晚安~~gogogo
  • 相关阅读:
    oracle 10g 免安装客户端在windows下配置
    sql2005 sa密码
    使用windows live writer 有感
    windows xp SNMP安装包提取
    汉化groove2007
    迁移SQL server 2005 Reporting Services到SQL server 2008 Reporting Services全程截图操作指南
    foxmail 6在使用中的问题
    AGPM客户端连接不上服务器解决一例
    SpringSource Tool Suite add CloudFoundry service
    Java 之 SWing
  • 原文地址:https://www.cnblogs.com/jackylee92/p/6209596.html
Copyright © 2011-2022 走看看