beego orm

栏目: Go · 发布时间: 7年前

内容简介:ORM官方文档为:beego orm是支持database/sql标准接口的ORM库,所以理论上来说,只要数据库驱动支持database/sql接口就可以无缝的接入beego orm。目前的驱动包括下面几个:首先你需要import相应的数据库驱动包、database/sql标准接口包以及beego orm包,如下所示:

ORM官方文档为: https://github.com/beego/beedoc/blob/master/zh-CN/mvc/model/orm.md

beego orm是支持database/sql标准接口的ORM库,所以理论上来说,只要数据库驱动支持database/sql接口就可以无缝的接入beego orm。目前的驱动包括下面几个:

Mysql: [github/go-mysql-driver/mysql](https://github.com/go-sql-driver/mysql)

PostgreSQL: [github.com/lib/pq](https://github.com/lib/pq)

SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)

Mysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql)

暂未支持数据库:

MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)

MS ADODB: [github.com/mattn/go-adodb](https://github.com/mattn/go-adodb)

Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8)

ODBC: [bitbucket.org/miquella/mgodbc](https://bitbucket.org/miquella/mgodbc)

## [](https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/05.5.md#%E5%AE%89%E8%A3%85)

初始化

首先你需要import相应的数据库驱动包、database/sql标准接口包以及beego orm包,如下所示:

import (
    "database/sql"
    "github.com/astaxie/beego/orm"
    _ "github.com/go-sql-driver/mysql"
)

func init() {
    //注册驱动
    orm.RegisterDriver("mysql", orm.DR_MySQL)
    //设置默认数据库
    orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
    //注册定义的model
        orm.RegisterModel(new(User))

    // 创建table
        orm.RunSyncdb("default", false, true)
}

PostgreSQL 配置:

//导入驱动
// _ "github.com/lib/pq"

// 注册驱动
orm.RegisterDriver("postgres", orm.DR_Postgres) 

// 设置默认数据库
//PostgresQL用户:postgres ,密码:zxxx , 数据库名称:test , 数据库别名:default
orm.RegisterDataBase("default", "postgres", "user=postgres password=zxxx dbname=test host=127.0.0.1 port=5432 sslmode=disable")

MySQL 配置:

//导入驱动
//_ "github.com/go-sql-driver/mysql"

//注册驱动
orm.RegisterDriver("mysql", orm.DR_MySQL)

// 设置默认数据库
//mysql用户:root ,密码:zxxx , 数据库名称:test , 数据库别名:default
 orm.RegisterDataBase("default", "mysql", "root:zxxx@/test?charset=utf8")

Sqlite 配置:

//导入驱动
//_ "github.com/mattn/go-sqlite3"

//注册驱动
orm.RegisterDriver("sqlite", orm.DR_Sqlite)

// 设置默认数据库
//数据库存放位置:./datas/test.db , 数据库别名:default
orm.RegisterDataBase("default", "sqlite3", "./datas/test.db")

导入必须的package之后,我们需要打开到数据库的链接,然后创建一个beego orm对象(以 MySQL 为例),如下所示 beego orm:

func main() {
        o := orm.NewOrm()
}

简单示例:

package main

import (
    "fmt"
    "github.com/astaxie/beego/orm"
    _ "github.com/go-sql-driver/mysql" // 导入数据库驱动
)

// Model Struct
type User struct {
    Id   int
    Name string `orm:"size(100)"`
}

func init() {
    // 设置默认数据库
    orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
    
    // 注册定义的 model
    orm.RegisterModel(new(User))
//RegisterModel 也可以同时注册多个 model
//orm.RegisterModel(new(User), new(Profile), new(Post))

    // 创建 table
    orm.RunSyncdb("default", false, true)
}

func main() {
    o := orm.NewOrm()

    user := User{Name: "slene"}

    // 插入表
    id, err := o.Insert(&user)
    fmt.Printf("ID: %d, ERR: %v\n", id, err)

    // 更新表
    user.Name = "astaxie"
    num, err := o.Update(&user)
    fmt.Printf("NUM: %d, ERR: %v\n", num, err)

    // 读取 one
    u := User{Id: user.Id}
    err = o.Read(&u)
    fmt.Printf("ERR: %v\n", err)

    // 删除表
    num, err = o.Delete(&u)
    fmt.Printf("NUM: %d, ERR: %v\n", num, err)
}

SetMaxIdleConns

根据数据库的别名,设置数据库的最大空闲连接

orm.SetMaxIdleConns("default", 30)

SetMaxOpenConns

根据数据库的别名,设置数据库的最大数据库连接 (go >= 1.2)

orm.SetMaxOpenConns("default", 30)

目前beego orm支持打印调试,你可以通过如下的代码实现调试

orm.Debug = true

接下来我们的例子采用前面的数据库表User,现在我们建立相应的struct

type Userinfo struct {
    Uid     int `PK` //如果表的主键不是id,那么需要加上pk注释,显式的说这个字段是主键
    Username    string
    Departname  string
    Created     time.Time
}

type User struct {
    Uid          int `PK` //如果表的主键不是id,那么需要加上pk注释,显式的说这个字段是主键
    Name        string
    Profile     *Profile   `orm:"rel(one)"` // OneToOne relation
    Post        []*Post `orm:"reverse(many)"` // 设置一对多的反向关系
}

type Profile struct {
    Id          int
    Age         int16
    User        *User   `orm:"reverse(one)"` // 设置一对一反向关系(可选)
}

type Post struct {
    Id    int
    Title string
    User  *User  `orm:"rel(fk)"`
    Tags  []*Tag `orm:"rel(m2m)"`    //设置一对多关系
}

type Tag struct {
    Id    int
    Name  string
    Posts []*Post `orm:"reverse(many)"`
}

func init() {
    // 需要在init中注册定义的model
    orm.RegisterModel(new(Userinfo),new(User), new(Profile), new(Tag))
}

注意一点,beego orm针对驼峰命名会自动帮你转化成下划线字段,例如你定义了Struct名字为UserInfo,那么转化成底层实现的时候是user_info,字段命名也遵循该规则。

插入数据

下面的代码演示了如何插入一条记录,可以看到我们操作的是struct对象,而不是原生的 sql 语句,最后通过调用Insert接口将数据保存到数据库。

o := orm.NewOrm()
var user User
user.Name = "zxxx"
user.Departname = "zxxx"

id, err := o.Insert(&user)
if err == nil {
    fmt.Println(id)
}

我们看到插入之后user.Uid就是插入成功之后的自增ID。

同时插入多个对象:InsertMulti

类似sql语句

insert into table (name, age) values("slene", 28),("astaxie", 30),("unknown", 20)

第一个参数 bulk 为并列插入的数量,第二个为对象的slice

返回值为成功插入的数量

users := []User{
    {Name: "slene"},
    {Name: "astaxie"},
    {Name: "unknown"},
    ...
}
successNums, err := o.InsertMulti(100, users)

bulk 为 1 时,将会顺序插入 slice 中的数据

更新数据

继续上面的例子来演示更新操作,现在user的主键已经有值了,此时调用Insert接口,beego orm内部会自动调用update以进行数据的更新而非插入操作。

o := orm.NewOrm()
user := User{Uid: 1}
if o.Read(&user) == nil {
    user.Name = "MyName"
    if num, err := o.Update(&user); err == nil {
        fmt.Println(num)
    }
}

Update 默认更新所有的字段,可以更新指定的字段:

// 只更新 Name
o.Update(&user, "Name")
// 指定多个字段
// o.Update(&user, "Field1", "Field2", ...)

//Where:用来设置条件,支持多个参数,第一个参数如果为整数,相当于调用了Where("主键=?",值)。

查询数据

beego orm的查询接口比较灵活,具体使用请看下面的例子

例子1,根据主键获取数据:

o := orm.NewOrm()
var user User

user := User{Id: 1}

err = o.Read(&user)

if err == orm.ErrNoRows {
    fmt.Println("查询不到")
} else if err == orm.ErrMissPK {
    fmt.Println("找不到主键")
} else {
    fmt.Println(user.Id, user.Name)
}

例子2:

o := orm.NewOrm()
var user User

qs := o.QueryTable(user) // 返回 QuerySeter
qs.Filter("id", 1) // WHERE id = 1
qs.Filter("profile__age", 18) // WHERE profile.age = 18

例子3,WHERE IN查询条件:

qs.Filter("profile__age__in", 18, 20) 
// WHERE profile.age IN (18, 20)

例子4,更加复杂的条件:

qs.Filter("profile__age__in", 18, 20).Exclude("profile__lt", 1000)
// WHERE profile.age IN (18, 20) AND NOT profile_id < 1000

可以通过如下接口获取多条数据,请看示例

例子1,根据条件age>17,获取20位置开始的10条数据的数据

var allusers []User
qs.Filter("profile__age__gt", 17)
// WHERE profile.age > 17

例子2,limit默认从10开始,获取10条数据

qs.Limit(10, 20)
// LIMIT 10 OFFSET 20 注意跟SQL反过来的

删除数据

beedb提供了丰富的删除数据接口,请看下面的例子

例子1,删除单条数据

o := orm.NewOrm()
if num, err := o.Delete(&User{Id: 1}); err == nil {
    fmt.Println(num)
}

Delete 操作会对反向关系进行操作,此例中 Post 拥有一个到 User 的外键。删除 User 的时候。如果 on_delete 设置为默认的级联操作,将删除对应的 Post

关联查询

有些应用却需要用到连接查询,所以现在beego orm提供了一个简陋的实现方案:

type Post struct {
    Id    int    `orm:"auto"`
    Title string `orm:"size(100)"`
    User  *User  `orm:"rel(fk)"`
}

var posts []*Post
qs := o.QueryTable("post")
num, err := qs.Filter("User__Name", "slene").All(&posts)

上面代码中我们看到了一个struct关联查询

Group By和Having

针对有些应用需要用到group by的功能,beego orm也提供了一个简陋的实现

qs.OrderBy("id", "-profile__age")
// ORDER BY id ASC, profile.age DESC

qs.OrderBy("-profile__age", "profile")
// ORDER BY profile.age DESC, profile_id ASC

上面的代码中出现了两个新接口函数

GroupBy:用来指定进行groupby的字段

Having:用来指定having执行的时候的条件

使用原生sql

简单示例:

o := orm.NewOrm()
var r orm.RawSeter
r = o.Raw("UPDATE user SET name = ? WHERE name = ?", "testing", "slene")

复杂原生sql使用:

func (m *User) Query(name string) user []User {
    var o orm.Ormer
    var rs orm.RawSeter
    o = orm.NewOrm()
    rs = o.Raw("SELECT * FROM user "+
        "WHERE name=? AND uid>10 "+
        "ORDER BY uid DESC "+
        "LIMIT 100", name)
    //var user []User
    num, err := rs.QueryRows(&user)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println(num)
        //return user
    }
    return
}

命令模式

注册模型与数据库以后,调用 RunCommand 执行 orm 命令。

func main() {
    // orm.RegisterModel...
    // orm.RegisterDataBase...
    ...
    orm.RunCommand()
}
go build main.go
./main orm
# 直接执行可以显示帮助
# 如果你的程序可以支持的话,直接运行 go run main.go orm 也是一样的效果

自动建表

./main orm syncdb -h
Usage of orm command: syncdb:
  -db="default": DataBase alias name
  -force=false: drop tables before create
  -v=false: verbose info

使用 -force=1 可以 drop table 后再建表

使用 -v 可以查看执行的 sql 语句

在程序中直接调用自动建表:

// 数据库别名
name := "default"

// drop table 后再建表
force := true

// 打印执行过程
verbose := true

// 遇到错误立即返回
err := orm.RunSyncdb(name, force, verbose)
if err != nil {
    fmt.Println(err)
}

自动建表功能在非 force 模式下,是会自动创建新增加的字段的。也会创建新增加的索引。

对于改动过的旧字段,旧索引,需要用户自行进行处理。

打印建表SQL

./main orm sqlall -h
Usage of orm command: syncdb:
  -db="default": DataBase alias name

默认使用别名为 default 的数据库。

注:此博客原文为: https://github.com/astaxie/build-web-application-with-golang/blob/master/zh/05.5.md

侵删


以上所述就是小编给大家介绍的《beego orm》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Linux Programming Interface

The Linux Programming Interface

Michael Kerrisk / No Starch Press / 2010-11-6 / GBP 79.99

The Linux Programming Interface describes the Linux API (application programming interface)-the system calls, library functions, and other low-level interfaces that are used, directly or indirectly, b......一起来看看 《The Linux Programming Interface》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具