Beego ORM 使用

发布时间: 更新时间: 总字数:1328 阅读时间:3m 作者: IP上海 分享 网址

Beego ORM 使用介绍,也可使用gorm作为Beego项目的数据库模块。

示例

package main

import (
	"fmt"

	"github.com/beego/beego/v2/client/orm"
	"github.com/beego/beego/v2/core/logs"
	_ "github.com/go-sql-driver/mysql"
)

type City struct {
	ID   int `orm:"column(id);pk;auto"` // 第一个int类型的值会自动定义为主键,默认转为驼峰式 i_d
	Name string
}

// TableName 指定数据库表名称
func (c *City) TableName() string {
	return "city"
}

func main() {
	// debug 模式
	orm.Debug = true
	// db
	orm.RegisterDriver("mysql", orm.DRMySQL)
	// 可以通过 aliasName 指定多个数据库
	orm.RegisterDataBase("default", "mysql", "root:root@tcp(100.80.0.128:3306)/golangdev?charset=utf8")
	orm.SetMaxIdleConns("default", 10)
	orm.SetMaxOpenConns("default", 5)

	//orm.RegisterModel(&City{})
	orm.RegisterModel(new(City))

	/* 注册orm 命令
	   $ go run main.go orm
	   	orm command usage:

	   	    syncdb     - auto create tables
	   	    sqlall     - print sql of create tables
	   	    help       - print this help
	*/
	//orm.RunCommand()

	// 同步数据库
	orm.RunSyncdb("default", false, true)

	// 数据操作
	// 插入
	c := &City{
		//ID: 1, // ID 自增,不需要指定
		Name: "shanghai",
	}
	logs.Info(c)
	ormer := orm.NewOrm()
	//ormer := orm.NewOrmUsingDB("default")
	ormer.Insert(c)
	logs.Info(c) // 自动填充 id

	cs := make([]*City, 5, 5)
	for i := 0; i < 5; i++ {
		cs[i] = &City{Name: fmt.Sprintf("c_%d", i)}
	}
	ormer.InsertMulti(2, cs)

	// 查询
	cr := &City{ID: 1}
	err := ormer.Read(cr)
	if err != nil {
		logs.Info(err)
	}
	logs.Info(cr)

	cr = &City{Name: "shanghai"}
	err = ormer.Read(cr, "Name")
	if err != nil {
		logs.Info(err)
	}
	logs.Info(cr)

	// 读,不存在创建
	logs.Info(ormer.ReadOrCreate(cr, "Name"))

	// 查询所有
	//ormer.QueryTable("city")
	queryset := ormer.QueryTable(&City{})
	logs.Info(queryset)
	logs.Info(queryset.Count())

	var cs1 []*City
	queryset.All(&cs1)
	logs.Info(cs1)

	/*
		= exact iexact
		> gt
		< lt
		>= gte
		<= lte
		in in
		like contains startswith endswith icontains istartswith iendswith
	*/
	var cs2 []*City
	queryset.Filter("name", "shanghai").All(&cs2)
	logs.Info("cs2", cs2)
	var cs3 []*City
	queryset.Filter("id__gt", 5).All(&cs3)
	logs.Info("cs3", cs3)

	logs.Info(queryset.Filter("id__in", []int{1, 2, 3}).Count())
	logs.Info(queryset.Filter("id__gt", 5).Filter("id__lt", 8).Count())

	// 排查
	logs.Info(queryset.Exclude("id__gt", 20).Count())

	// 分页
	var cs4 []*City
	logs.Info(queryset.Filter("id__gt", 20).Limit(10).Offset(10).All(&cs4))
	logs.Info("cs4", cs4)

	//queryset.OrderBy("Name", "ID") // asc
	//queryset.OrderBy("-Name") // desc
	//queryset.One(&c)

	// 复杂查询
	//cond := orm.NewCondition()
	//condor := cond.Or("id__gt", 20).Or("id__lt", 20)
	//cond := cond.And("name__contains", "hai").AndCond(condor)
	//queryset.SetCond(cond)

	// 批量更新
	//queryset.Update(orm.Params{"name": "shanghai"})
	//queryset.Update(orm.Params{"name": "shanghai", "id": orm.ColValue(orm.ColAdd, 1)})

	//// 更新
	//cr.Name = "muodu"
	//ormer.Update(cr)
	//ormer.Update(cr, "Name")
	//
	//// 删除
	//ormer.Delete(&City{ID: 2})
	// 批量删除
	//queryset.Filter("id__gt", 20).Delete()

	// 原始 SQL
	// 原始的db
	//db, err := orm.GetDB("default")
	//db.Ping()
	//db.Exec()
	//db.Query()
	//db.QueryRow()

	//rawseter := ormer.Raw("update/create/delete")
	//rawseter.Exec()

	//rawseter := ormer.Raw("select * from city")
	//var c5 []*City
	//rawseter.QueryRows(&c5)

	//rawseter := ormer.Raw("select name, count(1) from city group by name")
	//var result []orm.Params
	//rawseter.Values(&result)
	//logs.Info(result)
	//
	//var resultList []orm.ParamsList
	//rawseter.ValuesList(&resultList)
	//logs.Info(resultList)

	// 事务
	//ormer.Begin()
	//...
}

常用命令:

# 同步表结构,仅对第一次创建、添加字段/索引生效,修改字段不会生效
go run main.go orm sqlall

表字段

type Post struct {
    // 忽略 struct 中的字段
    AnyField string `orm:"-"`

    // 当 Field 类型为 int, int32, int64, uint, uint32, uint64 时,可以设置字段为自增健
    ID    int    `orm:"auto;colume(id)"`

    // 数据库表默认为 NOT NULL,设置 null 代表 ALLOW NULL
    Name string `orm:"null"`

    // 为单个字段增加索引
    Name string  `orm:"index"`

    // 为单个字段增加 unique 键
    Name string `orm:"unique"`

    // 为字段设置 db 字段的名称
    Name string `orm:"column(user_name)"`

    // string 类型字段默认为 varchar(255),设置 size 以后,db type 将使用 varchar(size)
    Title string `orm:"size(60)"`

    // 默认值
    Status int `orm:"default(1)"`

    // 外键
    User  *User  `orm:"rel(fk)"`

    // 设置 float32, float64 类型的浮点精度
    Money float64 `orm:"digits(12);decimals(4)"`

    // 设置为 datetime 时,time.Time 字段的对应 db 类型使用 datetime
    Created time.Time `orm:"auto_now_add;type(datetime)"`
    // 设置为 date 时,time.Time 字段的对应 db 类型使用 date
    // Created time.Time `orm:"auto_now_add;type(date)"`
    Updated time.Time `orm:"auto_now;type(datetime)"`

    // 为字段添加注释
    Status int `orm:"default(1);description(这是状态字段)"`

    // 为datetime字段设置精度值位数,不同DB支持最大精度值位数也不一致
    Created time.Time `orm:"type(datetime);precision(4)"`
}

// 多字段索引
func (u *User) TableIndex() [][]string {
    return [][]string{
        []string{"Id", "Name"},
    }
}

// 多字段唯一键
func (u *User) TableUnique() [][]string {
    return [][]string{
        []string{"Name", "Email"},
    }
}

func (u *User) TableEngine() string {
    return "innodb"
}

表关系

rel / reverse

  • RelOneToOne:
type User struct {
   ...
   Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
   ...
}
  • 对应的反向关系 RelReverseOne:
type Profile struct {
   ...
   User *User `orm:"reverse(one)"`
   ...
}

说明:

  • 查询管理数据,需要使用 orm.NewOrm().LoadRelated(user, "Profile")

外键

  • RelForeignKey
type Post struct {
   ...
   User *User `orm:"rel(fk)"` // RelForeignKey relation
   ...
}
  • 对应的反向关系 RelReverseMany
type User struct {
   ...
   Posts []*Post `orm:"reverse(many)"` // fk 的反向关系
   ...
}

说明:

  • 查询管理数据,需要使用 queryset.RelatedSel()

多对多

  • RelManyToMany
type Post struct {
   ...
   Tags []*Tag `orm:"rel(m2m)"` // ManyToMany relation
   ...
}
  • 对应的反向关系 RelReverseMany
type Tag struct {
   ...
   Posts []*Post `orm:"reverse(many)"`
   ...
}

rel_table / rel_through

此设置针对 orm:"rel(m2m)" 的关系字段

  • rel_table 设置自动生成的 m2m 关系表的名称,当设置 rel_table 时会忽略 rel_through
  • rel_through 如果要在 m2m 关系中使用自定义的 m2m 关系表,通过这个设置其名称,格式为 pkg.path.ModelName,eg: app.models.PostTagRel,PostTagRel 表需要有到 Post 和 Tag 的关系

设置方法:

orm:"rel(m2m);rel_table(the_table_name)"
orm:"rel(m2m);rel_through(pkg.path.ModelName)"

on_delete

设置对应的 rel 关系删除时,如何处理关系字段。

  • cascade 级联删除(默认值)
  • set_null 设置为 NULL,需要设置 null = true
  • set_default 设置为默认值,需要设置 default 值
  • do_nothing 什么也不做,忽略
// 删除 Profile 时将设置 User.Profile 的数据库字段为 NULL
type User struct {
   ...
   Profile *Profile `orm:"null;rel(one);on_delete(set_null)"`
   ...
}

type Profile struct {
   ...
   User *User `orm:"reverse(one)"`
   ...
}

复杂查询

cond := orm.NewCondition()
cond = cond.Add("deleted_at__isnull", true)
qcond:=orm.NewCondition()
qcond = qcond.Or("key__icontains", q)
qcond = qcond.Or("host__name__icontains", q)
cond = cond.AddCond(qcond)
queryset.RelatedSel().SetCond(cond).All(&objects)
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数