菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
0
0

GORM 中文文档_4.0. 链式操作

原创
05/13 14:22
阅读数 789

链式操作

Gorm 继承了链式操作接口, 所以你可以写像下面一样的代码:

db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")

// 创建一个新的关系
tx := db.Where("name = ?", "jinzhu")

// 新增更多的筛选条件
if someCondition {
    tx = tx.Where("age = ?", 20)
} else {
    tx = tx.Where("age = ?", 30)
}

if yetAnotherCondition {
    tx = tx.Where("active = ?", 1)
}

直到调用立即方法之前都不会产生查询,在某些场景中会很有用。

就像你可以封装一个包来处理一些常见的逻辑

创建方法

创建方法就是那些会产生 SQL 查询并且发送到数据库,通常它就是一些 CRUD 方法, 就像:

Create, First, Find, Take, Save, UpdateXXX, Delete, Scan, Row, Rows...

下面是一个创建方法的例子:

tx.Find(&user)

生成

SELECT * FROM users where name = 'jinzhu' AND age = 30 AND active = 1;

Scopes 方法

Scope 方法基于链式操作理论创建的。

使用它,你可以提取一些通用逻辑,写一些更可用的库。

func AmountGreaterThan1000(db *gorm.DB) *gorm.DB {
    return db.Where("amount > ?", 1000)
}

func PaidWithCreditCard(db *gorm.DB) *gorm.DB {
    return db.Where("pay_mode_sign = ?", "C")
}

func PaidWithCod(db *gorm.DB) *gorm.DB {
    return db.Where("pay_mode_sign = ?", "C")
}

func OrderStatus(status []string) func (db *gorm.DB) *gorm.DB {
    return func (db *gorm.DB) *gorm.DB {
        return db.Scopes(AmountGreaterThan1000).Where("status in (?)", status)
    }
}

db.Scopes(AmountGreaterThan1000, PaidWithCreditCard).Find(&orders)
// 查找所有大于1000的信用卡订单和金额

db.Scopes(AmountGreaterThan1000, PaidWithCod).Find(&orders)
// 查找所有大于1000的 COD 订单和金额

db.Scopes(AmountGreaterThan1000, OrderStatus([]string{"paid", "shipped"})).Find(&orders)
// 查找大于1000的所有付费和运单

多个创建方法

当使用 GORM 的创建方法,后面的创建方法将复用前面的创建方法的搜索条件(不包含内联条件)

db.Where("name LIKE ?", "jinzhu%").Find(&users, "id IN (?)", []int{1, 2, 3}).Count(&count)

生成

SELECT * FROM users WHERE name LIKE 'jinzhu%' AND id IN (1, 2, 3)

SELECT count(*) FROM users WHERE name LIKE 'jinzhu%'

线程安全

所有的链式操作都将会克隆并创建一个新的数据库对象(共享一个连接池),GORM 对于多个 goroutines 的并发使用是安全的。

发表评论

0/200
0 点赞
0 评论
收藏
为你推荐 换一批