学习Go语言基础类语法_Day10 数据库操作

1、golang操作mysql数据库

1.1、下载安装MySQL

https://dev.mysql.com/downloads/mysql/

1.1.1、配置环境变量

image
image
image
将bin目录路径粘贴上去
image

1.1.2、创建my.ini文件

在更目录下创建my.ini文件
image

[mysqld]
# 设置3306端口
port=3306
# 设置mysql的安装目录   
basedir=D:\\mysql-8.0.30-winx64
# 设置mysql数据库的数据的存放目录  
datadir=D:\\mysql-8.0.30-winx64\\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。
max_connect_errors=10
# 服务端使用的字符集默认为utf8mb4
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
#mysql_native_password
default_authentication_plugin=mysql_native_password
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[client]
# 设置mysql客户端连接服务端时默认使用的端口
port=3306
default-character-set=utf8mb4

1.1.3、执行mysqld --initialize --console

在MySQLbin目录执行以下命令

mysqld --initialize --console

image
如果出现这样情况就是说明data已经创建过了,删了data可以重新正常运行,如果data删不了的话需要按住win+r然后输入services.msc,回车找到mysql然后关闭它,就可以删了data了
image
执行成功后会给出一个临时密码
image

1.1.4、启动服务

D:\mysql-8.0.30-winx64\bin>net start mysql
MySQL 服务正在启动 .
MySQL 服务已经启动成功。

1.1.5、连接数据库

使用给的临时密码进行登录

D:\mysql-8.0.30-winx64\bin>mysql -uroot -pp6Tsa2=5ko8U
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.30

1.1.6、修改密码

alter user 'root'@'localhost' identified with mysql_native_password by '123456'

1.2、准备

1.2.1、创建一个go_db数据库

create database go_db

1.2.2、打开数据库

use go_db

1.2.3、创建表

CREATE TABLE user_tbl (
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  username VARCHAR (20),
  PASSWORD VARCHAR (20)
)

1.2.4、添加模拟数据

INSERT INTO user_tbl (username, PASSWORD) VALUES ("tom", "123")
INSERT INTO user_tbl (username, PASSWORD) VALUES ("kite", "456")

1.2.5、查看表属性

desc user_tbl

image

1.2.6、查看表数据

select * from user_tbl;

image

1.3、安装配置mysql驱动

1.3.1、安装驱动

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

1.3.2、初始化模块

go mod init m

1.3.3、导入驱动

package main

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

func main() {
	
}

1.3.4、执行go mod tidy

go mod tidy

1.4、获得数据库连接

1.4.1、导入包

package main

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

1.4.2、获得连接

package main

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

func main() {
	db, err := sql.Open("mysql", "root:123456@/go_db")
	if err != nil {
		panic(err)
	}
	print(db)
	// 最大连接时长
	db.SetConnMaxLifetime(time.Minute * 3)
	// 最大连接数
	db.SetMaxOpenConns(10)
	// 空闲连接数
	db.SetMaxIdleConns(10)
}

1.4.3、初始化连接

Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调用Ping方法。

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

package main

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

// 定义一个全局对象db
var db *sql.DB

// 定义一个初始化数据库的函数
func initDB() (err error) {
	dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
	// 不会校验账号密码是否正确
	// 注意!!!这里不要使用:=,我们是给全局变量赋值,然后在main函数中使用全局变量db
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		return err
	}
	// 尝试与数据库建立连接(校验dsn是否正确)
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil
}

func main() {
	err := initDB() // 调用输出化数据库的函数
	if err != nil {
		fmt.Printf("初始化失败!,err:%v\n", err)
		return
	}else{
		fmt.Printf("初始化成功")
	}
}

1.5、查询操作

1.5.1、单行查询

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

1.5.1.1、定义一个结构体

type user struct {
	id int
	username string
	password string
}

1.5.1.2、查询

// 查询一条用户数据
func queryRowDemo() {
	sqlStr := "select id, username, password from user_tbl where id=?"
	var u user
	// 确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
	err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.username, &u.password)
	if err != nil {
		fmt.Printf("scan failed, err:%v\n", err)
		return
	}
	fmt.Printf("id:%d name:%s age:%s\n", u.id, u.username, u.password)
}

1.5.1.3、测试

func main() {
	err := initDB() // 调用输出化数据库的函数
	if err != nil {
		fmt.Printf("初始化失败!,err:%v\n", err)
		return
	}else{
		fmt.Printf("初始化成功")
	}
	queryRowDemo()
}

运行结果

初始化成功id:1 name:tom age:123

1.5.2、查询多行

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

// 查询多条数据示例
func queryMultiRow() {
	sqlStr := "select id, username, password from user_tbl where id > ?"
	rows, err := db.Query(sqlStr, 0)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	// 非常重要:关闭rows释放持有的数据库链接
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() {
		var u user
		err := rows.Scan(&u.id, &u.username, &u.password)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			return
		}
		fmt.Printf("id:%d username:%s password:%s\n", u.id, u.username, u.password)
	}
}

运行结果

初始化成功
id:1 username:tom password:123
id:2 username:kite password:456

1.5.3、总代码

package main

import (
	"database/sql"
	"fmt"

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

var db *sql.DB

func initDB() (err error) {

	dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil

}

type user struct {
	id       int
	username string
	password string
}

func queryRowDemo() {
	s := "select id, username, password from user_tbl where id=?"
	var u user
	err := db.QueryRow(s, 1).Scan(&u.id, &u.username, &u.password)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("id:%d name:%s age:%s\n", u.id, u.username, u.password)

}

// 查询多条数据示例
func queryMultiRow() {
	sqlStr := "select id, username, password from user_tbl where id > ?"
	rows, err := db.Query(sqlStr, 0)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	// 非常重要:关闭rows释放持有的数据库链接
	defer rows.Close()

	// 循环读取结果集中的数据
	for rows.Next() {
		var u user
		err := rows.Scan(&u.id, &u.username, &u.password)
		if err != nil {
			fmt.Printf("scan failed, err:%v\n", err)
			return
		}
		fmt.Printf("id:%d username:%s password:%s\n", u.id, u.username, u.password)
	}
}

func main() {
	err := initDB()

	if err != nil {
		fmt.Printf("初始化失败!err: %v\n", err)
		return
	} else {
		fmt.Printf("初始化成功!\n")
	}
	queryRowDemo()
	queryMultiRow()
}

1.6、插入数据

1.6.1、使用语法

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

func (db *DB) Exec(query string, args ...interface{}) (Result, error)
// 插入数据
func insertData() {
	sqlStr := "insert into user_tbl(username,password) values (?,?)"
	ret, err := db.Exec(sqlStr, "张三", "zs123")
	if err != nil {
		fmt.Printf("insert failed, err:%v\n", err)
		return
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		fmt.Printf("get lastinsert ID failed, err:%v\n", err)
		return
	}
	fmt.Printf("insert success, the id is %d.\n", theID)
}

测试

func main() {
	err := initDB() // 调用输出化数据库的函数
	if err != nil {
		fmt.Printf("初始化失败!,err:%v\n", err)
		return
	}else{
		fmt.Printf("初始化成功\n")
	}
	//queryRowDemo()
	//queryMultiRow()
	insertData()
}

运行结果

初始化成功
insert success, the id is 3.

1.6.2、实例代码

package main

import (
	"database/sql"
	"fmt"

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

var db *sql.DB

func initDB() (err error) {

	dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil

}

func insertData() {
	s := "insert into user_tbl(username,password) values (?,?)"
	r, err := db.Exec(s, "Caidd123", "123")
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	i, err := r.LastInsertId()
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("插入成功,id为: %v\n", i)
}

func insertData2(username, password string) {
	s := "insert into user_tbl(username,password) values (?,?)"
	r, err := db.Exec(s, username, password)
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	i, err := r.LastInsertId()
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("插入成功,id为: %v\n", i)
}

func main() {
	err := initDB()

	if err != nil {
		fmt.Printf("初始化失败!err: %v\n", err)
		return
	} else {
		fmt.Printf("初始化成功!\n")
	}
	//insertData()
	insertData2("XE", "123456")
}

1.7、更新数据

1.7.1、使用语法

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

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

更新

func updateData()  {
	sql := "update user_tbl set username=?, password=? where id=?"
	ret, err := db.Exec(sql, "kite2", "kite123", "2")
	if err != nil {
		fmt.Printf("更新失败, err:%v\n", err)
		return
	}
	rows, err := ret.RowsAffected()
	if err != nil {
		fmt.Printf("更新行失败, err:%v\n", err)
		return
	}
	fmt.Printf("更新成功, 更新的行数: %d.\n", rows)
}

1.7.2、实例代码

package main

import (
	"database/sql"
	"fmt"

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

var db *sql.DB

func initDB() (err error) {

	dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil

}

func updateData() {
	s := "update user_tbl set username=?, password=? where id=?"
	r, err := db.Exec(s, "kite2", "kite123", "2")
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	i, err := r.RowsAffected()
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("更新成功,更新行数为: %v\n", i)
}

func main() {
	err := initDB()

	if err != nil {
		fmt.Printf("初始化失败!err: %v\n", err)
		return
	} else {
		fmt.Printf("初始化成功!\n")
	}
	updateData()
}

1.8、删除数据

1.8.1、使用语法

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

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

删除

func delData()  {
	sql := "delete from user_tbl where id =?"
	ret, err := db.Exec(sql, "1")
	if err != nil {
		fmt.Printf("删除失败, err:%v\n", err)
		return
	}
	rows, err := ret.RowsAffected()
	if err != nil {
		fmt.Printf("删除行失败, err:%v\n", err)
		return
	}
	fmt.Printf("删除成功, 删除的行数: %d.\n", rows)
}

1.8.2、实例代码

package main

import (
	"database/sql"
	"fmt"

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

var db *sql.DB

func initDB() (err error) {

	dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}
	err = db.Ping()
	if err != nil {
		return err
	}
	return nil

}

func delData() {
	s := "delete from user_tbl where id =?"
	r, err := db.Exec(s, "1")
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	i, err := r.RowsAffected()
	if err != nil {
		fmt.Printf("err: %v\n", err)
		return
	}
	fmt.Printf("删除成功,删除的行数为: %v\n", i)
}

func main() {
	err := initDB()

	if err != nil {
		fmt.Printf("初始化失败!err: %v\n", err)
		return
	} else {
		fmt.Printf("初始化成功!\n")
	}
	delData()
}
posted @ 2022-10-09 14:24  Caidd123  阅读(21)  评论(0)    收藏  举报