博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gf框架之gdb - 优雅强大的数据库ORM
阅读量:6521 次
发布时间:2019-06-24

本文共 8327 字,大约阅读时间需要 27 分钟。

文章来源:

gf框架的数据库ORM操作由gdb包提供支持,gdb包经过非常精心优雅的设计,提供了非常强大的配置管理、方法操作、链式操作、事务操作等功能。gdb包具体API说明文档详见: 。本章节对gdb包的使用进行基本的介绍,包括:gdb包基本功能介绍,配置管理功能说明,常见用法及常用操作示例。

使用方式:

import "gitee.com/johng/gf/g/database/gdb"

数据库配置

gdb数据结构:

type List        []Map                  // 数据记录列表 type Map         map[string]interface{} // 数据记录type Config      map[string]ConfigGroup // 数据库配置对象type ConfigGroup []ConfigNode           // 数据库分组配置// 数据库配置项(一个分组配置对应多个配置项)type ConfigNode  struct {    Host     string // 地址    Port     string // 端口    User     string // 账号    Pass     string // 密码    Name     string // 数据库名称    Type     string // 数据库类型:mysql, sqlite, mssql, pgsql, oracle(目前仅支持mysql,pgsql)    Role     string // (可选,默认为master)数据库的角色,用于主从操作分离,至少需要有一个master,参数值:master, slave    Charset  string // (可选,默认为 utf-8)编码,默认为 utf-8    Priority int    // (可选)用于负载均衡的权重计算,当集群中只有一个节点时,权重没有任何意义    Linkinfo string // (可选)自定义链接信息,当该字段被设置值时,以上链接字段(Host,Port,User,Pass,Name)将失效(该字段是一个扩展功能,参考sql.Open参数)}

其中,Map和List用于数据表记录操作,分别对应一条数据表记录和数据表记录列表;Config、ConfigGroup及ConfigNode用于数据库配置管理,ConfigNode用于存储一个数据库节点信息,ConfigGroup用于管理多个数据库节点组成的配置分组(一般一个分组对应一个业务数据库集群),Config用于管理多个ConfigGroup配置分组。

gdb主要特点:

  1. 支持多节点数据库集群管理,采用单例模式管理数据库实例化对象;
  2. 支持对数据库集群分组管理,按照分组名称获取实例化的数据库操作对象;
  3. 支持多种关系型数据库管理,可通过ConfigNode.Type属性进行配置(目前仅支持mysql和pgsql数据库);
  4. 支持Master-Slave读写分离,可通过ConfigNode.Role属性进行配置;
  5. 支持客户端的负载均衡管理,可通过ConfigNode.Priority属性进行配置,值越大,优先级越高;

特别说明,gdb的配置管理最大的特点是,(同一进程中)所有的数据库集群信息都使用同一个配置管理模块进行统一维护,不同业务的数据库集群配置使用不同的分组名称进行配置和获取。

配置方法

数据库配置管理方法列表:

// 添加一个数据库节点到指定的分组中func AddConfigNode(group string, node ConfigNode)// 添加一个配置分组到数据库配置管理中(同名覆盖)func AddConfigGroup(group string, nodes ConfigGroup)// 添加一个数据库节点到默认的分组中(默认为default,可修改)func AddDefaultConfigNode(node ConfigNode)// 添加一个配置分组到数据库配置管理中(默认分组为default,可修改)func AddDefaultConfigGroup(nodes ConfigGroup)// 设置数据库配置为定义的配置信息func SetConfig(c Config)// 设置默认的分组名称func SetDefaultGroup(groupName string)

默认分组表示,如果获取数据库对象时不指定配置分组名称,那么gdb默认读取的配置分组。例如:gdb.Instance()可获取一个默认分组的数据库单例对象。

简单的做法,我们可以通过gdb包的SetConfig配置管理方法进行自定义的数据库全局配置,例如:

gdb.SetConfig(gdb.Config {    "default" : gdb.ConfigGroup {        gdb.ConfigNode {            Host     : "127.0.0.1",            Port     : "3306",            User     : "root",            Pass     : "123456",            Name     : "test",            Type     : "mysql",            Role     : "master",            Priority : 100,        },        gdb.ConfigNode {            Host     : "127.0.0.2",            Port     : "3306",            User     : "root",            Pass     : "123456",            Name     : "test",            Type     : "mysql",            Role     : "master",            Priority : 100,        },    },})

配置文件

当然,gdb支持配置文件进行配置,这样也便于项目的配置管理,具体请参见【ORM高级用法】章节。

数据库操作

gdb数据库操作的方法比较多,具体详见,以下仅对一些常用的方法进行介绍。

方法操作

// 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(query string, args ...interface{}) (List, error)GetOne(query string, args ...interface{}) (Map, error)GetValue(query string, args ...interface{}) (interface{}, error)// 开启事务操作Begin() (*Tx, error)// 数据单条操作Insert(table string, data Map) (sql.Result, error)Replace(table string, data Map) (sql.Result, error)Save(table string, data Map) (sql.Result, error)// 数据批量操作BatchInsert(table string, list List, batch int) (sql.Result, error)BatchReplace(table string, list List, batch int) (sql.Result, error)BatchSave(table string, list List, 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)// 创建链式操作对象(Table为From的别名)Table(tables string) (*DbOp)From(tables string) (*DbOp)    // 关闭数据库Close() error

需要说明一下Insert/Replace/Save三者的区别(BatchInsert/BatchReplace/BatchSave同理):

  1. Insert:使用insert into语句进行数据库写入,如果写入的数据中存在Primary Key或者Unique Key的情况,返回失败,否则写入一条新数据;
  2. Replace:使用replace into语句进行数据库写入,如果写入的数据中存在Primary Key或者Unique Key的情况,删除原有记录,按照给定数据新写入一条新记录,否则写入一条新数据;
  3. Save:使用insert into语句进行数据库写入,如果写入的数据中存在Primary Key或者Unique Key的情况,更新原有数据,否则写入一条新数据;

链式操作

gdb提供简便灵活的链式操作接口,通过数据库对象的db.Table/db.From方法或者事务对象的tx.Table/tx.From方法基于指定的数据表返回一个链式操作对象DbOp,该对象可以执行以下方法(具体方法说明请参考)。

func LeftJoin(joinTable string, on string) (*DbOp)func RightJoin(joinTable string, on string) (*DbOp)func InnerJoin(joinTable string, on string) (*DbOp)func Fields(fields string) (*DbOp)func Limit(start int, limit int) (*DbOp)func Data(data interface{}) (*DbOp)func Batch(batch int) *DbOpfunc Where(where string, args...interface{}) (*DbOp)func GroupBy(groupby string) (*DbOp)func OrderBy(orderby string) (*DbOp)func Insert() (sql.Result, error)func Replace() (sql.Result, error)func Save() (sql.Result, error)func Update() (sql.Result, error)func Delete() (sql.Result, error)func Select() (List, error)func All() (List, error)func One() (Map, error)func Value() (interface{}, error)

数据库示例

方法操作

  1. 获取ORM单例对象

    // 获取默认配置的数据库对象(配置名称为"default")db, err := gdb.Instance()// 获取配置分组名称为"user-center"的数据库对象db, err := gdb.Instance("user-center")
  2. 数据写入

    r, err := db.Insert("user", gdb.Map {    "name": "john",})
  3. 数据查询(列表)

    list, err := db.GetAll("select * from user limit 2")
  4. 数据查询(单条)

    one, err := db.GetOne("select * from user limit 2")// 或者one, err := db.GetOne("select * from user where uid=1000")
  5. 数据保存

    r, err := db.Save("user", gdb.Map {    "uid"  :  1,    "name" : "john",})
  6. 批量操作

    // BatchInsert/BatchReplace/BatchSave 同理_, err := db.BatchInsert("user", gdb.List {    {"name": "john_1"},    {"name": "john_2"},    {"name": "john_3"},    {"name": "john_4"},}, 10)
  7. 数据更新/删除

    // db.Update/db.Delete 同理r, err := db.Update("user", gdb.Map {"name": "john"}, "uid=?", 10000)r, err := db.Update("user", "name='john'", "uid=10000")r, err := db.Update("user", "name=?", "uid=?", "john", 10000)

    注意,参数域支持并建议使用预处理模式进行输入,避免SQL注入风险。

链式操作

  1. 链式查询

    // 查询多条记录并使用Limit分页r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*, ud.site").Where("u.uid > ?", 1).Limit(0, 10).Select()// 查询符合条件的单条记录(第一条)r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.site").Where("u.uid=?", 1).One()// 查询字段值r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("ud.site").Where("u.uid=?", 1).Value()// 分组及排序r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.city").GroupBy("city").OrderBy("register_time asc").Select()
  2. 链式更新/删除

    // 更新r, err := db.Table("user").Data(gdb.Map{"name" : "john2"}).Where("name=?", "john").Update()r, err := db.Table("user").Data("name='john3'").Where("name=?", "john2").Update()// 删除r, err := db.Table("user").Where("uid=?", 10).Delete()
  3. 链式写入/保存

    r, err := db.Table("user").Data(gdb.Map{"name": "john"}).Insert()r, err := db.Table("user").Data(gdb.Map{"uid": 10000, "name": "john"}).Replace()r, err := db.Table("user").Data(gdb.Map{"uid": 10001, "name": "john"}).Save()
  4. 链式批量写入

    r, err := db.Table("user").Data(gdb.List{    {"name": "john_1"},    {"name": "john_2"},    {"name": "john_3"},    {"name": "john_4"},}).Insert()

    可以指定批量操作中分批写入数据库的每批次写入条数数量:

    r, err := db.Table("user").Data(gdb.List{    {"name": "john_1"},    {"name": "john_2"},    {"name": "john_3"},    {"name": "john_4"},}).Batch(2).Insert()
  5. 链式批量保存

    r, err := db.Table("user").Data(gdb.List{    {"uid":10000, "name": "john_1"},    {"uid":10001, "name": "john_2"},    {"uid":10002, "name": "john_3"},    {"uid":10003, "name": "john_4"},}).Save()

事务操作

开启事务操作可以通过执行db.Begin方法,该方法返回事务的操作对象,类型为*gdb.Tx,通过该对象执行后续的数据库操作,并可通过tx.Commit提交修改,或者通过tx.Rollback回滚修改。

  1. 开启事务操作

    if tx, err := db.Begin(); err == nil {    fmt.Println("开启事务操作")}

    事务操作对象可以执行所有db对象的方法,具体请参考。

  2. 事务回滚操作

    if tx, err := db.Begin(); err == nil {    r, err := tx.Save("user", gdb.Map{        "uid"  :  1,        "name" : "john",    })    tx.Rollback()    fmt.Println(r, err)}
  3. 事务提交操作

    if tx, err := db.Begin(); err == nil {    r, err := tx.Save("user", gdb.Map{        "uid"  :  1,        "name" : "john",    })    tx.Commit()    fmt.Println(r, err)}
  4. 事务链式操作

    事务操作对象仍然可以通过tx.Table或者tx.From方法返回一个链式操作的对象,该对象与db.Table或者db.From方法返回值相同,只不过数据库操作在事务上执行,可提交或回滚。

    if tx, err := db.Begin(); err == nil {    r, err := tx.Table("user").Data(gdb.Map{"uid":1, "name": "john_1"}).Save()    tx.Commit()    fmt.Println(r, err)}

    其他链式操作请参考上述链式操作章节。

转载地址:http://corfo.baihongyu.com/

你可能感兴趣的文章
CentOS 7 关闭启动防火墙
查看>>
Vue-选项卡切换
查看>>
linux网络命令
查看>>
nodejs ejs 请求路径和静态资源文件路径
查看>>
4.1 State Snapshot Transfer
查看>>
C++小代码
查看>>
记一次思维转变的时刻
查看>>
phpcms v9 中的数据库操作函数
查看>>
远程桌面无法复制粘贴
查看>>
bzoj2754
查看>>
redis liunx下安装和配置
查看>>
Asp.Net MVC 学习心得 之 View
查看>>
STL - Map - 运行期自定义排序
查看>>
Oil Deposits
查看>>
c++builder6.0 mdi窗体+自定义子窗体
查看>>
poj3984 迷宫问题(简单搜索+记录路径)
查看>>
Linux 服务器buff/cache清理
查看>>
算法试题 及其他知识点
查看>>
php课程---Json格式规范需要注意的小细节
查看>>
hadoop hdfs notes
查看>>