GoLang Mysql helloworld

懒皮 · · 696 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

一、mysql安装

参考超级详细的mysql安装指南
Root Account Pwd:xxnetCuiXu

二、mysql使用

参考
21分钟MySQL基础入门
MySQL 教程
Mysql在命令行格式下输入命令需要加上“;”分号作为结束。如果不加上“;”分号结束符,那么就意味着命令没有完成,所以一直会出现这个类似于箭头的符号。

CREATE TABLE `user_accounts` (
    ->   `id`             int(100) unsigned NOT NULL AUTO_INCREMENT primary key,
    ->   `password`       varchar(32)       NOT NULL DEFAULT '' COMMENT '用户密码',
    ->   `reset_password` tinyint(32)       NOT NULL DEFAULT 0 COMMENT '用户类型:0-不需要重置密码;1-需要重置密码',
    ->   `mobile`         varchar(20)       NOT NULL DEFAULT '' COMMENT '手机',
    ->   `create_at`      timestamp(6)      NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
    ->   `update_at`      timestamp(6)      NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
    ->   -- 创建唯一索引,不允许重复
    ->   UNIQUE INDEX idx_user_mobile(`mobile`)
    -> )
    -> ENGINE=InnoDB DEFAULT CHARSET=utf8
    -> COMMENT='用户表信息';

随便插入几条数据:

INSERT INTO user_accounts
    -> (password,mobile)
    -> VALUES
    -> ("pas22","132241242");
Query OK, 1 row affected (0.06 sec)
三、go中使用

参考Golang Mysql笔记(一)--- 连接与连接池
1.database/sql
database/sql是golang的标准库之一,它提供了一系列接口方法,用于访问关系数据库。它并不会提供数据库特有的方法,那些特有的方法交给数据库驱动去实现

database/sql库提供了一些type。这些类型对掌握它的用法非常重要。

****DB**** 数据库对象。 sql.DB类型代表了数据库。和其他语言不一样,它并是数据库连接。golang中的连接来自内部实现的连接池,连接的建立是惰性的,当你需要连接的时候,连接池会自动帮你创建。通常你不需要操作连接池。一切都有go来帮你完成。

****Results**** 结果集。数据库查询的时候,都会有结果集。sql.Rows类型表示查询返回多行数据的结果集。sql.Row则表示单行查询结果的结果集。当然,对于插入更新和删除,返回的结果集类型为sql.Result。

****Statements**** 语句。sql.Stmt类型表示sql查询语句,例如DDL,DML等类似的sql语句。可以把当成prepare语句构造查询,也可以直接使用sql.DB的函数对其操作。

2.golang连接数据库用户的驱动是:go-sql-driver
安装的话,可以使用go get github.com/go-sql-driver/mysql,会安装到GoPath下,可以在命令行中使用go env来查看gopath。不过我用goland又把项目设置了新的gopath,所以直接复制了一份源码到项目里了。

对于其他语言,查询数据的时候需要创建一个连接,对于go而言则是需要创建一个数据库抽象对象。连接将会在查询需要的时候,由连接池创建并维护。使用sql.Open函数创建数据库对象。它的第一个参数是数据库驱动名,第二个参数是一个连接字串(符合DSN风格,可以是一个tcp连接,一个unix socket等)。格式是”用户名:密码@tcp(IP:端口)/数据库?charset=utf8”

import (
    "database/sql"
    "log"
    _ "github.com/go-sql-driver/mysql"
)

func main() {
    db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/test?parseTime=true")
    if err != nil{
        log.Fatal(err)
    }
    defer db.Close()
}

通常来说, 不应该直接使用驱动所提供的方法, 而是应该使用 sql.DB, 因此在导入 mysql 驱动时, 这里使用了匿名导入的方式(在包路径前添加 _), 当导入了一个数据库驱动后, 此驱动会自行初始化并注册自己到Golang的database/sql上下文中, 因此我们就可以通过 database/sql 包提供的方法访问数据库了.

Golang连接mysql数据库中,有更清晰的写法:

//数据库配置
const (
    userName = "root"
    password = "123456"
    ip = "127.0.0.1"
    port = "3306"
    dbName = "loginserver"
)
//Db数据库连接池
var DB *sql.DB

//注意方法名大写,就是public
func InitDB()  {
    //构建连接:"用户名:密码@tcp(IP:端口)/数据库?charset=utf8"
    path := strings.Join([]string{userName, ":", password, "@tcp(",ip, ":", port, ")/", dbName, "?charset=utf8"}, "")

    //打开数据库,前者是驱动名,所以要导入: _ "github.com/go-sql-driver/mysql"
    DB, _ = sql.Open("mysql", path)
    //设置数据库最大连接数
    DB.SetConnMaxLifetime(100)
    //设置上数据库最大闲置连接数
    DB.SetMaxIdleConns(10)
    //验证连接
    if err := DB.Ping(); err != nil{
        fmt.Println("opon database fail")
        return
    }
    fmt.Println("connnect success")
}

3.查询 一下试试

    // query
    rows, err := db.Query("SELECT * FROM user_accounts")
    checkErr(err)

    for rows.Next() {
        var id int
        var password string
        var reset_password int
        var mobile string
        var create_at string
        var update_at string

        err = rows.Scan(&id, &password,&reset_password,&mobile,&create_at,&update_at)
        checkErr(err)
        fmt.Println(id)
        fmt.Println(password)
    }

可以查到之前在mysql中插入的数据了。

  • rows.Scan 参数的顺序很重要, 需要和查询的结果的column对应. 例如 “SELECT * From user where age >=20 AND age < 30” 查询的行的 column 顺序是 “id, name, age” 和插入操作顺序相同, 因此 rows.Scan 也需要按照此顺序 rows.Scan(&id, &name, &age), 不然会造成数据读取的错位.
  • 因为golang是强类型语言,所以查询数据时先定义数据类型,但是查询数据库中的数据存在三种可能:存在值,存在零值,未赋值NULL 三种状态, 因为可以将待查询的数据类型定义为sql.Nullxxx类型,可以通过判断Valid值来判断查询到的值是否为赋值状态还是未赋值NULL状态.
  • 每次db.Query操作后, 都建议调用rows.Close(). 因为 db.Query() 会从数据库连接池中获取一个连接, 这个底层连接在结果集(rows)未关闭前会被标记为处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close(),但如果提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭, 则此连接会一直被占用. 因此通常我们使用 defer rows.Close() 来确保数据库连接可以正确放回到连接池中; 不过阅读源码发现rows.Close()操作是幂等操作,即一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同, 所以即便对已关闭的rows再执行close()也没关系.

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:懒皮

查看原文:GoLang Mysql helloworld

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

696 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传