数据库驱动是不同数据库开发商(比如oracle mysql等)

为计算机语言能够实现数据库访问而开发的程序

它将计算机语言对数据库的操作翻译成自身的数据库语言

 

使用go语言操作mysql, 需要的驱动: github.com/go-sql-driver/mysql

使用命令:go get安装第三方mysql驱动:

C:\Windows\System32>go get github.com/go-sql-driver/mysql

C:\Windows\System32>                  // 没有报错就表示安装成功(会下载到go path里面)

查看:D:\golang\workspace\project\src\github.com\go-sql-driver\mysql

 

导入mysql驱动包:

import (
    "database/sql"                        // 这个是go操作数据的系统包
    _ "github.com/go-sql-driver/mysql"    // go操作mysql的驱动包
)

mysql连结:

"mysql" 表示连结的数据库是mysql(也可以是其它的数据库)

"root" 表示帐户

"xxx" 表示密码

"test" 表示连结mysql的test数据库

db, err := sql.Open("mysql", "root:xxx@tcp(127.0.0.1:3306)/test");

返回的 *DB 是线程安全的, 可以被多个线程同时访问, 并会维护自身的闲置连接池。

这样一来,Open函数只需调用一次, 很少需要关闭DB

可以在init中连结数据库:

/*在init中连结mysql*/
func init() {
    db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/go_test")  // 此处没有密码
}

查询所有:

package main
import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "database/sql"
)

var db *sql.DB
type Person struct{
    Id int 			
    Name string		
    Sex string		
    Email string 	
}

/*在init中连结mysql*/
func init() {
    var err error
    db, err = sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/go_test")
    if err != nil {
        fmt.Println("mysql connection error: ", err)
        return
    }
}

func main() {
    rows_persons, err := db.Query("SELECT * FROM PERSION")  // 查询的结果放入"行"中, 表中有多少行记录, 就有多少个"行"
    if err != nil {
        fmt.Println("select error: ", err)
        return
    }

    var persons []Person	// 用于储存查询的结果
    for rows_persons.Next() {    // 循环 "行", 直到Next()的返回结果为false
        var person Person
        // 从rows中获取数据(参数需要sql语句里面的顺序, 才能保证数据赋值完全正确)
        rows_persons.Scan(&person.Id, &person.Name, &person.Email, &person.Sex)
        persons = append(persons, person)
    }
    fmt.Println(persons)
}

插入记录:

func main() {
    result, err := db.Exec("INSERT INTO PERSION(username, sex, email)VALUES (?, ?, ?)", "李四", "男", "lisi@sina.cn")
    if err != nil {
        fmt.Println("error:", err)
    }
    insertId, err2 := result.LastInsertId() // 获取最后一个insert id (RowsAffected()可以获取受影响的记录数)
    if err2 != nil {
        return
    }
    fmt.Println(insertId)
}

修改记录:

同上, 也使用Exec函数, 返回Result, 从Result中可以获取最后一个insert id(如上)

也可以获取受影响的行数(如下)

func main() {
    results, err:=db.Exec("UPDATE PERSION SET email = ? where user_id = ?", "123@.com", 2)
    if err != nil {
        return
    }
    num, err := results.RowsAffected()
    if err != nil {
        return
    }
    fmt.Println(num) // 受影响的记录数
}

删除记录:

仍然使用Exec函数(增删改都使用它), 只是sql语句不同而已

func main() {
    results, err := db.Exec("DELETE FROM PERSION where user_id = ?", 2)
    if err != nil {
        return
    }
    num, err := results.RowsAffected()
    if err != nil {
        return
    }
    fmt.Println(num) // 受影响的记录数
}

sqlx:

上面演示的是golang 标准库 database/sql 的基本crud操作

而sqlx是 database/sql 的扩展, 可以将记录与结构体映射, 支持命名参数, 增加接口等功能

sqlx的用法和sql基本是一样的(增删改), 但是sqlx的查询结果可以自动封装

安装sqlx: 

go get

增 删改 都是一样的操作(只是sql语句不同):

package main
import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
//  "database/sql"                                // 将标准库的sql注释
    "github.com/jmoiron/sqlx"                     // 导入第三方的sqlx
)

var db *sqlx.DB			// 使用sqlx代替sql
type Person struct{
    Id int 			
    Name string		
    Sex string		
    Email string 	
}

/*在init中连结mysql*/
func init() {
    var err error
    db, err = sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/go_test")  // Open函数不变
    if err != nil {
        fmt.Println("mysql connection error: ", err)
        return
    }
}

func main() {
    // 这里Exec函数也不变
    results, err := db.Exec("INSERT INTO PERSION VALUES(default, ?, ?, ?)", "小明", "man", "xiaoming@163.com")
    if err != nil {
        return
    }
    num, err := results.RowsAffected()
    if err != nil {
        return
    }
    fmt.Println(num) // 受影响的记录数
}

查询:

使用Select函数

在结构体中使用tag标签, 将数据库字段与结构体字段对应起来

这样查询后, 它会将查询结果自动封装到结构体切片中

import (
    "fmt"
    _ "github.com/go-sql-driver/mysql"
//	"database/sql"
    "github.com/jmoiron/sqlx"
)

var db *sqlx.DB			// 使用sqlx
type Person struct{
    Id int 	        `db:"user_id"`		// 必须指明数据库中的字段映射
    Name string		`db:"username"`		// 表中字段与此要正确对应, 否则赋值不正确
    Sex string		`db:"sex"`	
    Email string 	`db:"email"`
}

/*在init中连结mysql*/
func init() {
    var err error
    db, err = sqlx.Open("mysql", "root:@tcp(127.0.0.1:3306)/go_test")  // 使用sqlx
    if err != nil {
        fmt.Println("mysql connection error: ", err)
        return
    }
}

func main() {
    var persions []Person	// 不能是一个persion, 因为并不知道查询的结果是一个还是多个
    err := db.Select(&persions, "SELECT * FROM PERSION WHERE USER_ID = ?", 3)
    if err != nil {
        fmt.Println("error: ", err)
        return
    }
    fmt.Println(persions)
}