1.新建一个数据库名hui,数据库表名roles表结构如下图:

image.png
其中avatar字段保存的是二进制数据。
2.创建与表结构映射的结构体,方便存储读取数据。
3.具体简单示例如下代码:
package main
//Go语言中的database/sql包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的数据库驱动。
//使用database/sql包时必须注入(至少)一个数据库驱动。
import (
"fmt"
"io/ioutil"
"log"
"database/sql" //接口
_ "github.com/go-sql-driver/mysql" //MySQL驱动
)
//其中sql.DB是表示连接的数据库对象(结构体实例),它保存了连接数据库相关的所有信息。
//它内部维护着一个具有零到多个底层连接的连接池,它可以安全地被多个goroutine同时使用。
// 定义一个全局对象db
var db *sql.DB
func initDB() (err error) {
//事实上这个数据库中并不存在这个student库,但是Open没有返回err
//Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。
dsn := "root:root123456@tcp(127.0.0.1:3306)/hui"
db, err = sql.Open("mysql", dsn)
if err != nil {
return err
}
// 尝试与数据库建立连接(校验dsn是否正确)
err = db.Ping()
if err != nil {
return err
}
//设置数据库连接池的最大连接数
db.SetMaxOpenConns(4)
//设置数据库连接池的最大空闲连接数
db.SetMaxIdleConns(4)
return nil
}
//表映射结构
type Role struct {
Role_id int32
Role_name string
Avatar []byte
Sex byte
}
//更新一个用户
func UpdateRoleData(role_id int32, role *Role) error {
sqlStr := "update roles set role_id =?,role_name=?, avatar=?,sex=? where role_id = ?"
ret, err := db.Exec(sqlStr, role.Role_id, role.Role_name, role.Avatar, role.Sex, role_id)
if err != nil {
fmt.Printf("update failed, err:%v\n", err)
return err
}
n, err := ret.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return err
}
fmt.Printf("update success, affected rows:%d\n", n)
return nil
}
//删除一个用户
func DeleteRoleData(role_id int32) error {
sqlStr := "delete from roles where role_id = ?"
ret, err := db.Exec(sqlStr, role_id) //执行删除语句
if err != nil {
fmt.Printf("delete failed, err:%v\n", err)
return err
}
n, err := ret.RowsAffected() // 操作影响的行数
if err != nil {
fmt.Printf("get RowsAffected failed, err:%v\n", err)
return err
}
fmt.Printf("delete success, affected rows:%d\n", n)
return nil
}
//插入一条数据
func InsertRoleData(role *Role) error {
//使用func (db *DB) Exec(query string, args ...interface{}) (Result, error)插入数据
sql := "INSERT INTO `roles` (`role_id`, `role_name`, `sex`, `avatar`) VALUES (?, ?, ?, ?)"
res, err := db.Exec(sql, role.Role_id, role.Role_name, role.Sex, role.Avatar)
if err != nil {
return err
}
fmt.Println("db.Exec success:=", res)
return nil
}
// 查询单条数据
func QueryRoleData(role *Role) error {
sqlStr := "select * from `roles` where role_id= ? "
// 非常重要:确保QueryRow之后调用Scan方法,否则持有的数据库链接不会被释放
err := db.QueryRow(sqlStr, 1).Scan(&role.Role_id, &role.Role_name, &role.Sex, &role.Avatar)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return err
}
return nil
}
func main() {
err := initDB()
if err != nil {
log.Fatalln(err)
}
data, err := ioutil.ReadFile("my.png")
if err != nil {
log.Println(err)
return
}
role := &Role{
Role_name: "jian",
Avatar: data,
Sex: 1,
}
//插入一行数据
err = InsertRoleData(role)
if err != nil {
log.Println("InsertRoleData err:=", err)
return
}
//读取一个role数据
err = QueryRoleData(role)
if err != nil {
fmt.Println("QueryRoleData err:=", err)
}
//将读取二进制保存到一个文件中
//ioutil.WriteFile("newmy.png", role.Avatar, 0777)
//删除一个role
err = DeleteRoleData(1)
if err != nil {
fmt.Println("DeleteRoleData err:=", err)
}
//更新一个role数据
role.Role_id = 0
err = UpdateRoleData(2, role)
if err != nil {
fmt.Println("UpdateRoleData err:=", err)
}
}