Golang操作mysql数据库-准备数据库和表
下载安装MySQL
1
| https://dev.mysql.com/downloads/mysql/
|
创建一个go_db数据库
打开数据库
创建表
1 2 3 4 5
| CREATE TABLE user_tbl ( id INTEGER PRIMARY KEY AUTO_INCREMENT, username VARCHAR (20), PASSWORD VARCHAR (20) )
|
添加模拟数据
1 2
| INSERT INTO user_tbl (username, PASSWORD) VALUES ("tom", "123") INSERT INTO user_tbl (username, PASSWORD) VALUES ("kite", "456")
|
Golang操作mysql数据库-安装配置mysql驱动
安装驱动
1
| go get -u github.com/go-sql-driver/mysql
|
初始化模块
执行go mod tidy
导入驱动
1 2 3 4 5 6 7 8 9 10 11
| package main
import ( "fmt" "database/sql" _ "github.com/go-sql-driver/mysql" )
func main() {
}
|
Golang操作mysql数据库-获得数据库连接
导入包
1 2 3 4 5 6 7
| package main
import ( "fmt" "database/sql" _ "github.com/go-sql-driver/mysql" )
|
获得连接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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) }
|
初始化连接
Open函数可能只是验证其参数格式是否正确,实际上并不创建与数据库的连接。如果要检查数据源的名称是否真实有效,应该调用Ping方法。
返回的DB对象可以安全地被多个goroutine并发使用,并且维护其自己的空闲连接池。因此,Open函数应该仅被调用一次,很少需要关闭这个DB对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 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 { return err } 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("初始化成功") } }
|
Golang操作mysql数据库-查询操作
单行查询
单行查询 db.QueryRow()
执行一次查询,并期望返回最多一行结果(即Row)。QueryRow总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。
定义一个结构体
1 2 3 4 5
| type user struct { id int username string password string }
|
查询
1 2 3 4 5 6 7 8 9 10 11 12
| func queryRowDemo() { sqlStr := "select id, username, password from user_tbl where id=?" var u user 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 2 3 4 5 6 7 8 9 10
| func main() { err := initDB() if err != nil { fmt.Printf("初始化失败!,err:%v\n", err) return }else{ fmt.Printf("初始化成功") } queryRowDemo() }
|
运行结果
1
| 初始化成功id:1 name:tom age:123
|
查询多行
多行查询 db.Query()
执行一次查询,返回多行结果(即Rows),一般用于执行select命令。参数args表示query中的占位参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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 } 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) } }
|
运行结果
1 2 3
| 初始化成功 id:1 username:tom password:123 id:2 username:kite password:456
|
Golang操作mysql数据库-插入数据
插入、更新和删除操作都使用 Exec
方法。
1
| func (db *DB) Exec(query string, args ...interface{}) (Result, error)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 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() if err != nil { fmt.Printf("get lastinsert ID failed, err:%v\n", err) return } fmt.Printf("insert success, the id is %d.\n", theID) }
|
测试
1 2 3 4 5 6 7 8 9 10 11 12
| func main() { err := initDB() if err != nil { fmt.Printf("初始化失败!,err:%v\n", err) return }else{ fmt.Printf("初始化成功\n") } insertData() }
|
运行结果
1 2
| 初始化成功 insert success, the id is 3.
|
Golang操作mysql数据库-删除数据
插入、更新和删除操作都使用 Exec
方法。
1
| func (db *DB) Exec(query string, args ...interface{}) (Result, error)
|
删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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 2 3 4 5 6 7 8 9 10
| func main() { err := initDB() if err != nil { fmt.Printf("初始化失败!,err:%v\n", err) return }else{ fmt.Printf("初始化成功\n") } delData() }
|
运行结果
Golang操作mysql数据库-更新数据
插入、更新和删除操作都使用 Exec
方法。
1
| func (db *DB) Exec(query string, args ...interface{}) (Result, error)
|
更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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 2 3 4 5 6 7 8 9 10 11 12 13 14
| func main() { err := initDB() if err != nil { fmt.Printf("初始化失败!,err:%v\n", err) return }else{ fmt.Printf("初始化成功\n") } updateData() }
|
运行结果
Golang操作MongoDB-下载安装MongoDB
下载地址:
1
| https://www.mongodb.com/download-center/community
|
打开客户端
创建数据库
创建集合
1
| db.createCollection("student");
|
Golang操作MongoDB-下载安装驱动并连接数据库
下载地址:
1
| https://www.mongodb.com/download-center/community
|
打开客户端
创建数据库
创建集合
1
| db.createCollection("student");
|
下载驱动
1
| go get github.com/mongodb/mongo-go-driver
|
连接mongoDB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| package main
import ( "context" "fmt" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" "log" )
var client *mongo.Client
func initDB() { clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") var err error client, err = mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!") }
func main() { initDB() }
|
运行结果
Golang操作MongoDB-BSON简介
MongoDB中的JSON文档存储在名为BSON(二进制编码的JSON)的二进制表示中。与其他将JSON数据存储为简单字符串和数字的数据库不同,BSON编码扩展了JSON表示,使其包含额外的类型,如int、long、date、浮点数和decimal128。这使得应用程序更容易可靠地处理、排序和比较数据。
连接MongoDB的Go驱动程序中有两大类型表示BSON数据:D
和 Raw
。
类型 D
家族被用来简洁地构建使用本地Go类型的BSON对象。这对于构造传递给MongoDB的命令特别有用。D
家族包括四类:
- D:一个BSON文档。这种类型应该在顺序重要的情况下使用,比如MongoDB命令。
- M:一张无序的map。它和D是一样的,只是它不保持顺序。
- A:一个BSON数组。
- E:D里面的一个元素。
要使用BSON,需要先导入下面的包:
1
| import "go.mongodb.org/mongo-driver/bson"
|
下面是一个使用D类型构建的过滤器 文档的例子,它可以用来查找name字段与’张三’或’李四’匹配的文档:
1 2 3 4 5 6 7
| bson.D{{ "name", bson.D{{ "$in", bson.A{"张三", "李四"}, }}, }}
|
Raw
类型家族用于验证字节切片。你还可以使用 Lookup()
从原始类型检索单个元素。如果你不想要将BSON反序列化成另一种类型的开销,那么这是非常有用的。这个教程我们将只使用D类型。
Golang操作MongoDB-添加文档
创建一个结构体
1 2 3 4
| type Student struct { Name string Age int }
|
添加单个文档
使用 collection.InsertOne()
方法插入一条文档记录:
1 2 3 4 5 6 7 8 9
| func insertOne(s Student) { initDB() collection := client.Database("go_db").Collection("student") insertResult, err := collection.InsertOne(context.TODO(), s) if err != nil { log.Fatal(err) } fmt.Println("Inserted a single document: ", insertResult.InsertedID) }
|
测试
1 2 3 4
| func main() { s := Student{Name: "tom", Age: 20} insertOne(s) }
|
运行结果
1 2
| Connected to MongoDB! Inserted a single document: ObjectID("61124558682f5c9583330222")
|
客户端查看
1 2 3 4
| mongodb 打开客户端 use go_db db.student.find() db.student.remove({}) // 删除所有
|
插入多个文档
使用 collection.InsertMany()
方法插入多条文档记录:
1 2 3 4 5 6 7 8 9 10
| func insertMore(students []interface{}) { initDB() collection := client.Database("go_db").Collection("student") insertManyResult, err := collection.InsertMany(context.TODO(), students) if err != nil { log.Fatal(err) } fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs) }
|
测试
1 2 3 4 5 6 7
| func main() { s := Student{Name: "tom", Age: 20} s1 := Student{Name: "kite", Age: 21} s2 := Student{Name: "rose", Age: 22} students := []interface{}{s, s1, s2} insertMore(students) }
|
运行结果
1 2
| Connected to MongoDB! Inserted multiple documents: [ObjectID("611246c56637c3554426bc92") ObjectID("611246c56637c3554426bc93") ObjectID("611246c56637c3554426bc94")]
|
更多方法请查阅官方文档。
Golang操作MongoDB-查找文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| package main
import ( "context" "fmt" "log" "time"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" )
var client *mongo.Client func initDB() { clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
co := options.Client().ApplyURI("mongodb://localhost:27017") mongo.Connect(context.TODO(), co) var err error client, err = mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) }
client.Ping(context.TODO(), nil) err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!") }
func find() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() collection := client.Database("go_db").Collection("student") cur, err := collection.Find(ctx, bson.D{}) if err != nil { log.Fatal(err) } defer cur.Close(ctx) for cur.Next(ctx) { var result bson.D err := cur.Decode(&result) if err != nil { log.Fatal(err) } fmt.Printf("result: %v\n", result) fmt.Printf("result.Map(): %v\n", result.Map()["name"]) } if err := cur.Err(); err != nil { log.Fatal(err) } }
func main() { initDB() find() }
|
Golang操作MongoDB-更新文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package main
import ( "context" "fmt" "log"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" )
type Student struct { Name string Age int }
var client *mongo.Client
func initDb() { co := options.Client().ApplyURI("mongodb://localhost:27017") c, err := mongo.Connect(context.TODO(), co) if err != nil { log.Fatal(err) }
err2 := c.Ping(context.TODO(), nil) if err2 != nil { log.Fatal(err2) } else { fmt.Println("连接成功!") } client = c }
func update() { ctx := context.TODO() defer client.Disconnect(ctx) c := client.Database("go_db").Collection("Student")
update := bson.D{{"$set", bson.D{{"Name", "big tom"}, {"Age", 22}}}}
ur, err := c.UpdateMany(ctx, bson.D{{"name", "tom"}}, update) if err != nil { log.Fatal(err) } fmt.Printf("ur.ModifiedCount: %v\n", ur.ModifiedCount) }
func main() { initDb() update() }
|
Golang操作MongoDB-删除文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package main
import ( "context" "fmt" "log"
"go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" )
type Student struct { Name string Age int }
var client *mongo.Client
func initDb() { co := options.Client().ApplyURI("mongodb://localhost:27017") c, err := mongo.Connect(context.TODO(), co) if err != nil { log.Fatal(err) }
err2 := c.Ping(context.TODO(), nil) if err2 != nil { log.Fatal(err2) } else { fmt.Println("连接成功!") } client = c }
func del() {
initDb() c := client.Database("go_db").Collection("Student") ctx := context.TODO()
dr, err := c.DeleteMany(ctx, bson.D{{"Name", "big kite"}})
if err != nil { log.Fatal(err) } fmt.Printf("ur.ModifiedCount: %v\n", dr.DeletedCount)
}
func main() { del() }
|