这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
(内容根据字节跳动青训营课程内容以及自己的理解编写)
近期将日更这几个主题的文章,欢迎关注!
- 全面理解go协程
- channel通信
- Kitex
- Gorm
- Hertx
- go的测试环节
- go的内存管理
- go的性能优化及工具
这里是用go自带的原生库写的(相当于Java的JDBC)后面的文章会有Gorm等数据库框架
Go实现简单的增删改查
相信大家对CRUD已经快写烂了,这里就以模板+注意点的形式
简单连接数据库的代码
我们在go_orm表里新建一个user表
"CREATE TABLE user(id INT NOT NULL , name VARCHAR(20),password VARCHAR(12), PRIMARY KEY(ID));
直接调用db对象就行
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
// 新建数据库连接,并且捕获错误
db, err := sql.Open("mysql", "root:abc123@tcp(127.0.0.1:3306)/go_orm")
err = db.Ping()
if err != nil {
return
}
defer func(db *sql.DB) { // defer hu=
err := db.Close()
if err != nil {
}
}(db) // 这边这个写法的意思就是写了一个匿名函数,然后直接调用
if err != nil {
fmt.Println("数据库连接失败!")
log.Fatalln(err)
}
_, err2 := db.Exec("CREATE TABLE user(id INT NOT NULL , name VARCHAR(20),password VARCHAR(12), PRIMARY KEY(ID));")
if err2 != nil {
log.Fatal(err2)
}
fmt.Print("Successfully Created\n")
}
这里相当于java的JDBC操作了,不过后面会有更加简洁的连接方式包括池的连接啥的
增
向数据库中user表里插入(1, "sc", "123")
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql", "root:abc123@tcp(127.0.0.1:3306)/go_orm")
err1 := db.Ping()
if err1 != nil {
log.Fatalln(err1)
}
defer func(db *sql.DB) {
err := db.Close()
if err != nil {
log.Fatalln(err)
}
}(db)
if err != nil {
fmt.Println("数据库连接失败!")
log.Fatalln(err)
}
_, err2 := db.Query("INSERT INTO user VALUES(1, 'sc','123')") // 这里利用Query
if err2 != nil {
log.Fatal(err2)
}
fmt.Print("Successfully Inserted\n")
}
再次插入的话主键会重复,导致插入失败
我们这里再插入一个id为2的,方便后面的操作
删
删除掉id为1的数据
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql", "root:abc123@tcp(127.0.0.1:3306)/go_orm")
err1 := db.Ping()
if err1 != nil {
return
}
defer func(db *sql.DB) {
err := db.Close()
if err != nil {
fmt.Println(err)
}
}(db)
if err != nil {
fmt.Println("数据库连接失败!")
log.Fatalln(err)
}
sql := "DELETE FROM user WHERE id = 1"
res, err2 := db.Exec(sql)
if err2 != nil {
panic(err2.Error())
}
affectedRows, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("The statement affected %d rows\n", affectedRows)
}
删除的返回值是影响的行数
改
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql", "root:abc123@tcp(127.0.0.1:3306)/go_orm")
err1 := db.Ping()
if err1 != nil {
log.Fatal(err1)
}
defer func(db *sql.DB) {
err := db.Close()
if err != nil {
log.Fatal(err)
}
}(db)
if err != nil {
fmt.Println("数据库连接失败!")
log.Fatalln(err)
}
sql := "update user set name = ? WHERE id = ?"
res, err2 := db.Exec(sql, "swwk33", 1)
if err2 != nil {
panic(err2.Error())
}
affectedRows, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
fmt.Printf("Update Success, The statement affected %d rows\n", affectedRows)
}
查
查的话也就一点需要注意,就是这个返回值
result, err2 := db.Query("SELECT * FROM user")
然后我们可以循环遍历result.Next(),注意这里的指针是从-1开始的,所以我们可以直接循环开始,不需要do{}while这种结构
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql", "root:abc123@tcp(127.0.0.1:3306)/go_orm")
db.Ping()
defer db.Close()
if err != nil {
fmt.Println("数据库连接失败!")
log.Fatalln(err)
}
result, err2 := db.Query("SELECT * FROM user")
if err2 != nil {
log.Fatal(err2)
}
for result.Next() {
var id int
var name string
var password string
err = result.Scan(&id, &name, &password)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Id: %d, Name: %s, password: %s\n", id, name, password)
}
}
条件查询的话,也就和上面一样,只是改变一下sql语句
result, err2 := db.Query("SELECT * FROM user WHERE id = ?", mid)