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

  • 相关阅读:
    支持向量机SVM知识点概括
    决策树知识点概括
    HDU 3081 Marriage Match II
    HDU 3572 Task Schedule
    HDU 4888 Redraw Beautiful Drawings
    Poj 2728 Desert King
    HDU 3926 Hand in Hand
    HDU 1598 find the most comfortable road
    HDU 4393 Throw nails
    POJ 1486 Sorting Slides
  • 原文地址:https://www.cnblogs.com/kungfupanda/p/5573078.html
Copyright © 2011-2022 走看看