go-mysql

1、GO语言实现的简单TCP服务代码

package main

import (
"net"
"fmt"
)

var (    maxRead = 1100
    msgStop   = []byte("cmdStop")
    msgStart  = []byte("cmdContinue")
    )
func main() {
    hostAndPort := "localhost:54321"
    listener := initServer(hostAndPort)

    for {
        conn, err := listener.Accept()
        checkError(err, "Accept: ")
        go connectionHandler(conn)
    }
}

func initServer(hostAndPort string) *net.TCPListener {
    serverAddr, err := net.ResolveTCPAddr("tcp", hostAndPort)
    checkError(err, "Resolving address:port failed: ‘" + hostAndPort + "‘")
    listener, err := net.ListenTCP("tcp", serverAddr)
    checkError(err, "ListenTCP: ")
    println("Listening to: ", listener.Addr().String())
    return listener
}

func connectionHandler(conn net.Conn) {
    connFrom := conn.RemoteAddr().String()
    println("Connection from: ", connFrom)
    talktoclients(conn)
    for {
        var ibuf []byte = make([]byte, maxRead + 1)
        length, err := conn.Read(ibuf[0:maxRead])
        ibuf[maxRead] = 0 // to prevent overflow
      switch err {
        case nil:
            handleMsg(length, err, ibuf)

        default:
            goto DISCONNECT
      }
    }
    DISCONNECT:
    err := conn.Close()
    println("Closed connection:" , connFrom)
    checkError(err, "Close:" )
}

func talktoclients(to net.Conn) {
    wrote, err := to.Write(msgStart)
    checkError(err, "Write: wrote " + string(wrote) + " bytes.")
}

func handleMsg(length int, err error, msg []byte) {
    if length > 0 {

        for i := 0; ; i++ {
            if msg[i] == 0 {
                break
            }
        }
        fmt.Printf("Received data: %v", string(msg[0:length]))
        fmt.Println("   length:",length)
    }

}

func checkError(error error, info string) {
    if error != nil {
    panic("ERROR: " + info + " " + error.Error()) // terminate program
  }
}

例2 、

下面先创建一个简单的Server端:

package main

import (
    "net"
    "fmt"
)

func main() {
    if ln, err := net.Listen("tcp", ":8080"); err == nil {
        defer ln.Close()
        for{
            ln.Accept()
            fmt.Println("Receive a Message")
        }
    }
}

和脚本一样简单的写法。

先net.Listen(), 第一个参数是协议,tcp还是udp,第二个参数是ip地址,这里可以不填写IP只填写端口就是

使用defer 来Close,将close写在listen之后是个好习惯

然后再循环中使用Accept()接受消息

下面是一个可以进行压力测试的客户端程序

package main

import (
    "net"
    "fmt"
)

func main() {
    currency := 20 //并发数,记住,一个连接数是打开一个端口号,window和linux的端口号都是有限制的
    count := 10 //每条连接发送多少次连接

    for i:=0;i<currency;i++ {
        go func(){
            for j:=0;j<count;j++ {
                sendMessage()
            }
        }()
    }
    select{}
}

func sendMessage() {
    conn, err := net.Dial("tcp", "127.0.0.1:8080")

    if(err != nil) {
        panic("error")
    }

    header := "GET / HTTP/1.0\r\n\r\n"
    fmt.Fprintf(conn, header)
}

2、Go语言中使用MySql

首先安装mysql的go语言驱动

go get github.com/ziutek/mymysql/godrv

演示代码

package users

import (
    "database/sql"
    "fmt"
    _ "github.com/ziutek/mymysql/godrv"
)

const (
    DB_NAME = "mysql_database_name"
    DB_USER = "mysql_user"
    DB_PASS = "mysql_password"
)

type User struct {
    Id      int    `json:"id"`
    Name string `json:"name"`
    Alias   string `json:"alias"`
}

func OpenDB() *sql.DB {
    db, err := sql.Open("mymysql", fmt.Sprintf("%s/%s/%s", DB_NAME, DB_USER, DB_PASS))
    if err != nil {
        panic(err)
    }
    return db
}

func UserById(id int) User {
    db := OpenDB()
    defer db.Close()
    row := db.QueryRow("SELECT `id`, `name`,`alias` FROM `users` WHERE id=?", id)
    user := new(User)
    row.Scan(&user.Id, &user.Name, &user.Alias)
    return user
}

例2:

go的sql包是在pkg/database中,里面的两个包sqlsql/driver可以一起看。建议看这个两个包之前可以先看看sql文件夹下的doc.txt。这个文档说了几点比较重要的:

1 这两个包是真正Go风格的包。

2 这使用这两个包就不需要关于并发处理了,也不需要维护自己的数据库连接池了,一旦建立了一个连接,这个连接是可以在各个goroutine之间共用的。

sql/driver提供的是数据库的接口,具体的实现还需要自己实现。

一、先看database/driver包

第一个用到的方法是Register

这个方法将实现了driver.Driver的驱动注册到变量drivers中,当写完一个驱动之后,就需要将驱动注册到sql中才能使用sql包中的这些接口。这个实现了driver.Driver的必须实现了Open方法.

driver.Open返回的是driver.Conn,它的三个方法

Prepare : 参数绑定

Close : 关闭连接

Begin : 支持事务

先看Prepare,这个和php mysql pdo一样的用法

Conn.Prepare("select * from test where a=?")

返回的Stmt结构:

Close : 关闭这个statement

NumInput : 返回有多少个可以绑定的参数

Exec : Insert或者update等无返回的使用

Query :select等查询操作使用

Exec是绑定变量,然后返回Result结构

Query是绑定变量,然后返回Rows结果集

看Result里面的方法:

LastInsertId()  : Insert操作之后获取到的主键id

RowsAffect() : 影响到的行数

Rows:

Columns() : 返回的数据有哪些列,其实就是返回的表列名

Close() : 关闭Rows,调用之后不能再进行任何操作

Next() : 将下一行的数据取到des[] Value中。这里的Value接口可以是int64,float64,bool,[]byte,string,time.Time

下面回到Begin,返回了Tx

开始事务之后除了查询之外,就两种行为:Commit和Rollback,这两种行为都是Tx接口的方法

drvier中的结构全是接口性质的,它需要你来实现并注册到Register中。

二、驱动的具体使用是在database/sql中

首先将几个sql的结构看一遍

首先sql中的结构都是对driver中的结构进行了一层封装,比如像Rows,有个内部属性是rowsi driver.Rows。

对sql的实际操作都是使用driver.Rows里面的接口进行操作的,实际也就是使用你自己实现的driver进行操作。

driver和sql就像插头和一个充满插头的汽车一样,你实现了driver,即实现了这些插头的配置,你就可使用sql这个汽车了。

Result : 和driver中的Result一致,即你如果实现了driver.Result,那你自然就实现了sql.Result。它是个接口,其实没有什么特殊的用处,如果sql包中的所有Result都换成driver.Result也是行的,估计是作者希望返回值不要引用到其他包去,就使用这种方法。

Rows :  基于了driver.Rows, 还在上面扩展了几个其他的方法。拥有方法:

Close

Cloumns

Err

Next

Scan

Stmt :基于driver.Stmt。拥有方法

Close

Exec

Query

QueryRow

Tx:基于driver.Tx。拥有方法:

Commit

Exec

Prepare

Query

QueryRow

Rollback

Stmt

从sql.Open开始

返回了sql.DB结构,这个结构是实现了driver.Conn结构,除了Conn已有的Prepare,Begin,Close之外,还直接多了几个查询方法:

Driver() : 返回当前驱动

Exec() : 直接进行操作

Query() : 进行查询,返回Rows

QueryRow() : 预期返回单行,返回Row

不管Rows还是Row都有个很好用的方法Scan来将数据放到制定的变量中去。

比如下面就是典型的Rows用法

rows, err := db.Query("SELECT ...")
...

for rows.Next() {
    var id int
    var name string

    err = rows.Scan(&id, &name)
    ...
}

Prepare返回Stmt结构

Exec返回Result结构

至于这几个结构也有各自的方法。

时间: 2024-08-04 22:04:16

go-mysql的相关文章

记一次MySQL找回用户数据

事情经过 有天,我们公司外区的一个销售C说他8月3号以前的工作流记录找不到了.问清缘由,原来是更新了微信号(我们公司的工作流是基于企业微信开发的).经过分析,微信号和流程数据并没什么关系,所以初步得出结论:本来只需要更新微信号的,结果我们公司的流程系统管理员把用户先删除,再创建了新的用户. 解决过程 1.首先想到的是直接从定时备份数据里面找回原来的用户ID,结果发现系统只备份了十天的记录,而工作流系统上显示销售C只有8月3号以后的流程记录,距今已经40多天,从自动备份的数据里已经无法恢复. 2.

centos7下使用yum安装mysql

CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql的repo源. 1. 下载mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 2. 安装mysql-community-release-el7-5.noarch.rpm包 $ sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm 安装这个

EF+mvc+mysql

这个真是一个大坑啊.TM折腾了一下午终于弄好了.赶紧记录下来分享给大家,免得有和我一样一直配置不成功的又折腾半天-.1.安装MySQL for Visual Studio这个直接在mysql官网下载并安装就好了.不过这个必须是vs2013 professional版本以上才可以!!2.安装MySQL Connector/Net这个可以可以通过NuGet工具获得,比较轻松愉快,当然你也可以自己下载,自己引用.3.配置web.config.首先是connectionStrings节点 1 <conn

Linux环境下MySQL数据库用SQL语句插入中文显示 “问号或者乱码 ” 问题解决!

问题: 在普通用户权限下执行 mysql -u root -p进入mysql数据库,中间步骤省略,插入数据:insert into 库名(属性)values('汉字'); 会出现如下提示:  Query OK, 1 row affected, 1 warning (0.00 sec)    表明出现错误,没有插入成功,然后执行select * from 表名   就会出现如下的问题:显示的表中出现乱码或者问号. 如图: 解决方案: 首先重新打开一个终端窗口(方便操作),进入root用户模式 执行

Centos6.5 zabbix3.2.6监控mysql

  一.     操作环境 我使用的linux系统是centos6.5,数据库是mysql5.6,apache2.4,php5,6 安装目录: /usr/local/apache /usr/local/php /usr/local/mysql /usr/local/zabbix Zabbix服务器插件安装 Zabbix3.2.6自带监控mysql模板监控项不全面,所以重新下载导入到zabbix里面 下载网址:. https://www.percona.com/downloads/percona-

MySQL数据库基础知识

day02 MySQL数据库基础知识 一.基础知识概述: 基础决定你这门课程的学习成败!只有学习好这些基础知识以后,你才能真正的运用自如.才能够对数据库有更深入的了解,道路才会越走越远. 二.基础知识: 1.数据库(database):数据库就好比是一个物理的文档柜,一个容器,把我们整理好的数据表等等归纳起来. 创建数据库命令:        create database 数据库名; 2.查看数据库         show databases; 3.打开指定的数据库         use 

MariaDB(MySQL)创建、删除、选择及数据类型使用详解

一.MariaDB简介(MySQL简介略过) MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品.在存储引擎方面,使用XtraDB(英语:XtraDB)来代替MySQL的InnoDB. MariaDB由MySQL的创始人Michael Widenius(英语:Michael Widenius)主导开发,他早前曾以10亿美元的价格,将自己创建的公司MySQL A

Mac配置Mysql遇到的 --secure-file-priv问题

1.安装mysql 在官网上安装,一步步无障碍安装(但根据后来文件入法导入/导出的经验,最好在安装前设置secure-file-priv为empty,5.7.6之后似乎就默认为NULL,而secure-file-prive为NULL的话,就不支持文件导入/出) 2.安装navicat premimum 在网上找到一个破解版,按照破解步骤来安装,很好用 3.遇到的问题:在将选择的记录导出到.csv文件时,出现提示"The MySQL server is running with the --sec

MySQL(九)之数据表的查询详解(SELECT语法)二

上一篇讲了比较简单的单表查询以及MySQL的组函数,这一篇给大家分享一点比较难得知识了,关于多表查询,子查询,左连接,外连接等等.希望大家能都得到帮助! 在开始之前因为要多表查询,所以搭建好环境: 1)创建数据表suppliers 前面已经有一张表是book表,我们在建立一张suppliers(供应商)表和前面的book表对应. 也就是说 让book中s_id字段值指向suppliers的主键值,创建一个外键约束关系. 其实这里并没有达到真正的外键约束关系,只是模拟,让fruits中的s_id中

MySQL 警告WARN: Establishing SSL connection without server&#39;s identity verification is not recommended.解决办法

Success loading Mysql Driver!Mon Apr 04 15:43:00 CST 2016 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by d