GoFrame ORM 使用实践分享

简介: 今天这篇把我使用GoFrame ORM的过程中认为有价值、可能踩坑、比较好的实践等相关的知识点分享出来。

今天这篇把我使用GoFrame ORM的过程中认为有价值、可能踩坑、比较好的实践等相关的知识点分享出来。


值类型和指针类型


初学go的时候一直在纠结值类型和指针类型,后来在用的过程中发现大可不必纠结。

指针类型的优势就是节省内存空间,多个变量指向同一个内存地址,一荣俱荣,一个修改,处处修改。


而值类型可以简单理解为:避免这种一处修改处处修改的问题,有些场景下我们不能单纯的考虑性能,不能单纯地只考虑复用


在GoFrame中也鼓励我们使用指针类型,举个栗子:


使用Scan将查询结果转换成struct对象


Scan支持将查询结果转换为一个struct对象,查询结果应当是特定的一条记录,并且pointer参数应当为struct对象的指针地址(*struct或者**struct),使用方式例如:


type User struct {
    Id         int
    Passport   string
    Password   string
    NickName   string
    CreateTime *gtime.Time
}
user := User{}
g.Model("user").Where("id", 1).Scan(&user)


或者


var user = User{}
g.Model("user").Where("id", 1).Scan(&user)


前两种方式都是预先初始化对象(提前分配内存)


推荐的方式如下,这种方式只有在查询到数据的时候才会执行初始化及内存分配:


var user *User
g.Model("user").Where("id", 1).Scan(&user)


注意在用法上的区别,特别是传递参数类型的差别(前两种方式传递的参数类型是*User,这里传递的参数类型其实是**User)。


插入数据


InsertIgnore


这个函数需要重点和大家说一下,因为我之前有Laravel的使用经验,Laravel中的InsertIgnore是配合唯一索引使用,意思是如果存在唯一主键或者唯一索引就忽略掉,不重复插入。


在GoFrame中是相反的:


GoFrame中默认的insert函数,就会根据唯一索引(或主键)执行,如果有存在的数据返回失败,不重复插入。


而GoFrame中的InsertIgnore是忽略错误继续插入,而不是存在就不插入。


大家在使用中要注意。


灵活执行SQL


我们要拼接自定义的sql参数怎么办法呢?


gdb.Raw()


示例如下:


OnDuplicate(g.Map{
    "nickname": gdb.Raw("CONCAT('name_', VALUES(`nickname`))"),
})


gdb.Raw() 中的参数将作为sql执行的语句,不会自动转换成字符串类型,也不会作为预处理参数。


示例如下:


// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES(id+2,'80','123456','wzy',now())
g.Model("user").Data(g.Map{
  "id":          gdb.Raw("id+2"),
  "passport":    "80",
  "password":    "123456",
  "nickname":    "wzy",
  "create_time": gdb.Raw("now()"),
}).Insert()


链式安全

我们首先要有这个概念:什么是链式安全?


其实很简单:链式安全就是操作model模型时不会改变当前model对象,模型属性修改/条件叠加需要使用赋值来操作。


链式非安全或者非链式安全就是:操作model模型时会改变当前model对象的属性。


在GoFrame开发过程中,强烈建议使用gf gen dao生成的model和dao文件!!!


通过gf gen dao生成的model和dao文件默认是链式安全的。


举例如下:


func NewGomeStockDao() *GomeStockDao {
   return &GomeStockDao{
      M:     g.DB("default").Model("gome_stock").Safe(), //注意看这里
      DB:    g.DB("default"),
      Table: "gome_stock",
      Columns: gomeStockColumns{
         Id:            "id",
         MchWhseCode:   "mch_whse_code",
         MchWhseName:   "mch_whse_name",
         IsNationWide:  "is_nation_wide",
         Status:        "status",
         LastUpateTime: "last_upate_time",
      },
   }
}


链式安全时我们如何叠加条件改变呢?


答案就是:通过赋值。

链式安全时通过 m = m.xxx 方式赋值实现链式调用


举例如下:


m := user.Where("status IN(?)", g.Slice{1,2,3})
if vip {
    // 查询条件通过赋值叠加
    m = m.And("money>=?", 1000000)
} else {
    // 查询条件通过赋值叠加
    m = m.And("money<?",  1000000)
}
//  vip: SELECT * FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT * FROM user WHERE status IN(1,2,3) AND money < 1000000
r, err := m.All()
//  vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money < 1000000
n, err := m.Count()


相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
5天前
|
Oracle 关系型数据库 MySQL
Django框架ORM操作(二)
Django框架ORM操作(二)
|
5天前
|
SQL 存储 前端开发
Django框架ORM操作(一)
Django框架ORM操作(一)
Django框架ORM操作(一)
|
SQL 存储 缓存
odoo ORM API学习总结兼orm学习教程3
odoo ORM API学习总结兼orm学习教程
272 0
|
存储 缓存 API
odoo ORM API学习总结兼orm学习教程 2
odoo ORM API学习总结兼orm学习教程
149 0
|
存储 SQL XML
odoo ORM API学习总结兼orm学习教程 1
odoo ORM API学习总结兼orm学习教程
115 0
|
SQL 关系型数据库 MySQL
Django框架之ORM
Django框架之ORM
83 0
Django框架之ORM
Beego学习——orm实现简单的crud
Beego学习——orm实现简单的crud
74 0
|
SQL Go
GoFrame ORM原生方法 开箱体验 (上)
gf是支持ORM原生操作的,在ORM链式操作执行不了太过于复杂的SQL操作时,可以交给方法操作来处理。 这篇文章整理原生操作的常用方法,下篇文章根据整理的原生方法整理对应的开箱体验。
122 0
|
SQL 数据库连接 数据库
GoFrame ORM原生方法 开箱体验 (下)
gf是支持ORM原生操作的,在ORM链式操作执行不了太过于复杂的SQL操作时,可以交给方法操作来处理。 上一篇文章 整理了ORM的原生方法,这篇文章根据整理的原生方法整理对应的开箱体验。
108 0
GoFrame gset使用实践 | 交差并补集
今天继续分享gset的更多知识点。
GoFrame gset使用实践 | 交差并补集