前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go实战项目-Beego的orm的基本使用

Go实战项目-Beego的orm的基本使用

作者头像
用户6680840
发布2022-06-08 10:45:59
1.2K0
发布2022-06-08 10:45:59
举报
文章被收录于专栏:菜鸟程序员的自我修养

beego的使用三部曲: 1、在controllers里面创建控制器 2、在module里面创建数据模型 3、在router设置路由控制 对于beego的orm使用有很多种方式,我们主要采用过滤器的方式来实现。因为前面说过,严禁使用原生的sql语句。

单表查询

依然三部曲: 1、创建模型 2、注册模型 3、使用模型获取数据

代码语言:javascript
复制
//注意表和列的命名规则
type CLogin struct {
    Id             int       `orm:"column(id)" json:"id"`
    LoginId        string    `orm:"column(LoginId)" json:"LoginId"`
    Pwd            string    `orm:"column(Pwd)" json:"Pwd"`
    FullName       string    `orm:"column(FullName)" json:"FullName"`
    DepartmentId   int       `orm:"column(DepartmentId)" json:"DepartmentId"`
    DepartmentName string    `orm:"column(DepartmentName)" json:"DepartmentName"`
    RoleId         int       `orm:"column(role_id)" json:"role_id"`
    Deleted        int       `orm:"column(deleted)" json:"deleted"`
    Telephone      string    `orm:"column(telephone)" json:"telephone"`
    IdCard         string    `orm:"column(id_card)" json:"id_card"`
    JobCard        string    `orm:"column(job_card)" json:"job_card"`
    EnterpriseId   int64     `orm:"column(enterpriseId)" json:"enterpriseId"`
    UpdateTime     time.Time `orm:"type(datetime);column(update_time)" json:"update_time"` //date  这些tag可以通过反射来自己实现
    //CRole          *CRoles `orm:"rel(one)" json:"role"`
}

站在这里就有int,string,date格式的表述,其他类型,都是一次类推,特殊类型的,可以用type指定,如orm:”type(datetime);column(update_time)

单表查询的一种方式,仅仅作为演示:

代码语言:javascript
复制
    o := orm.NewOrm()
    user = CLogin{LoginId: loginId}
    err = o.Read(&user, "LoginId")
    //多条件不能这么写,这样获取不到数据
    //user = CLogin{LoginId: loginId, Pwd: md5Pwd}

注意,这种方式只能匹配第一参数,后面添加了也不会识别,不知道是不是我使用的问题还是怎么回事,咱的重点也不在这,由于此项目没有外键,无法进行模型关联查询,所以只能舍弃这种方式的研究,采用过滤器的方式。当然,还有build的方式来实现,可以参考官网自己实现。

//采用过滤器QuerySeter实现 err = o.QueryTable(“c_login”).Filter(“LoginId”,loginId).Filter(“pwd”,pwd).One(&user) 不定项条件查询:

代码语言:javascript
复制
//不定项多条件查询
querySet := o.QueryTable("c_login")
querySet = querySet.Filter("LoginId", loginId)
if pwd != "123456" {
    querySet = querySet.Filter("pwd", pwd)
}
err = querySet.One(&user)

注意,不能采用链式直连的方式,如果去掉多次赋值的话,前面的条件都不会生效,因为在他是采用值复制的方式传递的,并非采用引用传递的。

多表查询

前面有说到,建立模型可以直接正在做到关联查询,前提是必须要有外键的存在,前人制造的表结构,我们也不好意思评价,这恰恰可以给我们成长提供机会。所以,我采用的是raw,采用占位符的方式,否则就需要建立外键和对应的外键id,否则会报错提是找不到外键id。

代码语言:javascript
复制
//获取角色权限
func GetRoleSession(roleId int) ([]orm.Params, error) {
    var (
        err  error
        maps []orm.Params
    )
    o := orm.NewOrm()
    _, err = o.Raw("select p.id,p.url,p.name, p.code,1 as checked from c_role_power as r join c_power as p on r.pid = p.id where r.rid=?", roleId).Values(&maps)
    return maps, err
}

其他操作

querySeter的其他操作,可以仿照查询的条件添加方式进行操作。可以hi姐实现。比如:

代码语言:javascript
复制
//更新c_login表
func LoginUpdate(id int, pwd string) error {
    o := orm.NewOrm()
    querySetter := o.QueryTable("c_login")
    querySetter = querySetter.Filter("id", id)
    params := make(map[string]interface{})
    params["id"] = id
    params["Pwd"] = utils.Md5(pwd)
    params["update_time"] = time.Now().Format("2006-01-02 15:04:05")
    fmt.Println("params", params)
    _, err := querySetter.Update(params)
    return err
}

Update(values Params) (int64, error) Delete() (int64, error) PrepareInsert() (Inserter, error) Exist() bool :判断表书否存在,这个对于私有化部署,代码添加新表做升级处理方便直接的多。

别忘了,还有注册结构模型

代码语言:javascript
复制
    orm.RegisterModel(new(CLogin), new(CRoles))
    //orm.RegisterModelWithPrefix("c_", new(Roles))

除了直接注册表名规范之外,还有前缀的方式添加, 这样结构体的名字就不会这么的恶心了。

orm的连接池和库切换

这个多库的比较麻烦,必须要注册数据库,并且要设置别名,后续的使用也是必须使用别名来调用数据库才能生效。直接贴上工具类:

代码语言:javascript
复制
//Use "callout" db "default" as alias name if you not set.
func GetOrm(dbName ...string) (orm.Ormer, error) {
    var (
        alias      string
        tempDbName string
        err        error
    )
    if len(dbName) > 0 {
        tempDbName = dbName[0]
    } else {
        tempDbName = "callout"
    }
    o := orm.NewOrm()
    if tempDbName == "callout" {
        alias = "default"
    } else if tempDbName == "default" {
        alias = "default"
    } else if !strings.HasPrefix(tempDbName, "co") {
        alias = "co" + tempDbName
    } else {
        alias = "default"
    }

    logs.Info("alias: ", alias)
    err = o.Using(alias) //这里使用的是数据库的别名,不是直接连接数据库
    logs.Info("using alias err: ", err)
    if err != nil { //代表没有这个别名的数据库,需要注册
        registerDatabases(alias)
        err = o.Using(alias)
        logs.Info("using alias against err: ", err)
    }
    return o, err
}

//初始化设置数据库,注册一个默认的数据库,并设置最大连接数和最大空闲数
func InitBeeGoOrm() {
    defaultDB := beego.AppConfig.String("defaultDB") //app.conf文件配置
    err := orm.RegisterDriver("mysql", orm.DRMySQL)
    if err != nil {
        fmt.Println("RegisterDriver err: ", err)
    }
    // 参数1        数据库的别名,用来在 ORM 中切换数据库使用
    // 参数2        driverName
    // 参数3        对应的链接字符串
    // 参数4(可选)  设置最大空闲连接
    // 参数5(可选)  设置最大数据库连接 (go >= 1.2)
    err = orm.RegisterDataBase("default", "mysql", defaultDB, 50, 100) //暂时写死,可以写成动态的
    if err != nil {
        fmt.Println("RegisterDataBase err: ", err)
    }
}

//注册数据库
func registerDatabases(dbName string) {
    mySqlUser := beego.AppConfig.String("mySqlUser")
    mySqlPwd := beego.AppConfig.String("mySqlPwd")
    mySqlAddress := beego.AppConfig.String("mySqlAddress")
    fmt.Println("RegisterDataBase: ", mySqlUser, mySqlPwd, mySqlAddress)
    defaultDB := fmt.Sprintf("%s:%s@(%s)/%s?timeout=30s&charset=utf8mb4&collation=utf8mb4_general_ci", mySqlUser, mySqlPwd, mySqlAddress, dbName)
    fmt.Println("RegisterDataBase defaultDB: ", defaultDB)
    err := orm.RegisterDataBase(dbName, "mysql", defaultDB, 50, 100)
    if err != nil {
        fmt.Println("RegisterDataBase err: ", err)
    }
}

多库之间的别名,我采用的是数据库名作为别名,这样方便注册和使用。但是,默认的是数据库只能是default,这个有点耍流氓了。但是,不影响我们封装起来,只是一个判断的问题。后续的使用也方便,只需要把o, err = utils.GetOrm(strEnterprise)替换掉o := orm.NewOrm()就可以了直接使用了。至于池的概念,那就是使用框架自身的,在函数InitBeeGoOrm里面就有设置。空闲数和连接数,依然按照之前的方式来调试设置。

本作品采用《CC 协议》,转载必须注明作者和本文链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单表查询
  • 多表查询
  • 其他操作
  • orm的连接池和库切换
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档