导入包时,golang会隐式的调用该包的init()函数。以下代码适用于在golang没有使用包的情况下,调用init初始化函数
import (
_ "github.com/go-sql-driver/mysql"
)
可变长参数在源码中很常见,接收参数后,常用for range循环,基本类型会变成数组方便计算。 可变长参数有传入interface类型的,interface对象占用16字节长度,包含一个指向原数据的指针,和一个指向运行时类型信息的指针。深入探究的话,其使用方法和golang的语言设计相关,属于编译原理范畴。除非你想写底层,不然不推荐用这个。因为这个东西开始对位 进行操作了,不报错的。
type user struct {
id int
name string
age int
}
func queryOneRow ( ) {
sql := "select * from user where id = ?"
row := db. QueryRow ( sql, 1 )
var u user
err := row. Scan ( & u. id, & u. name, & u. age)
if ( err!= nil ) {
fmt. Printf ( "row.Scan() failed \n %v" , err)
return
}
fmt. Println ( u)
}
基于以上考虑,注意row.Scan()是传入指针的,不过就算不注意,也会报错的。 sql可以用问号 占位,调用db.QueryRow(sql,1,…)可变长,db.QueryRow(sql)也可以的 db.QueryRow(sql)内部占用 一个连接,row.Scan()内部释放 一个连接。 如果可用连接db.SetMaxOpenConns(1)设定的比较小,不释放会一直阻塞。所以一定要确保 row := db.QueryRow(sql)后面要用row.Scan() 所以一般都直接用,不要分开搞
err := db. QueryRow ( sql, 1 ) . Scan ( & u. id, & u. name, & u. age)
Scan(&u.id,&u.name,&u.age)会直接赋值 的哟 更新,插入可以拼好sql直接 _,err := db.Exec(sql) 预处理,使用Query(args),不是Exec()
sqlStr := "select id, name, age from user where id > ?"
state, _ := db. Prepare ( sqlStr)
state. Query ( 0 )
state. Close ( )
事务提交前,要自己判断是否合规。因为提交没法回滚。