• 1. 获取ORM对象
  • 2. 单表/联表查询
    • 1). 基础查询
    • 2). join查询
    • 3). select in查询
    • 4). like查询
    • 5). sum查询
    • 6). count查询
    • 7). distinct查询
  • 3. 链式更新/删除
  • 4. 链式写入/保存
  • 5. 链式批量写入
  • 6. 链式批量保存
  • 7. 参数自动过滤
  • 8. 查询结果处理

    1. 获取ORM对象

    1. // 获取默认配置的数据库对象(配置名称为"default")
    2. db := g.Database()
    3. // 或者(别名方式, 推荐)
    4. db := g.DB()
    5. // 获取配置分组名称为"user-center"的数据库对象
    6. db := g.Database("user-center")
    7. // 或者 (别名方式, 推荐)
    8. db := g.DB("user-center")
    9. // 使用原生New方法创建数据库对象
    10. db, err := gdb.New()
    11. db, err := gdb.New("user-center")
    12. // 使用原生单例管理方法获取数据库对象单例
    13. db, err := gdb.Instance()
    14. db, err := gdb.Instance("user-center")
    15. // 注意不用的时候不需要使用Close方法关闭数据库连接(并且gdb也没有提供Close方法),
    16. // 数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭

    2. 单表/联表查询

    TIPS: Where条件参数推荐使用字符串的传递方式(使用?占位符预处理),因为map/struct类型作为查询参数无法保证顺序性,且在部分情况下(数据库有时会帮助你自动进行查询索引优化),数据库的索引和你传递的查询条件顺序有一定关系。

    条件连接符号可以使用Where/And/Or,其中当使用多个Where方法连接查询条件时,作用同And。此外,当存在多个查询条件时,gdb会默认将多个条件分别使用()符号进行包含,这种设计可以非常友好地支持查询条件分组。

    1). 基础查询

    Where + string,条件参数使用字符串和预处理。

    1. // 查询多条记录并使用Limit分页
    2. // SELECT * FROM user WHERE uid>1 LIMIT 0,10
    3. r, err := db.Table("user").Where("uid > ?", 1).Limit(0, 10).Select()
    4. // 使用Fields方法查询指定字段
    5. // 未使用Fields方法指定查询字段时,默认查询为*
    6. // SELECT uid,name FROM user WHERE uid>1 LIMIT 0,10
    7. r, err := db.Table("user").Fileds("uid,name").Where("uid > ?", 1).Limit(0, 10).Select()
    8. // 支持多种Where条件参数类型
    9. // SELECT * FROM user WHERE uid=1
    10. r, err := db.Table("user").Where("u.uid=1",).One()
    11. r, err := db.Table("user").Where("u.uid", 1).One()
    12. r, err := db.Table("user").Where("u.uid=?", 1).One()
    13. // SELECT * FROM user WHERE (uid=1) AND (name='john')
    14. r, err := db.Table("user").Where("uid", 1).Where("name", "john").One()
    15. r, err := db.Table("user").Where("uid=?", 1).And("name=?", "john").One()
    16. // SELECT * FROM user WHERE (uid=1) OR (name='john')
    17. r, err := db.Table("user").Where("uid=?", 1).Or("name=?", "john").One()

    Where + slice,预处理参数可直接通过slice参数给定。

    1. // SELECT * FROM user WHERE age>18 AND name like '%john%'
    2. r, err := db.Table("user").Where("age>? AND name like ?", g.Slice{18, "%john%"}).All()
    3. // SELECT * FROM user WHERE status=1
    4. r, err := db.Table("user").Where("status=?", g.Slice{1}).All()

    Where + map,条件参数使用任意map类型传递。

    1. // SELECT * FROM user WHERE uid=1 AND name='john'
    2. r, err := db.Table("user").Where(g.Map{"uid" : 1, "name" : "john"}).One()
    3. // SELECT * FROM user WHERE uid=1 AND age>18
    4. r, err := db.Table("user").Where(g.Map{"uid" : 1, "age>" : 18}).One()

    Where + struct/*structstruct标签支持 gconv/json,映射属性到字段名称关系。

    1. type User struct {
    2. Id int `json:"uid"`
    3. UserName string `gconv:"name"`
    4. }
    5. // SELECT * FROM user WHERE uid =1 AND name='john'
    6. r, err := db.Table("user").Where(User{ Id : 1, UserName : "john"}).One()
    7. // SELECT * FROM user WHERE uid =1
    8. r, err := db.Table("user").Where(&User{ Id : 1}).One()

    以上的查询条件相对比较简单,我们来看一个比较复杂的查询示例。

    1. conditions := g.Map{
    2. "title like ?" : "%九寨%",
    3. "online" : 1,
    4. "hits between ? and ?" : g.Slice{1, 10},
    5. "exp > 0" : nil,
    6. "category" : g.Slice{100, 200},
    7. }
    8. result, err := db.Table("article").Where(conditions).All()
    9. // SELECT * FROM article WHERE title like '%九寨%' AND online=1 AND hits between 1 and 10 AND exp > 0 AND category IN(100,200)

    2). join查询

    1. // 查询符合条件的单条记录(第一条)
    2. // SELECT u.*,ud.site FROM user u LEFT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1
    3. r, err := db.Table("user u").LeftJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.site").Where("u.uid=?", 1).One()
    4. // 查询指定字段值
    5. // SELECT ud.site FROM user u RIGHT JOIN user_detail ud ON u.uid=ud.uid WHERE u.uid=1 LIMIT 1
    6. r, err := db.Table("user u").RightJoin("user_detail ud", "u.uid=ud.uid").Fields("ud.site").Where("u.uid=?", 1).Value()
    7. // 分组及排序
    8. // SELECT u.*,ud.site FROM user u INNER JOIN user_detail ud ON u.uid=ud.uid GROUP BY city ORDER BY register_time asc
    9. r, err := db.Table("user u").InnerJoin("user_detail ud", "u.uid=ud.uid").Fields("u.*,ud.city").GroupBy("city").OrderBy("register_time asc").Select()
    10. // 不使用join的联表查询
    11. // SELECT u.*,ud.city FROM user u,user_detail ud WHERE u.uid=ud.uid
    12. r, err := db.Table("user u,user_detail ud").Where("u.uid=ud.uid").Fields("u.*,ud.city").All()

    3). select in查询

    使用字符串、slice参数类型。当使用slice参数类型时,预处理占位符只需要一个?即可。

    1. // SELECT * FROM user WHERE uid IN(100,10000,90000)
    2. r, err := db.Table("user").Where("uid IN(?,?,?)", 100, 10000, 90000).All()
    3. // SELECT * FROM user WHERE gender=1 AND uid IN(100,10000,90000)
    4. r, err := db.Table("user").Where("gender=? AND uid IN(?)", 1, g.Slice{100, 10000, 90000}).All()
    5. // SELECT COUNT(*) FROM user WHERE age in(18,50)
    6. r, err := db.Table("user").Where("age IN(?,?)", 18, 50).Count()

    使用任意map参数类型。

    1. // SELECT * FROM user WHERE gender=1 AND uid IN(100,10000,90000)
    2. r, err := db.Table("user").Where(g.Map{
    3. "gender" : 1,
    4. "uid" : g.Slice{100,10000,90000},
    5. }).All()

    使用struct参数类型,注意查询条件的顺序和struct的属性定义顺序有关。

    1. type User struct {
    2. Id []int `gconv:"uid"`
    3. Gender int `gconv:"gender"`
    4. }
    5. // SELECT * FROM user WHERE uid IN(100,10000,90000) AND gender=1
    6. r, err := db.Table("user").Where(User{
    7. "gender" : 1,
    8. "uid" : []int{100, 10000, 90000},
    9. }).All()

    4). like查询

    1. // SELECT * FROM user WHERE name like '%john%'
    2. r, err := db.Table("user").Where("name like ?", "%john%").Select()
    3. // SELECT * FROM user WHERE birthday like '1990-%'
    4. r, err := db.Table("user").Where("birthday like ?", "1990-%").Select()

    5). sum查询

    1. // SELECT SUM(score) FROM user WHERE uid=1
    2. r, err := db.Table("user").Fields("SUM(score)").Where("uid=?", 1).Value()

    6). count查询

    1. // SELECT COUNT(1) FROM user WHERE `birthday`='1990-10-01'
    2. r, err := db.Table("user").Where("birthday=?", "1990-10-01").Count()
    3. // SELECT COUNT(uid) FROM user WHERE `birthday`='1990-10-01'
    4. r, err := db.Table("user").Fields("uid").Where("birthday=?", "1990-10-01").Count()

    7). distinct查询

    1. // SELECT DISTINCT uid,name FROM user
    2. r, err := db.Table("user").Fields("DISTINCT uid,name").Select()

    3. 链式更新/删除

    1. // UPDATE user SET name='john guo' WHERE name='john'
    2. r, err := db.Table("user").Data(gdb.Map{"name" : "john guo"}).Where("name=?", "john").Update()
    3. r, err := db.Table("user").Data("name='john guo'").Where("name=?", "john").Update()
    4. // UPDATE user SET status=1 ORDER BY login_time asc LIMIT 10
    5. r, err := db.Table("user").Data("status", 1).OrderBy("login_time asc").Limit(10).Update
    6. // DELETE FROM user WHERE uid=10
    7. r, err := db.Table("user").Where("uid=?", 10).Delete()
    8. // DELETE FROM user ORDER BY login_time asc LIMIT 10
    9. r, err := db.Table("user").OrderBy("login_time asc").Limit(10).Delete()

    其中Data是数值方法,用于指定写入/更新/批量写入/批量更新的数值。支持多种形式的数值参数:

    1. r, err := db.Table("user").Data("status=1").Update()
    2. r, err := db.Table("user").Data("status", 1).Update()
    3. r, err := db.Table("user").Data(g.Map{"status" : 1}).Update()

    4. 链式写入/保存

    1. r, err := db.Table("user").Data(gdb.Map{"name": "john"}).Insert()
    2. r, err := db.Table("user").Data(g.Map{"uid": 10000, "name": "john"}).Replace()
    3. r, err := db.Table("user").Data(g.Map{"uid": 10001, "name": "john"}).Save()

    其中,数值方法参数既可以使用gdb.Map,也可以使用g.Map

    5. 链式批量写入

    1. r, err := db.Table("user").Data(gdb.List{
    2. {"name": "john_1"},
    3. {"name": "john_2"},
    4. {"name": "john_3"},
    5. {"name": "john_4"},
    6. }).Insert()

    可以通过Batch方法指定批量操作中分批写入条数数量:

    1. r, err := db.Table("user").Data(g.List{
    2. {"name": "john_1"},
    3. {"name": "john_2"},
    4. {"name": "john_3"},
    5. {"name": "john_4"},
    6. }).Batch(2).Insert()

    当然,gdb.List类型也可以使用g.List类型。

    6. 链式批量保存

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

    7. 参数自动过滤

    gdb可以自动同步数据表结构到程序缓存中(缓存不过期,直至程序重启/重新部署),并且可以过滤提交参数中不符合表结构的数据项,该特性可以使用Filter方法实现,例如:

    1. r, err := db.Table("user").Filter().Data(g.Map{
    2. "id" : 1,
    3. "uid" : 1,
    4. "passport" : "john",
    5. "password" : "123456",
    6. }).Insert()
    7. // INSERT INTO user(uid,passport,password) VALUES(1, "john", "123456")

    其中id为不存在的字段,在写入数据时将会被过滤掉,不至于被构造成写入SQL中产生执行错误。

    8. 查询结果处理

    请参考【ORM结果处理】章节。