CURD
Create
json自定义字段使用
如下为system使用自定义字段
1
2
3type System struct{
Version string
}为自定义类型实现接口Value/Scan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25func (s System)Value()(driver.Value, error) {
bytes, err := json.Marshal(s)
return string(bytes), err
}
func (s *System) Scan(value interface{}) error {
var bytes []byte
switch v := value.(type) {
case []byte:
bytes = v
case string:
bytes = []byte(v)
default:
return fmt.Errorf("解析失败,原始数据:%v", value)
}
result := System{}
if len(bytes) <= 0 {
*s = result
return nil
}
err := json.Unmarshal(bytes, &result)
*s = result
return err
}json查询,例如这里要查询version=1.0的System
1
2select * from table_t
where system->'$.version' = "1.0"
Update
Retrieve
预加载,preload
外键tag
预加载依赖在领域层结构体变量的gorm tag,需要在结构体上变量上增加外键tag,tag有多种写法,根
领域对象间的不同关系如:belongs to/has one/has many等有不同写法.
- belongs to 参考: https://gorm.io/zh_CN/docs/belongs_to.html
- has one
- has many
- many to many
在项目ForeignKey,References这两个标签最常用,主要用于Preload相关数据
自定义预加载,可在预加载时添加条件实现排序等功能
排序
1
2
3
4
5
6
7// 文档:https://gorm.io/zh_CN/docs/preload.html
//您可以通过 func(db *gorm.DB) *gorm.DB 实现自定义预加载 SQL,例如:
db.Preload("Users", func(db *gorm.DB) *gorm.DB {
return db.Order("user.age DESC")
}).Find(&users)
// SELECT * FROM user WHERE id IN (1,2,3,4) order by user.age DESC;
2.
order by
常用
指定从数据库检索记录时的排序方式1
2
3
4
5
6
7
8
9
10
11db.Order("age desc, name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;
// 多个 order
db.Order("age desc").Order("name").Find(&users)
// SELECT * FROM users ORDER BY age desc, name;
db.Clauses(clause.OrderBy{
Expression: clause.Expr{SQL: "FIELD(id,?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
}).Find(&User{})
// SELECT * FROM users ORDER BY FIELD(id,1,2,3)order by field 自定义排序
使用上面的写法通过自定义字段排序时注意,WithoutParentheses为true,为false是构建的sql为order by field(column,(“f1,f2,f3,…”)),会报错组合排序
1
2
3select id,status,create_time
FROM `order`
ORDER BY FIELD(status,'s3','s2','s1')desc,create_time desc如上的sql使用gorm框架可以这么写:
1
2
3
4
5
6
7
8res:=[]*Order{}
db.Clauses(clause.OrderBy{
Expression: clause.Expr{
SQL: "FIELD(status,?) DESC,create_time DESC",
Vars: []interface{}{
[]string{"s3","s2","s1"},
},
WithoutParentheses: true}}).Find(&res)不能使用链式调用(gorm v2版本,版本号:gorm.io/gorm v1.20.11),如:
1
2
3
4
5
6
7
8
9db.Clauses(clause.OrderBy{
Expression: clause.Expr{
SQL: "FIELD(status,?) DESC",
Vars: []interface{}{
[]string{"s3","s2","s1"},
},
WithoutParentheses: true}}).
Order("create_time DESC").
Find(&res)参考文档
- gorm v2文档: https://gorm.io/zh_CN/docs/query.html#Order
索引
强制索引
1
2
3
4
5
6
7
8
9
10
11
12import "gorm.io/hints"
db.Clauses(hints.UseIndex("idx_user_name")).Find(&User{})
// SELECT * FROM `users` USE INDEX (`idx_user_name`)
db.Clauses(hints.ForceIndex("idx_user_name", "idx_user_id").ForJoin ()).Find(&User{})
// SELECT * FROM `users` FORCE INDEX FOR JOIN (`idx_user_name`, `idx_user_id`)"
db.Clauses(
hints.ForceIndex("idx_user_name", "idx_user_id").ForOrderBy(),
hints.IgnoreIndex("idx_user_name").ForGroupBy(),
).Find(&User{})Index 用于提高数据检索和 SQL 查询性能。 Index Hints 向优化器提供了在查询处理过程中如何选择索引的信息。与 optimizer 相比,它可以更灵活地选择更有效的执行计划
- 加了join
1
2
3
4db.Table("`order` FORCE INDEX (order_create_time_d977ab1e,idx_demand_number, idx_stocked_number,idx_di)").
//Clauses(hints.CommentBefore("from", "FORCE INDEX (order_create_time_d977ab1e, idx_demand_number,idx_stocked_number,idx_di)")).
// 这样写,生成的sql语句有问题,force index位置在where条件中间
Joins("left join servicelist on order.service_list_id=servicelist.id").Find(& orders)
Delete
Config
ConnPool
gorm 连接池配置通过sql.DB实现
1
2
3
4
5
6
7
8
9gormDB,err:=gorm.Open(...)
db,err:=gormDB.DB()
if err!=nil{
return
}
db.SetConnMaxLifetime() //连接最长复用时间
db.SetConnMaxIdleTime() //maximum amount of time a connection may be idle,最长空闲时间
db.SetMaxIdleConns() // 最长空闲时间 maximum number of connections in the idle connection pool
db.SetMaxOpenConns() // 最大连接数 maximum number of open connections to the database