学习的q1mi老师的视频
Go操作常见数据库
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
//连接数据库
//创建数据库信息
dsn := "root:root@tcp(127.0.0.1:3306)/sql_test"
//只能检验dsn格式是否正确
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
defer db.Close() //这行要在err下面,程序会先注册defer,要确保没有err。
//验证能否真正连接数据库
err = db.Ping()
if err != nil {
fmt.Printf("connect to db failed :%v\n", err)
}
fmt.Println("connect to db success")
}
按照项目结构分层,应该将数据库相关函数,摘出来,如下
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
// 全局db对象
var db *sql.DB
func InitMysql() (err error) {
//创建数据库信息
dsn := "root:root@tcp(127.0.0.1:3306)/gin_orm"
//只能检验dsn格式是否正确
db, err = sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
//验证能否真正连接数据库
err = db.Ping()
if err != nil {
fmt.Printf("connect to db failed :%v\n", err)
return
}
return
}
func main() {
//连接数据库
err := InitMysql()
if err != nil {
panic(err)
}
defer db.Close() //这行要在err下面,程序会先注册defer,要确保没有err。
fmt.Println("connect to db success")
}
mysql连接数
根据业务具体情况来定
增删改查操作
创建数据库
CREATE DATABASE sql_test;
进入数据库
use sql_test;
创建表
CREATE TABLE `user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT '',
`age` INT(11) DEFAULT '0',
PRIMARY KEY(`id`)
)ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
go操作原生sql
查询单行
// 原生sql查询
func queryRowDemo() {
//查询sql
sqlStr := "select id,age,name from user where id=?"
var u user
//将查询内容,手动映射赋值给u,比较繁琐
//查询后,必须scan释放连接数,所以写成链式
if err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.age, &u.name); err != nil {
fmt.Printf("select failed ,err:%v\n", err)
return
}
fmt.Printf("id:%d,age:%d,name:%s", u.id, u.age, u.name)
}
查询多行
插入单行
// 原生sql插入
func insertRowDemo() {
sqlStr := "insert into user (name,age) values (?,?)"
ret, err := db.Exec(sqlStr, "zhangchi", 18)
if err != nil {
fmt.Printf("insert failed ,err:%v\n", err)
}
var id int64
id, err = ret.LastInsertId() //新插入数据的id
if err != nil {
fmt.Printf("get lastinser ID failed,err:%v", err)
}
fmt.Printf("insert success,the id is %d\n", id)
}
删除数据
mysql预处理
使用场景,批量执行sql语句,sql命令一样,占位符数据不一样
预处理关键字Prepare
sql注入
where永远成立
还有以下
事务
go 操作sqlx
连接数据库,如下
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
)
func main() {
if err := initDB(); err != nil {
fmt.Printf("connect to db failed ,err:%v\n", err)
}
fmt.Println("connect to db success")
defer db.Close()
}
var db *sqlx.DB
func initDB() (err error) {
dsn := "root:root@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True"
// 也可以使用MustConnect连接不成功就panic
db, err = sqlx.Connect("mysql", dsn) //封装了open()和ping()
if err != nil {
fmt.Printf("connect DB failed, err:%v\n", err)
return
}
db.SetMaxOpenConns(200)
db.SetMaxIdleConns(10)
return
}
查询
type user struct {
ID int `db:"id"`
Age int `db:"age"`
Name string `db:"name"`
}
// 查询单条数据示例
func queryRowDemo() {
sqlStr := "select id, name, age from user where id=?"
var u user
err := db.Get(&u, sqlStr, 1)
if err != nil {
fmt.Printf("get failed, err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%d\n", u.ID, u.Name, u.Age)
}
查询多条
// 查询多条数据示例
func queryMultiRowDemo() {
sqlStr := "select id, name, age from user where id > ?"
var users []user
err := db.Select(&users, sqlStr, 0)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
fmt.Printf("users:%#v\n", users)
}
根据map或结构体查询
sqlx事务和原生sql一样,begin改为beginx
bindvars
sql.in
go-redis
连接数据库
package main
import (
"fmt"
"github.com/go-redis/redis"
)
var rdb *redis.Client
func main() {
err := initRedis()
if err != nil {
fmt.Printf("connect to redis failed err:%v\n", err)
return
}
fmt.Println("connect to redis success")
defer rdb.Close()
}
func initRedis() (err error) {
rdb = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // 密码
DB: 0, // 数据库
PoolSize: 20, // 连接池大小
})
_, err = rdb.Ping().Result()
return err
}
日志
原生日志
zap日志
使用zap
go-web脚手架
创建配置文件
创建settings文件夹,创建config.yaml配置文件