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驱动)
- [root@localhost /]# yum install git
获取mysql驱动
- [root@localhost /]# go get github.com/go-sql-driver/mysql
- [root@localhost /]# ls
- pkg src
在当前目录下可以看到多出两个文件夹pkg和src,将src文件夹拷贝到go程序安装目录下或go工作环境下即可
- [root@localhost /]# cp -r src /usr/local/go/
- package main
- import (
- "database/sql"
- "fmt"
- _ "github.com/go-sql-driver/mysql"
- "reflect"
- )
- func main() {
- /*DSN数据源名称
- [username[:password]@][protocol[(address)]]/dbname[?param1=value1¶mN=valueN]
- user@unix(/path/to/socket)/dbname
- user:password@tcp(localhost:5555)/dbname?charset=utf8&autocommit=true
- user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?charset=utf8mb4,utf8
- user:password@/dbname
- 无数据库: user:password@/
- */
- db, err := sql.Open("mysql", "jesse:jesse@tcp(127.0.0.1:3306)/?charset=utf8") //第一个参数为驱动名
- checkErr(err)
- db.Query("drop database if exists tmpdb")
- db.Query("create database tmpdb")
- //db.Query("use tmpdb")
- db.Query("create table tmpdb.tmptab(c1 int, c2 varchar(20), c3 varchar(20))")
- db.Query("insert into tmpdb.tmptab values(101, '姓名1', 'address1'), (102, '姓名2', 'address2'), (103, '姓名3', 'address3'), (104, '姓名4', 'address4')")
- //checkErr(err)
- query, err := db.Query("select * from tmpdb.tmptab")
- checkErr(err)
- v := reflect.ValueOf(query)
- fmt.Println(v)
- fmt.Println("--增加数据测试--")
- printResult(query)
- db.Query("delete from tmpdb.tmptab where c1 = 101")
- //checkErr(err)
- query2, _ := db.Query("select * from tmpdb.tmptab")
- fmt.Println("--删除数据测试--")
- printResult(query2)
- db.Query("update tmpdb.tmptab set c3 = 'address4' where c1 = 103")
- //checkErr(err)
- query3, _ := db.Query("select * from tmpdb.tmptab")
- fmt.Println("--更新数据测试--")
- printResult(query3)
- db.Query("delete from tmpdb.tmptab")
- //checkErr(err)
- query4, _ := db.Query("select * from tmpdb.tmptab")
- fmt.Println("--清空数据测试--")
- printResult(query4)
- db.Query("drop table tmpdb.tmptab")
- db.Query("drop database tmpdb")
- //stmt, err := db.Prepare("create database tmpdb")
- db.Close()
- }
- func checkErr(errMasg error) {
- if errMasg != nil {
- panic(errMasg)
- }
- }
- func printResult(query *sql.Rows) {
- column, _ := query.Columns() //读出查询出的列字段名
- values := make([][]byte, len(column)) //values是每个列的值,这里获取到byte里
- scans := make([]interface{}, len(column)) //因为每次查询出来的列是不定长的,用len(column)定住当次查询的长度
- for i := range values { //让每一行数据都填充到[][]byte里面
- scans[i] = &values[i]
- }
- results := make(map[int]map[string]string) //最后得到的map
- i := 0
- for query.Next() { //循环,让游标往下移动
- if err := query.Scan(scans...); err != nil { //query.Scan查询出来的不定长值放到scans[i] = &values[i],也就是每行都放在values里
- fmt.Println(err)
- return
- }
- row := make(map[string]string) //每行数据
- for k, v := range values { //每行数据是放在values里面,现在把它挪到row里
- key := column[k]
- row[key] = string(v)
- }
- results[i] = row //装入结果集中
- i++
- }
- for k, v := range results { //查询出来的数组
- fmt.Println(k, v)
- }
- }
4.1 编译运行
- [root@localhost /]# go build MysqlGoTest.go
- [root@localhost /]# ls
- MysqlGoTest.go MysqlGoTest
- [root@localhost /]# ./MysqlGoTest
4.2 直接运行
- [root@localhost /]# go run MysqlGoTest.go
- <*sql.Rows Value>
- --增加数据测试--
- 0 map[c1:101 c2:姓名1 c3:address1]
- 1 map[c1:102 c2:姓名2 c3:address2]
- 2 map[c1:103 c2:姓名3 c3:address3]
- 3 map[c1:104 c2:姓名4 c3:address4]
- --删除数据测试--
- 0 map[c1:102 c2:姓名2 c3:address2]
- 1 map[c1:103 c2:姓名3 c3:address3]
- 2 map[c1:104 c2:姓名4 c3:address4]
- --更新数据测试--
- 0 map[c1:102 c2:姓名2 c3:address2]
- 1 map[c1:103 c2:姓名3 c3:address4]
- 2 map[c1:104 c2:姓名4 c3:address4]
- --清空数据测试--
5.1 避免中文乱码
为确保程序写入数据库以及从数据库读出时不出现乱码,需要做如下配置: go客户端程序级别: go程序文件设置编码 utf8,如
- db, err := sql.Open("mysql", "jesse:jesse@tcp(127.0.0.1:3306)/?charset=utf8")
mysql数据库级别:
设置MySQL数据库客户端及服务端配置为utf8
例如:
在my.cnf配置文件中配置
- [mysql]
- default_character_set=utf8
- [mysqld]
- character-set-server=utf8
- collation-server=utf8_bin
5.2 go语言反射机制
用途:可获取对象数据类型
很多语言都有反射机制。通过反射,我们可以知道一个未知对像的属性,方法。
在写一个函数的时候,有时你需要另外一个对象或者类的某些属性,方法,但这个程序不能认识所需要的对象或者类,这时便需要通过反射来操作了。通过反射,你变很方便的加载、探知、使用编译期间完全未知的对象或者类了。
所谓反射,也就是相当于物理的反射,你通过镜子,可以看到自己的摸样,函数通过反射,可以获得想要的信息。在golang的反射包reflect中,反射类型Type()和Value(),可以改变反射回来变量的值。例如获取变量value的类型,可通过函数reflect.ValueOf()进行操作。
- var value interface {} = &User{1,"Tom",12,"nan"}
- v := reflect.ValueOf(value)
- fmt.Println(v)
****************************************************************************************
原文地址:http://blog.csdn.net/jesseyoung/article/details/40398321
博客主页:http://blog.csdn.net/jesseyoung
****************************************************************************************
go语言操作mysql范例(增删查改)的更多相关文章
- Python对MySQL进行增删查改
python连接MySQL数据库:pymysql # 测试操作 import pymysql # 打开数据库 db = pymysql.connect("localhost", & ...
- Mysql常用增删查改及入门(二)
常用:数据库常用就是DML:增删查改 1.增加数据: insert into 表名 values (值1,值2...); insert into 表名 (字段1,字段2) values (值1,值2) ...
- VisualStudio 连接 MySql 实现增删查改
首先创建数据库,建立一个用户登录表 2.visualStudio默认是不支持MySql的,要想通过Ado.Net 操作MySql 需要在管理NeGet包添加对MySql.Data 和 MySql.D ...
- Yii2使用数据库操作汇总(增删查改、事务)
查询 //1.简单查询 $admin=Admin::model()->findAll($condition,$params); $admin=Admin::model()->findAll ...
- asp.net操作xml(增删查改)
asp.net操作xml 1.xml文档Products.xml <?xml version="1.0" encoding="utf-8"?> &l ...
- 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)
1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...
- PHP与MYSQL结合操作——文章发布系统小项目(实现基本增删查改操作)
php和mysql在一起几十年了,也是一对老夫老妻了,最近正在对他们的爱情故事进行探讨,并做了一个很简单的小东西——文章发布系统,目的是为了实现mysql对文章的基本增删查改操作 前台展示系统有:文章 ...
- Java连接MySQL数据库及简单的增删查改操作
主要摘自 https://www.cnblogs.com/town123/p/8336244.html https://www.runoob.com/java/java-mysql-connect.h ...
- nodejs连接mysql并进行简单的增删查改
最近在入门nodejs,正好学习到了如何使用nodejs进行数据库的连接,觉得比较重要,便写一下随笔,简单地记录一下 使用在安装好node之后,我们可以使用npm命令,在项目的根目录,安装nodejs ...
随机推荐
- Java-继承,多态练习0922-06
编写一个Shape类,具有属性:周长和面积: 定义其子类三角形和矩形,分别具有求周长的方法. 定义主类E,在其main方法中创建三角形和矩形类的对象, 并赋给Shape类的对象a.b,使用对象a.b来 ...
- 使用反射将DataTable的数据转成实体类
利用反射避免了硬编码出现的错误,但是实体类的属性名必须和数据库名字对应(相同) 1.利用反射把DataTable的数据写到单个实体类 /// <summary> ///利用反射把DataT ...
- android sdk下载
android sdk下载 所有的离线包都有 http://mirrors.neusoft.edu.cn/android/repository/
- Liferay7 BPM门户开发之46: 集成Activiti用户、用户组、成员关系同步
在实际的BPM集成开发过程中,Liferay和Activiti这两个异构的系统之间,用户.组的同步需求非常重要,用来实现签收组的概念,比如指定签收组.会签.抢签都需要用到. Activiti可以通过自 ...
- SQL Pass北京举行2014年第一次线下活动
地点:北京微软(中国)有限公司[望京利星行],三层308室 时间:2014年 3 月15日 13:30-16:30 SQL PASS 北京QQ群号:2435349 报名地址:http://1drv.m ...
- <C#>找出数组中重复次数最多的数值
给定一个int数组,里面存在重复的数值,如何找到重复次数最多的数值呢? 这是在某社区上有人提出的问题,我想到的解决方法是分组. 1.先对数组中的所有元素进行分组,那么,重复的数值肯定会被放到一组中: ...
- Android 自定义View及其在布局文件中的使用示例(二)
转载请注明出处 http://www.cnblogs.com/crashmaker/p/3530213.html From crash_coder linguowu linguowu0622@gami ...
- 移动web开发之视口viewport
× 目录 [1]布局视口 [2]视觉视口 [3]理想视口[4]meta标签[5]总结 前面的话 在CSS标准文档中,视口viewport被称为初始包含块.这个初始包含块是所有CSS百分比宽度推算的根源 ...
- Android开发之广播
广播是Android开发中的一个重要的功能,在Android里面有各式各样的广播,比如:电池的状态变化.信号的强弱状态.电话的接听和短信的接收等等,现在给大家简单介绍一下系统发送.监听这些广播的机制. ...
- poj1006生理周期(中国剩余定理)
/* 中国剩余定理可以描述为: 若某数x分别被d1..….dn除得的余数为r1.r2.….rn,则可表示为下式: x=R1r1+R2r2+…+Rnrn+RD 其中R1是d2.d3.….dn的公倍数,而 ...