数据库
概述
想要通过代码来控制数据库,那么在代码中,首先需要连接到数据库,只有打开了一个连接(socket),才可以通过代码来对数据库进行操作
而一般情况下,数据库并不是通过 go 语言写的,那么如何连接呢,就需要调用数据库的 API 接口,而想要调用该接口,则需要使用第三方库才可以,这个第三方库,这个库会提供几种"method",包括连接数据库,对数据库执行操作等。
GORM
参考:
GORM 是一个出色的 ORM 库,旨在对开发人员友好。
- 全功能ORM(几乎)
- 关联(包含一个,包含多个,属于,多对多,多种包含)
- Callbacks(创建/保存/更新/删除/查找之前/之后)
- 预加载(急加载)
- 事务
- 复合主键
- SQL Builder
- 自动迁移
- 日志
- 可扩展,编写基于GORM回调的插件
- 每个功能都有测试
- 开发人员友好
常用示例
gorm模糊查询和分页查询同时查总条数
func (u *userService) GetuserList(offset, limit int, search User) (users []User, count int, err error) {
if search.Name != "" {
u.mysql = u.mysql.Where("name LIKE ?", search.Name+"%")
}
if search.Category != "" {
u.mysql = u.mysql.Where("age =?", search.Age)
}
err = u.mysql.Offset(offset).Limit(limit).Find(&users).Offset(-1).Limit(-1).Count(&count).Error
return users, count, err
}
这简单的一小段已经包含了gorm的模糊查询,动态条件,分页查询,数据条数。 这就是一个最常见的列表查询,列表需要支持条件查询,模糊查询,分页,从代码可以直接看到。
if
代码是动态组装条件。err = u.mysql.Offset(offset).Limit(limit).Find(&users).Offset(-1).Limit(-1).Count(&count).Error
这行代码包含了数据列表查询和数据条数。- 有些需要注意的地方是
u.mysql.Offset(offset).Limit(limit).Find(&users)
用于查询数据列表, .Offset(-1).Limit(-1).Count(&count)
用户查询条数,Offset(-1)和Limit(-1)很重要,不加的话会在统计条数后也加上offset和limit,导致查不到条数。 查询结果:
SELECT * FROM `user` LIMIT 10 OFFSET 0;
SELECT count(*) FROM `user`;
常见问题
为 For 循环中的多个 Or 创建分组
参考:
for _, field := range queryCardDesc.QField {
result = result.Or(field+" LIKE ?", "%"+queryCardDesc.Keyword+"%")
}
上面的例子通过 result=result.Where(result)
分组将会异常,产生多次 SQL,就像这样:
SELECT count(*) FROM `card_descs` WHERE (effect LIKE '%奥米加%' OR sc_name LIKE '%奥米加%' OR evo_cover_effect LIKE '%奥米加%') OR sc_name LIKE '%奥米加%' OR evo_cover_effect LIKE '%奥米加%' OR effect LIKE '%奥米加%' AND color LIKE '%红%'
可以通过如此方式解决:
f := func(queryCardDesc *models.CardDescQuery, result *gorm.DB) *gorm.DB {
// 通过 Session() 创建一个新的 DB 实例,避免影响原来的 DB 实例。用以实现为多个 Or 分组的功能
newResult := result.Session(&gorm.Session{NewDB: true})
for _, field := range queryCardDesc.QField {
newResult = newResult.Or(field+" LIKE ?", "%"+queryCardDesc.Keyword+"%")
}
return newResult
}(queryCardDesc, result)
Redis
go get -u -v github.com/garyburd/redigo/redis
package main
import (
"fmt"
"github.com/garyburd/redigo/redis" // 引入redis第三方库
)
func main() {
// 连接到redis
c, err := redis.Dial("tcp", "127.0.0.1:6379")
if err != nil {
fmt.Println("Connect to redis error", err)
return
}
// 注意关闭连接
defer c.Close()
// 通过go代码向redis写入数据
_, err = c.Do("SET", "mykey", "superWang")
if err != nil {
fmt.Println("redis set failed:", err)
}
// 通过go代码读取redis中的数据,由于返回的值为 interface{} ,所以需要转换成字符串,才能正常显示
username, err := redis.String(c.Do("GET", "mykey"))
if err != nil {
fmt.Println("redis get failed:", err)
} else {
fmt.Printf("Get mykey: %v \n", username)
}
}
反馈
此页是否对你有帮助?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.