zoukankan      html  css  js  c++  java
  • Go语言之Go语言操作数据库(Mysql)

    Go 语言操作Mysql

    连接mysql

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。

    Go语言MySQL包

    使用第三方开源的mysql库:

    github.com/go-sql-driver/mysql (MySQL驱动)

    github.com/jmoiron/sqlx (基于MySQL驱动的封装)

    通过如下命令,保存下载第三方库:

    go get github.com/go-sql-driver/mysql 
    go get github.com/jmoiron/sqlx  
    

    创建数据库、数据表

    在MySQL下创建 oldboy库:

    mysql> CREATE DATABASE IF NOT EXISTS oldboy DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
    

    在oldboy库中创建student表。

    mysql> use oldboy;
    
    mysql> CREATE TABLE IF NOT EXISTS `student`(
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `name` varchar(100) NOT NULL,
        `sex` varchar(40) NOT NULL,
        `age` int(11) DEFAULT NULL,
        `course` varchar(100) NOT NULL,
        PRIMARY KEY (`id`)
    )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    MySQL连接池

    数据库连接使用datebase/sql Open函数进行连接,用户应该通过db.Ping()函数来检查数据库是否实际可用。

    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    func main() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    }
    
    

    连接池配置

    配置连接池有两个的函数:

    设置最大数据库连接:使用 db.SetMaxOpenConns(n int) 函数设置打开数据库的最大连接数。包含正在使用的连接和连接池的连接。如果你的函数调用需要申请一个连接,并且连接池已经没有了连接或者连接数达到了最大连接数。此时的函数调用将会被block,直到有可用的连接才会返回。设置这个值可以避免并发太高导致连接mysql出现too many connections的错误。该函数的默认设置是0,表示无限制。

    设置最大空闲连接:使用db.SetMaxIdleConns(n int) 函数设置连接池中的保持连接的最大连接数。默认也是0,表示连接池不会保持释放会连接池中的连接的连接状态:即当连接释放回到连接池的时候,连接将会被关闭。这会导致连接再连接池中频繁的关闭和创建

    插入数据

    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type Student struct {
    	Id     int    `db:"id"`
    	Name   string `db:"name"`
    	Sex    string `db:"sex"`
    	Age    int    `db:"age"`
    	Course string `db:"course"`
    }
    
    var Db *sqlx.DB
    
    // 初始化数据库
    func init() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    	Db = sql
    }
    
    func main() {
    
    	// func (db *DB) Exec(query string, args ...interface{}) (Result, error)
    	reslut, err := Db.Exec("insert into student(name, sex, age, course)values(?, ?, ?, ?)", "张三", "男", 18, "Golang")
    	if err != nil {
    		fmt.Println("插入数据失败")
    		fmt.Printf("%v", err)
    		return
    	}
    	id, err := reslut.LastInsertId()
    	if err != nil {
    		fmt.Println("exec failed, ", err)
    		return
    	}
    	fmt.Println("插入的id为", id)
    
    }
    
    

    查询操作

    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type Student struct {
    	Id     int    `db:"id"`
    	Name   string `db:"name"`
    	Sex    string `db:"sex"`
    	Age    int    `db:"age"`
    	Course string `db:"course"`
    }
    
    var Db *sqlx.DB
    
    // 初始化数据库
    func init() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    	Db = sql
    }
    
    func main() {
    	var student []Student
    	// func (db *DB) Select(dest interface{}, query string, args ...interface{})
    	err := Db.Select(&student, "select id, name, sex, age, course from student where course=?", "Golang")
    	if err != nil {
    		fmt.Println("查询失败")
    	}
    	fmt.Println(student)
    }
    
    D:goprogramgosrcday08
    λ go run test.go         
    数据库连接成功                  
    [{1 张三 男 18 Golang}]     
                             
    

    修改操作

    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type Student struct {
    	Id     int    `db:"id"`
    	Name   string `db:"name"`
    	Sex    string `db:"sex"`
    	Age    int    `db:"age"`
    	Course string `db:"course"`
    }
    
    var Db *sqlx.DB
    
    // 初始化数据库
    func init() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    	Db = sql
    }
    
    func main() {
    	res, err := Db.Exec("update student set name=? where course=?", "李四", "Golang")
    	if err != nil {
    		fmt.Println("操作失败")
    		return
    	}
    	row, err := res.RowsAffected()
    	if err != nil {
    		fmt.Println("rows failed, ", err)
    	}
    	fmt.Println("update succ:", row)
    }
    

    删除操作

    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type Student struct {
    	Id     int    `db:"id"`
    	Name   string `db:"name"`
    	Sex    string `db:"sex"`
    	Age    int    `db:"age"`
    	Course string `db:"course"`
    }
    
    var Db *sqlx.DB
    
    // 初始化数据库
    func init() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    	Db = sql
    }
    func main() {
    	res, err := Db.Exec("delete from student where name=?", "李四")
    	if err != nil {
    		fmt.Println("删除数据失败")
    		return
    	}
    	row, err := res.RowsAffected()
    	if err != nil {
    		fmt.Println("rows faoiled")
    		return
    	}
    	fmt.Println(row)
    
    }
    

    修改和删除操作都比较简单,同插入数据类似,只是使用RowsAffected来获取影响的数据行数。

    Mysql事务

    MySQL 事务主要用于处理操作量大,复杂度高的数据。

    在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

    事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行。

    事务用来管理 insert,update,delete 语句

    一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

    Go语言MySQL事务应用包与函数:

    1) import ("github.com/jmoiron/sqlx")
    2)  conn, err := Db.Begin()    开始事务
    3)  conn.Commit()              提交事务
    4)  conn.Rollback()            回滚事务
    
    package main
    
    import (
    	"fmt"
    
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/jmoiron/sqlx"
    )
    
    type Student struct {
    	Id     int    `db:"id"`
    	Name   string `db:"name"`
    	Sex    string `db:"sex"`
    	Age    int    `db:"age"`
    	Course string `db:"course"`
    }
    
    var Db *sqlx.DB
    
    // 初始化数据库
    func init() {
    	// Open(driverName, dataSourceName string) (*DB, error)
    	// ("数据库类型", "用户名:密码@tcp(地址:端口)/数据库名")
    	sql, err := sqlx.Open("mysql", "root:123@tcp(127.0.0.1:3306)/oldboy")
    	if err != nil {
    		fmt.Println("打开数据库失败")
    	}
    	// func (db *DB) Ping() error
    	err = sql.Ping()
    	if err != nil {
    		fmt.Println("数据库连接失败")
    	} else {
    		fmt.Println("数据库连接成功")
    	}
    	Db = sql
    }
    
    func main() {
    	// 开始事务
    	// func (db *DB) Begin() (*Tx, error)
    	conn, err := Db.Begin()
    	if err != nil {
    		fmt.Println("begin failed")
    		return
    	}
    	r, err := Db.Exec("insert into student(name, sex, age, course)values(?, ?, ?, ?)", "王五", "男", 18, "Golang")
    	if err != nil {
    		fmt.Println("exec failed ")
    		conn.Rollback()
    		return
    	}
    	id, err := r.LastInsertId()
    	if err != nil {
    		fmt.Println("exec failed, ", err)
    		conn.Rollback()
    		return
    	}
    	fmt.Println("insert succ:", id)
    
    	r, err = Db.Exec("insert into student(name, sex, age, course)values(?, ?, ?, ?)", "赵六", "男", 18, "Linux、Python、Java")
    	if err != nil {
    		fmt.Println("exec failed, ", err)
    		conn.Rollback()
    		return
    	}
    	id, err = r.LastInsertId()
    	if err != nil {
    		fmt.Println("exec failed, ", err)
    		conn.Rollback()
    		return
    	}
    	fmt.Println("insert succ:", id)
    
    	conn.Commit()
    }
    
    D:goprogramgosrcday08
    λ go run test.go
    数据库连接成功
    insert succ: 2
    insert succ: 3
    

  • 相关阅读:
    hadoop常用命令详细解释
    2019-05-20 Sublime Text 编辑
    2019-05-20 什么是分布式系统、分布式锁
    2019-05-19 centos7下删掉一个目录下所有的文件
    2019-05-17 ABRT has detected 1 problem(s). For more info run: abrt-cli list --since 1558053651
    2019-05-17 java.net.BindException: Address already in use: JVM_Bind <null>:8083
    2019-05-16mysql忘记密码怎么办
    2019-05-16查看MySQL版本sql语句
    2019-05-15 cenots7动态IP地址改为静态
    2019-05-14 MySQL通过dos命令操作数据库
  • 原文地址:https://www.cnblogs.com/heych/p/12579643.html
Copyright © 2011-2022 走看看