官方对mysql使用标准三步走: sql="insert into users(age) values(?)";
正常的操作是
stmt = db.Prepare(sql)
stmt.Exec(...)
stmt.Close
prepare的时候会先从连接池里取一个连接,然后根据sql语句 创建一个stmt。但是对于同一种数据频繁数据的场景来说,一次prepare就可以了,没必要每次都重写创建一次stmt。
因此在mysqlConn的时候维护一个cache,以sql语句为key,对应的stmt为value。 同一个sql语句直接返回stmt。
当DB.Close的时候,会调用每次mysqlConn的Close,此时遍历cache释放stmt(stmt.Close()) ,释放cache。
具体操作看我github提交的源码。
有疑问加站长微信联系(非本文作者)

你是不是对prepare有什么误解
正常操作是不需要prepare的
prepare出的stmt本来就是为了多次使用的啊。
考虑下多个协程操作数据库的场景,另外stmt是跟连接绑定的。
文档先确认下啊……
https://golang.org/pkg/database/sql/#Stmt
Stmt is a prepared statement. A Stmt is safe for concurrent use by multiple goroutines.
If a Stmt is prepared on a Tx or Conn, it will be bound to a single underlying connection forever. If the Tx or Conn closes, the Stmt will become unusable and all operations will return an error. If a Stmt is prepared on a DB, it will remain usable for the lifetime of the DB. When the Stmt needs to execute on a new underlying connection, it will prepare itself on the new connection automatically.
场景需求,对于多协程+多sql语句的情景下你需要自己维护一个stmt表,而我做的是从mysql驱动层,在每一个mysqlConn里面扩展了一个cache,不需要对原来的代码做修改。
唔 我标题起的不太合适了,算不上加速,只是接替了维护sql string和stmt的关系
刚在github上讨论了下,原来有个库已经做的了。 https://godoc.org/github.com/Masterminds/squirrel#StmtCache
我一开始只是没明白需求点而已。
既然能满足你的需求,就是好库。
至于是否已经有现成的库,其实这部重要。
用库么,要么用最通用的,要么用自己写的。
既然你自己的需求已经到自己需要自己写的程度,其实大概率自己的写更好。
在理,这个库我看了下,其实实现就是相当于我之前说的维护一个sql语句和stmt的map。。这种就容易犯忘记释放的错误。
所以我倾向于交给驱动层去处理,缺点也显而易见就是太底层了,扩展性不方便。