与数据库打交道
够浪的官方
database/sql
库实际只提供了一套操作数据库的接口和规范。如 抽象好的SQL预处理(prepare),连接池管理,数据绑定,事务,错误处理等等,并未提供具体某种数据库实现的协议支持。
库 database/sql
DB 扮演的角色与laravel数据库管理实例,同nodejs中的sequelizejs连接大抵一样,都是掌权者,负责指挥不干活。
import _ "github.com/go-sql-driver/mysql"
是故需要匿名导入包含init函数的驱动包,实现官方接口
func init() {
sql.Register("mysql", &MySQLDriver{})
}
sql.Open
返回的DB是这货
type Conn interface {
Prepare(query string) (Stmt, error)
Close() error
Begin() (Tx, error)
}
Placeholder
不同类型的数据库占位符,有所不同
MySQL PostgreSQL Oracle
===== ========== ======
WHERE col = ? WHERE col = $1 WHERE col = :col
VALUES(?, ?, ?) VALUES($1, $2, $3) VALUES(:val1, :val2, :val3)
DB
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
// sql.DB sql.Rows sql.Scan
func main() {
// *sql.DB
db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/shop58")
if err != nil {
log.Fatal(err)
}
defer db.Close()
var (
id int
name string
email string
)
// *sql.Rows
rows, err := db.Query("select id, name,email from users where id = ?", 1)
if err != nil {
log.Fatal(err)
}
// 防止进一步枚举(换而言之,读完会释放连接资源),很重要!!!
defer rows.Close()
// 读取下一行结果集
// 必须要把 rows 里的内容读完,或者显式调用 Close() 方法,
// 否则在 defer 的 rows.Close() 执行之前,连接永远不会释放
for rows.Next() {
err := rows.Scan(&id, &name, &email)
if err != nil {
log.Fatal(err)
}
log.Println(id, name, email)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
}
Tx
事务在够浪也有涉及,官方仅一个接口规范,管理了一个标准库
package main
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
"log"
)
func main() {
db, err := sql.Open("mysql", "root:@tcp(127.0.0.1:3306)/test")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// *sql.Tx
tx, err := db.Begin()
if err != nil {
log.Fatal(err)
}
defer tx.Rollback()
// *sql.Stmt
stmt, err := tx.Prepare("insert into account (id,price) values (null,?)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
for i := 0; i < 5; i++ {
_, err = stmt.Exec(i)
if err != nil {
log.Fatal(err)
}
}
err = tx.Commit()
if err != nil {
log.Fatal(err)
}
stmt.Close()
}
官方
包括该库的功能介绍、用法、注意事项和一些非人类方法实现,参阅 http://go-database-sql.org/
如反直觉的一些实现方式(同一个goroutine内对sql.DB
的查询,可能在多个连接上)。
官方东西总是大道至简,够用,多点操作,可能就要用到高效率的ORM和SQL Builder。这些工具屏蔽了DB层一些细节,让你几乎感觉不到数据库的存在,只是使用面向对象的编码。中小型公司可能还凑合,到大厂不行了。比如某些orm会生成的SQL语句会自动limit 1000,这是后话。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: