- Created by 海亮, last modified by 郭强 on Jan 06, 2021
基本介绍
gf
框架的ORM
功能由gdb
模块实现,用于常用关系型数据库的ORM
操作。其最大的特色在于同时支持map
和struct
两种方式操作数据库。gdb
默认情况下使用的是map
数据类型作为基础的数据表记录载体,开发者无需预先定义数据表记录struct
便可直接对数据表记录执行各种操作。这样的设计赋予了开发者更高的灵活度和简便性。
gdb
数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭,因此链接对象不用的时候不需要显式使用Close
方法关闭数据库连接。这也是gdb
数据库模块人性化设计的地方,方便开发者使用数据库而无需手动维护大量的数据库链接对象。
注意:为提高数据库操作安全性,在ORM
操作中不建议直接将参数拼接成SQL
字符串执行,建议尽量使用预处理的方式(充分使用?
占位符)来传递SQL参数。gdb
的底层实现中均采用的是预处理的方式处理开发者传递的参数,以充分保证数据库操作安全性。
接口文档: https://godoc.org/github.com/gogf/gf/database/gdb
数据结构
为便于数据表记录的操作,ORM
定义了5种基本的数据类型:
type Map map[string]interface{} // 数据记录
type List []Map // 数据记录列表
type Value *gvar.Var // 返回数据表记录值
type Record map[string]Value // 返回数据表记录键值对
type Result []Record // 返回数据表记录列表
Map
与List
用于ORM操作过程中的输入参数类型(与全局类型g.Map
和g.List
一致,在项目开发中常用g.Map
和g.List
替换);Value/Record/Result
用于ORM操作的结果数据类型,具体说明请查看 ORM结果处理 章节;
接口方法
以下是DB
接口提供的常用方法列表,详细的方法列表请参考接口文档:https://godoc.org/github.com/gogf/gf/database/gdb
// 创建模型对象 Model(table ...string) *Model // 切换数据库 Schema(schema string) *Schema // 自定义上下文变量 Ctx(ctx context.Context) DB // SQL操作方法,返回原生的标准库sql对象 Query(query string, args ...interface{}) (*sql.Rows, error) Exec(query string, args ...interface{}) (sql.Result, error) Prepare(query string) (*sql.Stmt, error) // 数据表记录查询: // 查询单条记录、查询多条记录、获取记录对象、查询单个字段值(链式操作同理) GetAll(sql string, args ...interface{}) (Result, error) GetOne(sql string, args ...interface{}) (Record, error) GetValue(sql string, args ...interface{}) (Value, error) GetArray(sql string, args ...interface{}) ([]Value, error) GetCount(sql string, args ...interface{}) (int, error) GetStruct(objPointer interface{}, sql string, args ...interface{}) error GetStructs(objPointerSlice interface{}, sql string, args ...interface{}) error GetScan(objPointer interface{}, sql string, args ...interface{}) error // 数据单条操作 Insert(table string, data interface{}, batch...int) (sql.Result, error) Replace(table string, data interface{}, batch...int) (sql.Result, error) Save(table string, data interface{}, batch...int) (sql.Result, error) // 数据批量操作 BatchInsert(table string, list interface{}, batch...int) (sql.Result, error) BatchReplace(table string, list interface{}, batch...int) (sql.Result, error) BatchSave(table string, list interface{}, batch...int) (sql.Result, error) // 数据修改/删除 Update(table string, data interface{}, condition interface{}, args ...interface{}) (sql.Result, error) Delete(table string, condition interface{}, args ...interface{}) (sql.Result, error) // 开启事务操作 Begin() (*TX, error) // 事务闭包操作 Transaction(f func(tx *TX) error) (err error) // 设置管理 GetCache() *gcache.Cache SetDebug(debug bool) GetDebug() bool SetSchema(schema string) GetSchema() string GetPrefix() string GetGroup() string SetDryRun(dryrun bool) GetDryRun() bool SetLogger(logger *glog.Logger) GetLogger() *glog.Logger GetConfig() *ConfigNode SetMaxIdleConnCount(n int) SetMaxOpenConnCount(n int) SetMaxConnLifetime(d time.Duration) // 工具类方法 GetCtx() context.Context GetChars() (charLeft string, charRight string) GetMaster(schema ...string) (*sql.DB, error) GetSlave(schema ...string) (*sql.DB, error) QuoteWord(s string) string QuoteString(s string) string QuotePrefixTableName(table string) string Tables(schema ...string) (tables []string, err error) TableFields(table string, schema ...string) (map[string]*TableField, error) HasTable(name string) (bool, error)
g.DB
与gdb.New
、gdb.Instance
获取数据库操作对象有三种方式,一种是使用g.DB
方法(推荐),一种是使用原生gdb.New
方法,还有一种是使用包原生单例方法gdb.Instance
,而第一种是推荐的使用方式。这三种方式的区别如下:
g.DB
对象管理方式获取的是单例对象,整合了配置文件的管理功能,支持配置文件热更新;gdb.New
是创建一个新的数据库对象(非单例),无法使用配置文件,需要使用包配置管理方法进行配置;gdb.Instance
是包原生单例管理方法,需要结合配置方法一起使用,通过分组名称(非必需)获取对应配置的数据库单例对象;- 其他使用无差别;
有这么多对象获取方式原因在于GF
是一个模块化设计的框架,每个模块皆可单独使用。为了方便开发者使用常用的一些模块,因此框架也提供了一个g
模块,这是一个高度耦合的模块,封装了一些常用对象的单例获取方式,详见 对象管理 章节。
获取ORM
对象示例:
// 获取默认配置的数据库对象(配置名称为"default")
db := g.DB()
// 获取配置分组名称为"user-center"的数据库对象
db := g.DB("user-center")
// 使用原生New方法创建数据库对象
db, err := gdb.New()
db, err := gdb.New("user-center")
// 使用原生单例管理方法获取数据库对象单例
db, err := gdb.Instance()
db, err := gdb.Instance("user-center")
// 注意不用的时候不需要使用Close方法关闭数据库连接(并且gdb也没有提供Close方法),
// 数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭
支持的数据库类型
由于go标准库的数据库操作对象采用接口实现,因此提供了非常好的可扩展性和兼容性。
MySQL
内置支持,无需额外扩展或第三方包接入,直接可用。 依赖的第三方包:https://github.com/go-sql-driver/mysql
SQLite
在使用时需要引入第三方包 ( go-sqlite3 ):
_ "github.com/mattn/go-sqlite3"
限制
- 不支持
Save/Replace
方法
PostgreSQL
在使用时需要引入第三方包 (pq ):
_ "github.com/lib/pq"
限制
- 不支持
LastInsertId
方法 - 不支持
Save/Replace
方法
SQL Server
使用时需导入第三方包 (go-mssqldb ):
_ "github.com/denisenkom/go-mssqldb"
限制
- 不支持
LastInsertId
方法 - 不支持
Save/Replace
方法 - 仅支持
SQL Server 2005
及其后的版本
Oracle
使用时需导入第三方包 (go-oci8 ):
_ "github.com/mattn/go-oci8"
限制
- 不支持
LastInsertId
方法 - 不支持
Save/Replace
方法
其他数据库类型
额外接入新的数据库相当方便,可参考源码中关于PostgreSQL
、SQLite
、Oracle
、SQL Server
的接入方式。具体介绍请参考后续 ORM接口开发-驱动开发 章节。
- No labels
13 Comments
陈富贵
请问orm报错empty database configuration for item name 'default'是什么问题呀,之前一直没有问题,这两天就不行了。但是数据库配置也没问题,在test包测试执行同样的orm也没问题(但是我重新装过go,不知道有没有关系)。执行gf gen dao也是报错Error: database initialization failed。
郭强
表示你的配置文件中的数据库配置有问题,检查一下,参考一下:ORM使用配置
Yufan Sheng
在微服务生产环境中,通常有数据库 migrate 需求,这块 ORM 是否有考虑支持?
郭强
暂无考虑。
英梨梨
gdb 有类似gorm的 AutoMigrate 自动建表功能吗?最近在学习focus发现用的是gdb但是搜了下没发现自动建表的功能 需要手动建表或者导入 是我没搜到还是没有呢?
郭强
goframe
的orm
没有migrate
功能,未来估计也不太可能会有。刘羽禅
DDL操作 和 DML操作应该分开
代码 应该只操作数据 而不应该操作数据库表
权限越位了.
且,库表的创建修改权限,应该集中在技术管理人员手里, 如果放在代码账号里,
人人都有权限,存在操作风险哦,团队内的成员,SQL水平参差不齐,安全意识也不一定到位.
奭奭
postgresql 如何支持LastInsertId,有别的方法可以用吗
奭奭
postgresql 如何实现获取自增主键
奭奭
gorm Create 是会返回主键的,请问,gform如何返回postgresql主键 RETURNING "id"
郭强
暂不支持
ganziwz
请问支持SQL版本管理吗
郭强
麻烦具体描述一下呢?