zoukankan      html  css  js  c++  java
  • go语言操作mysql范例(增删查改)

    http://blog.csdn.net/jesseyoung/article/details/40398321

     go语言连接mysql简介
        go官方仅提供了database package,database package下有两个包sql,sql/driver。这两个包用来定义操作数据库的接口,这就保证了无论使用哪种数据库,他们的操作方式都是相同的。
        但go官方并没有提供连接数据库的driver,如果要操作数据库,还需要第三方的driver 包,最常用的有:
        https://github.com/Go-SQL-Driver/MySQL支持database/sql,全部采用go写。
        https://github.com/ziutek/mymysql 支持database/sql,也支持自定义的接口,全部采用go写。
        推荐使用前者,因为前者的效率更高一点,二者效率的对比可参考benchmark测试结果:https://github.com/go-sql-driver/sql-benchmark

        go连接其他主流数据库的驱动介绍可参考:

        https://code.google.com/p/go-wiki/wiki/SQLDrivers

    2 测试环境准备
        操作系统:Red Hat Enterprise Linux Server release 6.4 
        mysql版本:mysql-5.5.28
        安装git客户端(方便从github上获取mysql驱动)

    [plain] view plain copy
    1. [root@localhost /]# yum install git  

        获取mysql驱动

    [plain] view plain copy
    1. [root@localhost /]# go get github.com/go-sql-driver/mysql  
    2. [root@localhost /]# ls  
    3. pkg  src   

        在当前目录下可以看到多出两个文件夹pkg和src,将src文件夹拷贝到go程序安装目录下或go工作环境下即可

    [plain] view plain copy
    1. [root@localhost /]# cp -r src /usr/local/go/  

    3 编程实例

    [plain] view plain copy
    1. package main  
    2.   
    3. import (  
    4.         "database/sql"  
    5.         "fmt"  
    6.         _ "github.com/go-sql-driver/mysql"  
    7.         "reflect"  
    8. )  
    9.   
    10. func main() {  
    11.         /*DSN数据源名称  
    12.           [username[:password]@][protocol[(address)]]/dbname[?param1=value1¶mN=valueN]  
    13.           user@unix(/path/to/socket)/dbname  
    14.           user:password@tcp(localhost:5555)/dbname?charset=utf8&autocommit=true  
    15.           user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?charset=utf8mb4,utf8  
    16.           user:password@/dbname  
    17.           无数据库: user:password@/  
    18.         */  
    19.         db, err := sql.Open("mysql", "jesse:jesse@tcp(127.0.0.1:3306)/?charset=utf8") //第一个参数为驱动名    
    20.         checkErr(err)  
    21.         db.Query("drop database if exists tmpdb")  
    22.         db.Query("create database tmpdb")  
    23.         //db.Query("use tmpdb")  
    24.         db.Query("create table tmpdb.tmptab(c1 int, c2 varchar(20), c3 varchar(20))")  
    25.         db.Query("insert into tmpdb.tmptab values(101, '姓名1', 'address1'), (102, '姓名2', 'address2'), (103, '姓名3', 'address3'), (104, '姓名4', 'address4')")  
    26.         //checkErr(err)  
    27.         query, err := db.Query("select * from tmpdb.tmptab")  
    28.   
    29.         checkErr(err)  
    30.         v := reflect.ValueOf(query)  
    31.         fmt.Println(v)  
    32.         fmt.Println("--增加数据测试--")  
    33.         printResult(query)  
    34.         db.Query("delete from tmpdb.tmptab where c1 = 101")  
    35.         //checkErr(err)  
    36.         query2, _ := db.Query("select * from tmpdb.tmptab")  
    37.         fmt.Println("--删除数据测试--")  
    38.         printResult(query2)  
    39.         db.Query("update tmpdb.tmptab set c3 = 'address4' where c1 = 103")  
    40.         //checkErr(err)  
    41.         query3, _ := db.Query("select * from tmpdb.tmptab")  
    42.         fmt.Println("--更新数据测试--")  
    43.         printResult(query3)  
    44.         db.Query("delete from tmpdb.tmptab")  
    45.         //checkErr(err)  
    46.         query4, _ := db.Query("select * from tmpdb.tmptab")  
    47.         fmt.Println("--清空数据测试--")  
    48.         printResult(query4)  
    49.         db.Query("drop table tmpdb.tmptab")  
    50.         db.Query("drop database tmpdb")  
    51.         //stmt, err := db.Prepare("create database tmpdb")  
    52.         db.Close()  
    53. }  
    54.   
    55. func checkErr(errMasg error) {  
    56.         if errMasg != nil {  
    57.                 panic(errMasg)  
    58.         }  
    59. }  
    60.   
    61. func printResult(query *sql.Rows) {  
    62.         column, _ := query.Columns()              //读出查询出的列字段名  
    63.         values := make([][]byte, len(column))     //values是每个列的值,这里获取到byte里  
    64.         scans := make([]interface{}, len(column)) //因为每次查询出来的列是不定长的,用len(column)定住当次查询的长度  
    65.         for i := range values {                   //让每一行数据都填充到[][]byte里面  
    66.                 scans[i] = &values[i]  
    67.         }  
    68.         results := make(map[int]map[string]string) //最后得到的map  
    69.         i := 0  
    70.         for query.Next() { //循环,让游标往下移动  
    71.                 if err := query.Scan(scans...); err != nil { //query.Scan查询出来的不定长值放到scans[i] = &values[i],也就是每行都放在values里  
    72.                         fmt.Println(err)  
    73.                         return  
    74.                 }  
    75.                 row := make(map[string]string) //每行数据  
    76.                 for k, v := range values {     //每行数据是放在values里面,现在把它挪到row里  
    77.                         key := column[k]  
    78.                         row[key] = string(v)  
    79.                 }  
    80.                 results[i] = row //装入结果集中  
    81.                 i++  
    82.         }  
    83.         for k, v := range results { //查询出来的数组  
    84.                 fmt.Println(k, v)  
    85.         }  
    86. }  

    4 运行程序

        4.1 编译运行

    [plain] view plain copy
    1. [root@localhost /]# go build MysqlGoTest.go  
    2. [root@localhost /]# ls  
    3. MysqlGoTest.go  MysqlGoTest  
    4. [root@localhost /]# ./MysqlGoTest  


    4.2 直接运行

    [plain] view plain copy
    1. [root@localhost /]# go run MysqlGoTest.go  
    2. <*sql.Rows Value>  
    3. --增加数据测试--  
    4. 0 map[c1:101 c2:姓名1 c3:address1]  
    5. 1 map[c1:102 c2:姓名2 c3:address2]  
    6. 2 map[c1:103 c2:姓名3 c3:address3]  
    7. 3 map[c1:104 c2:姓名4 c3:address4]  
    8. --删除数据测试--  
    9. 0 map[c1:102 c2:姓名2 c3:address2]  
    10. 1 map[c1:103 c2:姓名3 c3:address3]  
    11. 2 map[c1:104 c2:姓名4 c3:address4]  
    12. --更新数据测试--  
    13. 0 map[c1:102 c2:姓名2 c3:address2]  
    14. 1 map[c1:103 c2:姓名3 c3:address4]  
    15. 2 map[c1:104 c2:姓名4 c3:address4]  
    16. --清空数据测试--  

    5 补充知识

        5.1 避免中文乱码

        为确保程序写入数据库以及从数据库读出时不出现乱码,需要做如下配置:     go客户端程序级别:     go程序文件设置编码 utf8,如

    [plain] view plain copy
    1. db, err := sql.Open("mysql", "jesse:jesse@tcp(127.0.0.1:3306)/?charset=utf8")  

        mysql数据库级别:
        设置MySQL数据库客户端及服务端配置为utf8 
        例如:
        在my.cnf配置文件中配置

    [plain] view plain copy
    1. [mysql]    
    2. default_character_set=utf8    
    3. [mysqld]    
    4. character-set-server=utf8    
    5. collation-server=utf8_bin   

        5.2 go语言反射机制

        用途:可获取对象数据类型

        很多语言都有反射机制。通过反射,我们可以知道一个未知对像的属性,方法。

        在写一个函数的时候,有时你需要另外一个对象或者类的某些属性,方法,但这个程序不能认识所需要的对象或者类,这时便需要通过反射来操作了。通过反射,你变很方便的加载、探知、使用编译期间完全未知的对象或者类了。

        所谓反射,也就是相当于物理的反射,你通过镜子,可以看到自己的摸样,函数通过反射,可以获得想要的信息。在golang的反射包reflect中,反射类型Type()和Value(),可以改变反射回来变量的值。例如获取变量value的类型,可通过函数reflect.ValueOf()进行操作。

    [plain] view plain copy
    1. var value interface {} = &User{1,"Tom",12,"nan"}  
    2. v := reflect.ValueOf(value)  
    3. fmt.Println(v)  

     
    ****************************************************************************************
        原文地址:http://blog.csdn.net/jesseyoung/article/details/40398321
        博客主页:http://blog.csdn.net/jesseyoung
    ****************************************************************************************

  • 相关阅读:
    Sql获取数据集中各类型中的最大值(最新值)
    oracle重装系统后恢复
    icePDF去水印方法
    js的倒计时在ie下显示NAN的最佳解决办法
    类属性与类方法
    多继承、多态
    继承、方法重写与调用
    私有方法
    对象的属性隐藏
    __init__、__str__、__del__方法
  • 原文地址:https://www.cnblogs.com/kungfupanda/p/5573078.html
Copyright © 2011-2022 走看看