基本介绍

gf框架的ORM功能由gdb模块实现,用于常用关系型数据库的ORM操作。其最大的特色在于同时支持mapstruct两种方式操作数据库。gdb默认情况下使用的是map数据类型作为基础的数据表记录载体,开发者无需预先定义数据表记录struct便可直接对数据表记录执行各种操作。这样的设计赋予了开发者更高的灵活度和简便性。

gdb数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭,因此链接对象不用的时候不需要显式使用Close方法关闭数据库连接。这也是gdb数据库模块人性化设计的地方,方便开发者使用数据库而无需手动维护大量的数据库链接对象。

注意:为提高数据库操作安全性,在ORM操作中不建议直接将参数拼接成SQL字符串执行,建议尽量使用预处理的方式(充分使用?占位符)来传递SQL参数。gdb的底层实现中均采用的是预处理的方式处理开发者传递的参数,以充分保证数据库操作安全性。

接口文档: https://godoc.org/github.com/gogf/gf/database/gdb

数据结构

为便于数据表记录的操作,ORM定义了5种基本的数据类型:

  1. type Map map[string]interface{} // 数据记录
  2. type List []Map // 数据记录列表
  3. type Value *gvar.Var // 返回数据表记录值
  4. type Record map[string]Value // 返回数据表记录键值对
  5. type Result []Record // 返回数据表记录列表
  1. MapList用于ORM操作过程中的输入参数类型(与全局类型g.Mapg.List一致,在项目开发中常用g.Mapg.List替换);
  2. Value/Record/Result用于ORM操作的结果数据类型,具体说明请查看 ORM结果处理 章节;

接口方法

以下是DB接口提供的常用方法列表,详细的方法列表请参考接口文档:https://godoc.org/github.com/gogf/gf/database/gdb

  1. // 创建模型对象
  2. Model(table ...string) *Model
  3. // 切换数据库
  4. Schema(schema string) *Schema
  5. // 自定义上下文变量
  6. Ctx(ctx context.Context) DB
  7. // SQL操作方法,返回原生的标准库sql对象
  8. Query(query string, args ...interface{}) (*sql.Rows, error)
  9. Exec(query string, args ...interface{}) (sql.Result, error)
  10. Prepare(query string) (*sql.Stmt, error)
  11. // 数据表记录查询:
  12. // 查询单条记录、查询多条记录、获取记录对象、查询单个字段值(链式操作同理)
  13. GetAll(sql string, args ...interface{}) (Result, error)
  14. GetOne(sql string, args ...interface{}) (Record, error)
  15. GetValue(sql string, args ...interface{}) (Value, error)
  16. GetArray(sql string, args ...interface{}) ([]Value, error)
  17. GetCount(sql string, args ...interface{}) (int, error)
  18. GetStruct(objPointer interface{}, sql string, args ...interface{}) error
  19. GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error
  20. GetScan(objPointer interface{}, sql string, args ...interface{}) error
  21. // 数据单条操作
  22. Insert(table string, data interface{}, batch...int) (sql.Result, error)
  23. Replace(table string, data interface{}, batch...int) (sql.Result, error)
  24. Save(table string, data interface{}, batch...int) (sql.Result, error)
  25. // 数据批量操作
  26. BatchInsert(table string, list interface{}, batch...int) (sql.Result, error)
  27. BatchReplace(table string, list interface{}, batch...int) (sql.Result, error)
  28. BatchSave(table string, list interface{}, batch...int) (sql.Result, error)
  29. // 数据修改/删除
  30. Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error)
  31. Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error)
  32. // 开启事务操作
  33. Begin() (*TX, error)
  34. // 事务闭包操作
  35. Transaction(f func(tx *TX) error) (err error)
  36. // 设置管理
  37. GetCache() *gcache.Cache
  38. SetDebug(debug bool)
  39. GetDebug() bool
  40. SetSchema(schema string)
  41. GetSchema() string
  42. GetPrefix() string
  43. GetGroup() string
  44. SetDryRun(dryrun bool)
  45. GetDryRun() bool
  46. SetLogger(logger *glog.Logger)
  47. GetLogger() *glog.Logger
  48. GetConfig() *ConfigNode
  49. SetMaxIdleConnCount(n int)
  50. SetMaxOpenConnCount(n int)
  51. SetMaxConnLifetime(d time.Duration)
  52. // 工具类方法
  53. GetCtx() context.Context
  54. GetChars() (charLeft string, charRight string)
  55. GetMaster(schema ...string) (*sql.DB, error)
  56. GetSlave(schema ...string) (*sql.DB, error)
  57. QuoteWord(s string) string
  58. QuoteString(s string) string
  59. QuotePrefixTableName(table string) string
  60. Tables(schema ...string) (tables []string, err error)
  61. TableFields(table string, schema ...string) (map[string]*TableField, error)
  62. HasTable(name string) (bool, error)

g.DBgdb.Newgdb.Instance

获取数据库操作对象有三种方式,一种是使用g.DB方法(推荐),一种是使用原生gdb.New方法,还有一种是使用包原生单例方法gdb.Instance,而第一种是推荐的使用方式。这三种方式的区别如下:

  1. g.DB对象管理方式获取的是单例对象,整合了配置文件的管理功能,支持配置文件热更新;
  2. gdb.New是创建一个新的数据库对象(非单例),无法使用配置文件,需要使用包配置管理方法进行配置;
  3. gdb.Instance是包原生单例管理方法,需要结合配置方法一起使用,通过分组名称(非必需)获取对应配置的数据库单例对象;
  4. 其他使用无差别;

有这么多对象获取方式原因在于GF是一个模块化设计的框架,每个模块皆可单独使用。为了方便开发者使用常用的一些模块,因此框架也提供了一个g模块,这是一个高度耦合的模块,封装了一些常用对象的单例获取方式,详见 对象管理 章节。

获取ORM对象示例:

  1. // 获取默认配置的数据库对象(配置名称为"default")
  2. db := g.DB()
  3. // 获取配置分组名称为"user-center"的数据库对象
  4. db := g.DB("user-center")
  5. // 使用原生New方法创建数据库对象
  6. db, err := gdb.New()
  7. db, err := gdb.New("user-center")
  8. // 使用原生单例管理方法获取数据库对象单例
  9. db, err := gdb.Instance()
  10. db, err := gdb.Instance("user-center")
  11. // 注意不用的时候不需要使用Close方法关闭数据库连接(并且gdb也没有提供Close方法),
  12. // 数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭

支持的数据库类型

由于go标准库的数据库操作对象采用接口实现,因此提供了非常好的可扩展性和兼容性。

MySQL

内置支持,无需额外扩展或第三方包接入,直接可用。 依赖的第三方包:https://github.com/go-sql-driver/mysql

SQLite

在使用时需要引入第三方包 ( go-sqlite3 ):

  1. _ "github.com/mattn/go-sqlite3"

限制

  1. 不支持Save/Replace方法

PostgreSQL

在使用时需要引入第三方包 (pq ):

  1. _ "github.com/lib/pq"

限制

  1. 不支持LastInsertId方法
  2. 不支持Save/Replace方法

SQL Server

使用时需导入第三方包 (go-mssqldb ):

  1. _ "github.com/denisenkom/go-mssqldb"

限制

  1. 不支持LastInsertId方法
  2. 不支持Save/Replace方法
  3. 仅支持SQL Server 2005及其后的版本

Oracle

使用时需导入第三方包 (go-oci8 ):

  1. _ "github.com/mattn/go-oci8"

限制

  1. 不支持LastInsertId方法
  2. 不支持Save/Replace方法

其他数据库类型

额外接入新的数据库相当方便,可参考源码中关于PostgreSQLSQLiteOracleSQL Server的接入方式。具体介绍请参考后续 ORM接口开发-驱动开发 章节。