同步操作将从 goflyfox/gfstudy 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
gf
框架的ORM
功能由gdb
模块实现,用于常用关系型数据库的ORM
操作。其最大的特色在于同时支持map
和struct
两种方式操作数据库。gdb
默认情况下使用的是map
数据类型作为基础的数据表记录载体,开发者无需预先定义数据表记录struct
便可直接对数据表记录执行各种操作。这样的设计赋予了开发者更高的灵活度和简便性。
支持的数据库类型:Mysql,SQLite,PostgreSQL,SQLServer,Oracle
推荐使用配置文件及单例对象来管理和使用数据库操作。
如果我们使用g
对象管理模块中的g.DB("数据库分组名称")
方法获取数据库操作对象,数据库对象将会自动读取config.toml
配置文件中的相应配置项(通过配置管理模块),并自动初始化该数据库操作的单例对象。
[database]
[[database.default]]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
[[database.user]]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"
注意每一项分组配置均可以是多个节点,支持负载均衡权重策略。如果不使用多节点负载均衡特性,仅使用配置分组特性,也可以简化为如下格式:
[database]
[database.default]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
[database.user]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user"
如果仅仅是单数据库节点,不使用配置分组特性,那么也可以简化为如下格式:
[database]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
不同数据类型对应的linkinfo
如下:
数据库类型 | Linkinfo配置 | 更多参数 |
---|---|---|
mysql | mysql: 账号:密码@tcp(地址:端口)/数据库名称 |
mysql |
pgsql | pgsql: user=账号 password=密码 host=地址 port=端口 dbname=数据库名称 |
pq |
mssql | mssql: user id=账号;password=密码;server=地址;port=端口;database=数据库名称;encrypt=disable |
go-mssqldb |
sqlite |
sqlite: 文件绝对路径 (如: /var/lib/db.sqlite3 ) |
go-sqlite3 |
oracle | oracle: 账号/密码@地址:端口/数据库名称 |
go-oci8 |
gdb
支持日志输出,内部使用的是glog.Logger
对象实现日志管理,并且可以通过配置文件对日志对象进行配置。默认情况下gdb
关闭了DEBUG
日志输出,如果需要打开DEBUG
信息需要将数据库的debug
参数设置为true
。以下是为一个配置文件示例:
[database]
[database.logger]
Path = "/var/log/gf-app/sql"
Level = "all"
Stdout = true
[database.primary]
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/user_center"
debug = true
其中database.logger
即为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操作的结果数据类型;Insert/Replace/Save
这三个链式操作方法用于数据的写入,并且支持自动的单条或者批量的数据写入,三者区别如下:
Insert
使用INSERT INTO
语句进行数据库写入,如果写入的数据中存在主键或者唯一索引时,返回失败,否则写入一条新数据;
Replace
使用REPLACE INTO
语句进行数据库写入,如果写入的数据中存在主键或者唯一索引时,会删除原有的记录,必定会写入一条新记录;
Save
使用INSERT INTO
语句进行数据库写入,如果写入的数据中存在主键或者唯一索引时,更新原有数据,否则写入一条新数据;
在部分数据库类型中,并不支持
Replace/Save
方法
Update
更新方法Update
用于数据的更新,往往需要结合Data
及Where
方法共同使用。Data
方法用于指定需要更新的数据,Where
方法用于指定更新的条件范围。同时,Update
方法也支持直接给定数据和条件参数。
Delete
删除方法Delete
方法用于数据的删除。
Where/And/Or
查询条件这三个方法用于传递查询条件参数,支持的参数为任意的string/map/slice/struct/*struct
类型。
Where
条件参数推荐使用字符串的参数传递方式(并使用?
占位符预处理),因为map
/struct
类型作为查询参数无法保证顺序性,且在部分情况下(数据库有时会帮助你自动进行查询索引优化),数据库的索引和你传递的查询条件顺序有一定关系。
当使用多个Where
方法连接查询条件时,作用同And
。 此外,当存在多个查询条件时,gdb
会默认将多个条件分别使用()
符号进行包含,这种设计可以非常友好地支持查询条件分组。
All/One/Value/Count
数据查询这四个方法是数据查询比较常用的方法:
All
用于查询并返回多条记录的列表/数组。One
用于查询并返回单条记录。Value
用于查询并返回一个字段值,往往需要结合Fields
方法使用。Count
用于查询并返回记录数。此外,也可以看得到这四个方法定义中也支持条件参数的直接输入,参数类型与Where
方法一致。但需要注意,其中Value
方法的参数中至少应该输入字段参数。
CREATE TABLE `user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`site` varchar(255) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=10000 ;
package test
import (
"fmt"
"github.com/gogf/gf/frame/g"
"testing"
)
// Insert
func TestInsert(t *testing.T) {
// INSERT INTO `user`(`name`) VALUES('john')
_, err := g.DB().Table("user").Data(g.Map{"uid": 10000, "name": "john"}).Insert()
if err != nil {
panic(err)
}
}
// Update
func TestUpdate(t *testing.T) {
// UPDATE `user` SET `name`='john guo' WHERE name='john'
_, err := g.DB().Table("user").Data("name", "john guo").
Where("name", "john").Update()
if err != nil {
panic(err)
}
}
// Delete
func TestDelete(t *testing.T) {
// DELETE FROM `user` WHERE uid=10
_, err := g.DB().Table("user").Where("uid", 10000).Delete()
if err != nil {
panic(err)
}
}
// Select Where
func TestWhere(t *testing.T) {
// INSERT INTO `user`(`name`) VALUES('john')
g.DB().Table("user").Data(g.Map{"uid": 10001, "name": "john"}).Insert()
g.DB().Table("user").Data(g.Map{"uid": 10002, "name": "john2"}).Insert()
// 数量
count, err := g.DB().Table("user").Where("uid", 10001).Count()
if err != nil {
panic(err)
}
fmt.Println("count:", count)
// 获取单个值
v, err := g.DB().Table("user").Where("uid", 10001).Fields("name").Value()
if err != nil {
panic(err)
}
fmt.Println("name:", v.String())
// 查询对象
r, err := g.DB().Table("user").Where("uid", 10002).One()
if err != nil {
panic(err)
}
fmt.Println("name:", r.Map()["name"])
// 查询对象
//l, err := g.DB().Table("user").As("t").Where("t.uid > ?", 10000).All()
// 也可以简写为 select * from user as t where t.uid > 10000
l, err := g.DB().Table("user").As("t").All("t.uid > ?", 10000)
if err != nil {
panic(err)
}
for index, value := range l {
fmt.Println(index, value["uid"], value["name"])
}
g.DB().Table("user").Where("uid", 10001).Delete()
g.DB().Table("user").Where("uid", 10002).Delete()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。