go语言操作MySQL

下载依赖

go get -u github.com/go-sql-driver/mysql

使用MySQL驱动

func Open(driverName, dataSourceName string) (*DB, error)

Open打开一个dirverName指定的数据库,dataSourceName指定数据源,一般至少包括数据库文件名和其它连接必要的信息。

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	dsn := "mysql:password@tcp(127.0.0.1:3306)/boor"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer db.Close()
}

为什么上面代码中的defer db.Close()语句不应该写在if err != nil的前面呢
初始化连接
Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调用Ping方法。

返回的DB对象可以安全地被多个goroutine并发使用,并且维护其自己的空闲连接池。因此,Open函数应该仅被调用一次,很少需要关闭这个DB对象。

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func main() {
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer db.Close()
}

其中sql.DB是表示连接的数据库对象(结构体实例),它保存了连接数据库相关的所有信息。它内部维护着一个具有零到多个底层连接的连接池,它可以安全地被多个goroutine同时使用。

SetMaxOpenConns
func (db *DB) SetMaxOpenConns(n int)
SetMaxOpenConns设置与数据库建立连接的最大数目。 如果n大于0且小于最大闲置连接数,会将最大闲置连接数减小到匹配最大开启连接数的限制。 如果n<=0,不会限制最大开启连接数,默认为0(无限制)。

SetMaxIdleConns
func (db *DB) SetMaxIdleConns(n int)
SetMaxIdleConns设置连接池中的最大闲置连接数。 如果n大于最大开启连接数,则新的最大闲置连接数会减小到匹配最大开启连接数的限制。 如果n<=0,不会保留闲置连接。

查询
单行查询db.QueryRow()执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。(如:未找到结果)

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type user struct {
	id   int
	name string
}

func selct(db *sql.DB) (users *user, err error) {
	u := user{}
	sqlStr := "select id,username from doorindex_username "
	err = db.QueryRow(sqlStr).Scan(&u.id, &u.name)
	if err != nil {
		return nil, err
	}
	return &u, nil
}

func main() {
	var db *sql.DB
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	u, err := selct(db)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("%T,%v\n", u.id, u.id)
	fmt.Printf("%T,%v\n", u.name, u.name)
	defer db.Close()
}

多行查询
多行查询db.Query()执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type user struct {
	id   int
	name string
}

func selct(db *sql.DB) (users *sql.Rows, err error) {
	sqlStr := "select id,username from doorindex_username"
	rows, err := db.Query(sqlStr)
	if err != nil {
		return nil, err
	}

	return rows, nil
}

func main() {
	var u user
	var db *sql.DB
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	rows, err := selct(db)
	if err != nil {
		fmt.Println(err, "rows")
	}
	for rows.Next() {
		err := rows.Scan(&u.id, &u.name)
		if err != nil {
			fmt.Println(err, "scan")
		}
	}
	fmt.Println(u.id, u.name, "user")
	defer rows.Close()
	defer db.Close()
}

插入数据
插入、更新和删除操作都使用Exec方法。

func (db *DB) Exec(query string, args ...interface{}) (Result, error)

Exec执行一次命令(包括查询、删除、更新、插入等),返回的Result是对已执行的SQL命令的总结。参数args表示query中的占位参数。

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type user struct {
	id   int
	name string
}

func selct(db *sql.DB) (users sql.Result, err error) {
	sqlStr := "INSERT INTO doorindex_username(id,username,jurisdiction) VALUE (?,?,?)"
	resu, err := db.Exec(sqlStr, 3, "13555202017", 0)
	if err != nil {
		return nil, err
	}

	return resu, nil
}

func main() {
	var db *sql.DB
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	//获取sql.Result
	resu, err := selct(db)
	if err != nil {
		fmt.Println(err, "rows")
	}
	//执行保存,v是执行后的状态
	v, ok := resu.LastInsertId()
	fmt.Println(ok)
	fmt.Println(v)
	defer db.Close()
}

修改操作

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

type user struct {
	id   int
	name string
}

func selct(db *sql.DB) (users sql.Result, err error) {
	sqlStr := "UPDATE doorindex_username set username=? where id=?"
	resu, err := db.Exec(sqlStr, "123456789", 3)
	if err != nil {
		return nil, err
	}

	return resu, nil
}

func main() {
	var db *sql.DB
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	resu, err := selct(db)
	if err != nil {
		fmt.Println(err, "rows")
	}
	//执行修改操作,v是执行的状态
	v, ok := resu.RowsAffected()
	fmt.Println(ok)
	fmt.Println(v)
	defer db.Close()
}

执行删除操作

package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

func selct(db *sql.DB) (users sql.Result, err error) {
	sqlStr := "DELETE FROM doorindex_username where id=?"
	resu, err := db.Exec(sqlStr, 3)
	if err != nil {
		return nil, err
	}

	return resu, nil
}

func main() {
	var db *sql.DB
	dsn := "root:123456@tcp(127.0.0.1:3306)/door?charset=utf8mb4&parseTime=True"
	db, err := sql.Open("mysql", dsn)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = db.Ping()
	if err != nil {
		fmt.Println(err)
		return
	}
	resu, err := selct(db)
	if err != nil {
		fmt.Println(err, "rows")
	}
	//执行删除操作,v是执行的状态
	v, ok := resu.RowsAffected()
	fmt.Println(ok)
	fmt.Println(v)
	defer db.Close()
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值