0. 操作思路
-
下载需要的对应依赖
"github.com/go-sql-driver/mysql"
-
数据库初始化操作
- 用户名密码等其他配置操作
-
创建数据库表结构体
-
编写对应数据库操作方法
-
测试运行
1. 直接代码操作
-
注意点
- 要创建数据库连接池对象
*sql.DB
- 要创建数据库表接受的对象struct
- 要创建数据库连接池对象
-
代码
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) var db *sql.DB //连接池对象 func initDB() (err error) { // DSN:Data Source Name dsn := "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True" db, err = sql.Open("mysql", dsn) //open不会校验用户名和密码是否正确 if err != nil { return } err = db.Ping() if err != nil { return } db.SetMaxOpenConns(10) //设置数据库连接池的最大连接数 10 db.SetMaxIdleConns(5) //设置最大空闲连接数 return } type user struct { //结构体 user_id int role_id int } func queryOne(id int) { var u1 user // 1.写查询单条记录的sql语句 sqlStr := "select user_id,role_id from sys_user_role where user_id =?;" //2.执行并拿到结果 //必须对row对象调用scan方法,该方法会释放数据库连接 db.QueryRow(sqlStr, id).Scan(&u1.user_id, &u1.role_id) //从连接池拿一个连接出去数据库查询单条记录 //打印结果 fmt.Println(u1) } func main() { err := initDB() if err != nil { fmt.Printf("init DB failed err:%v\n", err) } fmt.Println("连接数据库成功") queryOne(2) }
2. 配置文件抽取
2.0 数据库建表
CREATE TABLE `sys_user_role` (
`user_id` varchar(64) NOT NULL COMMENT '用户编号',
`role_id` varchar(64) NOT NULL COMMENT '角色编号',
PRIMARY KEY (`user_id`,`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户-角色';
2.1 下载依赖
go get -u github.com/go-sql-driver/mysql
2.2 编写配置文件
mysql:
user : root
password : root
host : 127.0.0.1
port : 3306
dbname : dns_manager
2.3 配置文件读取
-
配置文件对应结构体
type Sqls struct { Mysql struct {// todo 配置文件里面是结构体 结构体名称要大写 不要名称冲突 User string `yaml:"user"` Passwd string `yaml:"password"` Host string `yaml:"host"` Port int `yaml:"port"` Name string `yaml:"dbname"` } }
-
操作文件读取
func ReadYaml(initFile string) (*os.File,error){ // 打开文件 //dbConfig, err := os.Open("B:\code\go\workspace\go_mysql\db.yml") dbConfig, err := os.Open(initFile) if err != nil{ log.Fatalf("os.Open() failed with `%s` \n",err) return nil,err } return dbConfig,nil }
2.4 初始化链接
2.4.1 mysql驱动链接介绍
-
使用方法
func Open(driverName, driverName string) (*DB, error)
-
字段介绍
- driverName:指定数据库
- driverName:指定数据源
-
作用:sql.Open打开一个指定源头的数据库
import ( "database/sql" _ "github.com/go-sql-driver/mysql" ) func main() { dsn := "user:password@tcp(127.0.0.1:3306)/dbname" db, err := sql.Open("mysql", dsn) if err != nil { panic(err) } defer db.Close() }
2.4.2 初始化函数封装
-
注意点
- 导入的依赖要空值接受
*sql.DB
数据库连接对象- 配置文件读取
- 数据库url字符串链接
- 非查询需要启用事务
-
代码
// 初始化数据库配置 func initSql(initFile string) (*sql.DB, error ) { file, err := ReadYaml(initFile) // 操作文件 defer file.Close() // 读取文件流 decoder := yaml.NewDecoder(file) // 创建变量并赋值 var sqls Sqls err = decoder.Decode(&sqls)// 解码 if err != nil{ log.Fatalf("dec.Decode() failed with `%s` \n",err) return nil,err } // mysql中封装了对应的数据库配置 //"root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True" url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", sqls.Mysql.User, sqls.Mysql.Passwd, sqls.Mysql.Host, sqls.Mysql.Port,// TODO 拼接url sqls.Mysql.Name) open, err := sql.Open("mysql", url) //open, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True") if err != nil{ log.Fatalf("配置文件出错,原因为 %s\n",err) return nil,err } err = open.Ping() if err != nil { log.Fatalf("数据库连接失败,错误为%s\n",err) return nil,err } return open,nil }
2.5 插入
-
代码
// 插入角色 func InsertUser(userRole UserRole ,db *sql.DB) bool{ // 增加事务 begin, err2 := db.Begin() if err2 != nil{ log.Fatalf("err:%s",err2) return false } // sql prepare, err2 := begin.Prepare("INSERT INTO sys_user_role (`user_id`,`role_id`) value (?,?)") if err2 != nil { fmt.Println("Prepare fail") return false } // 执行 res, err2 := prepare.Exec(userRole.userId, userRole.roleId) fmt.Println(res) if err2 != nil{ fmt.Println("Exec fail") return false } // 事务 begin.Commit() return true }
2.6 修改
-
代码
func DeleteByUid(uid string,db *sql.DB) bool{ // 增加事务 begin, err := db.Begin() if err != nil{ log.Fatalf("err:%s",err) return false } // sql prepare, err2 := begin.Prepare("delete from sys_user_role where user_id = ?") if err2 != nil { fmt.Println("Prepare fail") return false } // 执行 res, err2 := prepare.Exec(uid) fmt.Println(res) if err2 != nil{ fmt.Println("Exec fail") return false } // 事务 begin.Commit() return true }
2.7 删除
-
代码
func UpdateUser(user UserRole,db *sql.DB) (bool) { //开启事务 tx, err := db.Begin() if err != nil{ fmt.Println("tx fail") } //准备sql语句 stmt, err := tx.Prepare("UPDATE sys_user_role SET user_id = ? WHERE role_id = ?") if err != nil{ fmt.Println("Prepare fail") return false } //设置参数以及执行sql语句 res, err := stmt.Exec(user.userId, user.roleId) fmt.Println(res) if err != nil{ fmt.Println("Exec fail") return false } //提交事务 tx.Commit() return true }
2.8 查询
-
代码
func SelectUserById(uid string,db *sql.DB) UserRole { var user UserRole err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId) if err != nil{ fmt.Println("查询出错了") } return user }
2.9 调用
-
代码
func SelectUserById(uid string,db *sql.DB) UserRole { var user UserRole err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId) if err != nil{ fmt.Println("查询出错了") } return user }
3. 完整代码
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"// todo 需要这样导入
"gopkg.in/yaml.v3"
"log"
"os"
)
type UserRole struct {
userId string
roleId string
}
type Sqls struct {
Mysql struct {// todo 配置文件里面是结构体 结构体名称要大写 不要名称冲突
User string `yaml:"user"`
Passwd string `yaml:"password"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Name string `yaml:"dbname"`
}
}
func main() {
filePath := "B:\code\go\workspace\go_mysql\db.yml"
open,_ := initSql(filePath)
var userRole UserRole
userRole.roleId = "23324"
userRole.userId = "23234"
//todo 非查询需要添加事务 插入
insertUser := InsertUser(userRole, open)
if insertUser {
log.Fatal("插入成功\n")
}
//
//// 删除
//uid := DeleteByUid("23", open)
//if uid {
// log.Fatal("删除成功\n")
//}
//var userRole2 UserRole
//userRole2.roleId = "23"
//userRole2.userId = "23"
//// 修改
//updateUser := UpdateUser(userRole2, open)
//if updateUser {
// log.Fatal("修改成功\n")
//}
//
////查询
//id := SelectUserById("2", open)
//fmt.Println(1,id.roleId)
}
func ReadYaml(initFile string) (*os.File,error){
// 打开文件
//dbConfig, err := os.Open("B:\code\go\workspace\go_mysql\db.yml")
dbConfig, err := os.Open(initFile)
if err != nil{
log.Fatalf("os.Open() failed with `%s` \n",err)
return nil,err
}
return dbConfig,nil
}
// 初始化数据库配置
func initSql(initFile string) (*sql.DB, error ) {
file, err := ReadYaml(initFile)
// 操作文件
defer file.Close()
// 读取文件流
decoder := yaml.NewDecoder(file)
// 创建变量并赋值
var sqls Sqls
err = decoder.Decode(&sqls)// 解码
if err != nil{
log.Fatalf("dec.Decode() failed with `%s` \n",err)
return nil,err
}
// mysql中封装了对应的数据库配置
//"root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True"
url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True", sqls.Mysql.User, sqls.Mysql.Passwd,
sqls.Mysql.Host, sqls.Mysql.Port,// TODO 拼接url
sqls.Mysql.Name)
open, err := sql.Open("mysql", url)
//open, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/dns_manager?charset=utf8&parseTime=True")
if err != nil{
log.Fatalf("配置文件出错,原因为 %s\n",err)
return nil,err
}
err = open.Ping()
if err != nil {
log.Fatalf("数据库连接失败,错误为%s\n",err)
return nil,err
}
return open,nil
}
// 插入角色
func InsertUser(userRole UserRole ,db *sql.DB) bool{
// 增加事务
begin, err2 := db.Begin()
if err2 != nil{
log.Fatalf("err:%s",err2)
return false
}
// sql
prepare, err2 := begin.Prepare("INSERT INTO sys_user_role (`user_id`,`role_id`) value (?,?)")
if err2 != nil {
fmt.Println("Prepare fail")
return false
}
// 执行
res, err2 := prepare.Exec(userRole.userId, userRole.roleId)
fmt.Println(res)
if err2 != nil{
fmt.Println("Exec fail")
return false
}
// 事务
begin.Commit()
return true
}
func DeleteByUid(uid string,db *sql.DB) bool{
// 增加事务
begin, err := db.Begin()
if err != nil{
log.Fatalf("err:%s",err)
return false
}
// sql
prepare, err2 := begin.Prepare("delete from sys_user_role where user_id = ?")
if err2 != nil {
fmt.Println("Prepare fail")
return false
}
// 执行
res, err2 := prepare.Exec(uid)
fmt.Println(res)
if err2 != nil{
fmt.Println("Exec fail")
return false
}
// 事务
begin.Commit()
return true
}
func UpdateUser(user UserRole,db *sql.DB) (bool) {
//开启事务
tx, err := db.Begin()
if err != nil{
fmt.Println("tx fail")
}
//准备sql语句
stmt, err := tx.Prepare("UPDATE sys_user_role SET user_id = ? WHERE role_id = ?")
if err != nil{
fmt.Println("Prepare fail")
return false
}
//设置参数以及执行sql语句
res, err := stmt.Exec(user.userId, user.roleId)
fmt.Println(res)
if err != nil{
fmt.Println("Exec fail")
return false
}
//提交事务
tx.Commit()
return true
}
func SelectUserById(uid string,db *sql.DB) UserRole {
var user UserRole
err := db.QueryRow("SELECT * FROM sys_user_role WHERE user_id = ?", uid).Scan(&user.userId,&user.roleId)
if err != nil{
fmt.Println("查询出错了")
}
return user
}