...
为简化示例编写,我们这里实现了一个自定义的MySQL
驱动,该驱动继承于gdb
模块中已经实现的DriverMysql
,并按照需要修改覆盖相应的接口方法。由于所有的SQL
语句执行必定会通过DoQuery
或者DoExec
接口,因此我们在自定义的驱动中实现并覆盖这两个接口方法即可。
Code Block | ||
---|---|---|
| ||
package driver import ( "context" "database/sql" "github.com/gogf/gf/database/gdb" "github.com/gogf/gf/os/gtime" ) // MyDriver is a custom database driver, which is used for testing only. // For simplifying the unit testing case purpose, MyDriver struct inherits the mysql driver // gdb.DriverMysql and overwrites its functions DoQuery and DoExec. // So if there's any sql execution, it goes through MyDriver.DoQuery/MyDriver.DoExec firstly // and then gdb.DriverMysql.DoQuery/gdb.DriverMysql.DoExec. // You can call it sql "HOOK" or "HiJack" as your will. type MyDriver struct { *gdb.DriverMysql } var ( // customDriverName is my driver name, which is used for registering. customDriverName = "MyDriver" ) func init() { // It here registers my custom driver in package initialization function "init". // You can later use this type in the database configuration. if err := gdb.Register(customDriverName, &MyDriver{}); err != nil { panic(err) } } // New creates and returns a database object for mysql. // It implements the interface of gdb.Driver for extra database driver installation. func (d *MyDriver) New(core *gdb.Core, node *gdb.ConfigNode) (gdb.DB, error) { return &MyDriver{ &gdb.DriverMysql{ Core: core, }, }, nil } // DoQuery commits the sql string and its arguments to underlying driver // through given link object and returns the execution result. func (d *MyDriver) DoQuery(ctx context.Context, link gdb.Link, sql string, args ...interface{}) (rows *sql.Rows, err error) { tsMilli := gtime.TimestampMilli() rows, err = d.DriverMysql.DoQuery(ctx, link, sql, args...) link.Exec( "INSERT INTO `monitor`(`sql`,`cost`,`time`,`error`) VALUES(?,?,?,?)", gdb.FormatSqlWithArgs(sql, args), gtime.TimestampMilli()-tsMilli, gtime.Now(), err, ) return } // DoExec commits the query string and its arguments to underlying driver // through given link object and returns the execution result. func (d *MyDriver) DoExec(ctx context.Context, link gdb.Link, sql string, args ...interface{}) (result sql.Result, err error) { tsMilli := gtime.TimestampMilli() result, err = d.DriverMysql.DoExec(ctx, link, sql, args...) link.Exec( "INSERT INTO `monitor`(`sql`,`cost`,`time`,`error`) VALUES(?,?,?,?)", gdb.FormatSqlWithArgs(sql, args), gtime.TimestampMilli()-tsMilli, gtime.Now(), err, ) return } |
...
我们看到,这里在包初始化方法init
中使用了gdb.Register("MyDriver", &MyDriver{})
来注册了了一个自定义名称的驱动。我们也可以通过gdb.Register("mysql", &MyDriver{})
来覆盖已有的框架mysql
驱动为自己的驱动。
...