go语言orm之gorose全新版本2.0低调发布

fizzday · 2019-06-26 20:04:17 · 1844 次点击 · 预计阅读时间 4 分钟 · 大约8小时之前 开始浏览    
这是一个创建于 2019-06-26 20:04:17 的文章,其中的信息可能已经有所发展或是发生改变。

号称go语言版本的laravel's eloquent, 发布了久违了2.0版本, 新版本做了很大的改进和升级, 下面我们一起来看一下新版本的特性.

架构调整

gorose 2.0版本做了彻底的重构, 拥有全新的架构. 架构如图:
gorose-2.0-design

gorose 2.0 采用模块化架构, 通过interface的api通信,严格的上层依赖下层.每一个模块都可以拆卸, 甚至可以自定义为自己喜欢的样子.

  • 主模块
    • engin
      gorose 初始化配置模块, 可以全局保存并复用
    • session
      真正操作数据库底层模块, 所有的操作, 最终都会走到这里来获取或修改数据
    • orm
      对象关系映射模块, 所有的orm操作, 都在这里完成
    • builder
      构建终极执行的sql模块, 可以构建任何数据库的sql, 但要符合database/sql包的接口
  • 子模块
    • driver
      数据库驱动模块, 被engin和builder依赖, 根据驱动来搞事情
    • binder
      结果集绑定模块, 所有的返回结果集都在这里

其他语言入手姿势

  1. php: 使用过laravel的orm就可以快速上手使用
  2. python: 使用过orator orm的用户,可以快速上手
  3. ruby: 使用过rails的orm就可以快速上手

支持驱动

mysql : https://github.com/go-sql-driver/mysql
sqlite3 : https://github.com/mattn/go-sqlite3
postgres : https://github.com/lib/pq
oracle : https://github.com/mattn/go-oci8
mssql : https://github.com/denisenkom/go-mssqldb
clickhouse : https://github.com/kshvakov/clickhouse

特色

  • 连接池
  • 链式调用
  • 支持传入struct,map或字符串表名
  • 读写分离集群支持
  • 海量数据自动分块处理
  • 一键开启事务,自动回滚和提交
  • 模块化架构,自由扩展

官方文档

最新版2.x文档

api预览

db.Table().Fields().Where().GroupBy().Having().OrderBy.Limit().Select()
db.Table().Data().Insert()
db.Table().Data().Where().Update()
db.Table().Where().Delete()

最佳实践

sql

DROP TABLE IF EXISTS "users";
CREATE TABLE "users" (
     "uid" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
     "name" TEXT NOT NULL,
     "age" integer NOT NULL
);

INSERT INTO "users" VALUES (1, 'gorose', 18);
INSERT INTO "users" VALUES (2, 'goroom', 18);
INSERT INTO "users" VALUES (3, 'fizzday', 18);

实战代码

package main

import (
    "fmt"
    "github.com/gohouse/gorose"
    _ "github.com/mattn/go-sqlite3"
)

type Users struct {
    Uid int64 `gorose:"uid"`
    Name string `gorose:"name"`
    Age int64 `gorose:"age"`
    Xxx interface{} `gorose:"ignore"` // 这个字段在orm中会忽略
}

func (u *Users) TableName() string {
    return "users"
}

var err error
var engin *gorose.Engin

func init() {
    // 全局初始化数据库,并复用
    // 这里的engin需要全局保存,可以用全局变量,也可以用单例
    // 配置&gorose.Config{}是单一数据库配置
    // 如果配置读写分离集群,则使用&gorose.ConfigCluster{}
    engin, err = gorose.Open(&gorose.Config{Driver: "sqlite3", Dsn: "./db.sqlite"})
}
func DB() gorose.IOrm {
    return engin.NewOrm()
}
func main() {
    // 这里定义一个变量db, 是为了复用db对象, 可以在最后使用 db.LastSql() 获取最后执行的sql
    // 如果不复用 db, 而是直接使用 DB(), 则会新建一个orm对象, 每一次都是全新的对象
    // 所以复用 db, 一定要在当前会话周期内
    db := DB()
    // 这里的对象是map, 所以需要初始化(var u = user{}), 不能像struct那样, 可以直接 `var u Users`
    var u = Users{}
    var count int64
    // 统计数据
    count,err = db.Table(&u).Fields("uid,name,age").Where("age",">",0).OrderBy("uid desc").Limit(10).Offset(1).Count()
    if err!=nil {
        fmt.Println(err)
    }
    // 查询数据并绑定到 user{} 上, 这里复用了 db 及上下文条件参数
    // 如果不想复用,则可以使用DB()就会开启全新会话,或者使用db.Reset()
    // db.Reset()只会清除上下文参数干扰,不回更换链接,DB()则会更换链接
    err = db.Select()

    fmt.Println(count)
    fmt.Println(u, u.Name.String())
    fmt.Println(db.LastSql())
}

官方网站

https://github.com/gohouse/gorose

官方qq群: 470809220,点击加入


有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1844 次点击  
加入收藏 微博
7 回复  |  直到 2019-08-09 13:45:58
polaris
polaris · #1 · 6年之前

支持~~

建议:按照惯例,忽略的字段,一般使用 - 这个 struct tag。建议 ignore 改为 -,至少得支持 -

18393910396
18393910396 · #2 · 6年之前

首先表示,非常支持!!!其次建议一点,和楼上一样,忽略的字段tag建议用 - 。看了一下,感觉挺不错,下次有机会试试!

fizzday
fizzday · #3 · 6年之前
polarispolaris #1 回复

支持~~ 建议:按照惯例,忽略的字段,一般使用 `-` 这个 struct tag。建议 ignore 改为 `-`,至少得支持 `-`

多谢建议, 正式版已经更改为 -

fizzday
fizzday · #4 · 6年之前
1839391039618393910396 #2 回复

首先表示,非常支持!!!其次建议一点,和楼上一样,忽略的字段tag建议用 - 。看了一下,感觉挺不错,下次有机会试试!

多谢建议, 正式版已经更改为 -

fenglangjuxu
fenglangjuxu · #5 · 6年之前

还是比较喜欢0.x版本 不用创建用户表相关的struct,直接用 现在的2.0模式 和xorm等等流行的orm没什么大的区别吧(仅仅猜测的)

fizzday
fizzday · #6 · 6年之前
fenglangjuxufenglangjuxu #5 回复

还是比较喜欢0.x版本 不用创建用户表相关的struct,直接用 现在的2.0模式 和xorm等等流行的orm没什么大的区别吧(仅仅猜测的)

现在版本, 依然可以不用传入struct, 直接使用即可,如:

result, err := db.Table("users").Get()

或者

type result map[string]interface{}

db.Table(&result).Select()
fenglangjuxu
fenglangjuxu · #7 · 6年之前
fizzdayfizzday #6 回复

#5楼 @fenglangjuxu 现在版本, 依然可以不用传入struct, 直接使用即可,如: ``` result, err := db.Table("users").Get() ``` 或者 ``` type result map[string]interface{} db.Table(&result).Select() ```

奥 那挺好的~

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传