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

图片 1

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  

图片 2

 

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. –清空数据测试–  

 

图片 3

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
****************************************************************************************

网站地图xml地图