go语言web开发18 - beego框架之go orm使用03 - orm模型定义、自动建表与基本的增删改查操作

一、结构体定义与注册模型

1.1、说明

本次定义了四个orm模型,四个模型的对应关系为:

  • 作者模型(Author):
  • 作者信息模型(AuthorInfo):AuthorInfo和Author表之间是一对一的关系(一个作者有一个单独的作者信息)
  • 文章模型(Article):Author和Article表之间是一对多的关系(一个作者可以发表多篇文章)
  • 标签模型(Tags):Article和Tags表之间是多对多的关系(一篇文章可以对应多个标签,一个标签也可以对应多篇文章)

说明:后面的所有orm增删改查实验操作都是基于本次定义的模型操作的,定义模型与建表方法如下:

 

1.2、模型定义

(1)作者模型(Author)与作者信息模型(AuthorInfo):

package models

// 1.定义结构体并使用struct tag定义表关系
type Author struct {
    Id int32 `orm:"column(id);pk;auto;description(ID)"`
    AuthorName string `orm:"size(36);column(author_name);description(作者名称)"`
    Age int32 `orm:"column(age);description(作者年龄)"`
    Gender string `orm:"column(gender);size(12);description(性别)"`
    // 一对一关联字段(不会在该表里创建外键关联,主要用于orm反查询),关键字:“reverse(one)”
    AuthorInfo *AuthorInfo `orm:"reverse(one)"`
    // 一对多关联字段(不会在该表里创建外键关联,主要用于orm反查询),关键字:“reverse(many)”,因为是一对多,所以该字段的类型是切片
    Article []*Article `orm:"reverse(many)"`
}

// 1.定义结构体并使用struct tag定义表关系
type AuthorInfo struct {
    Id int32 `orm:"column(id);pk;auto;description(ID)"`
    Phone string `orm:"column(Phone); size(11);description(电话号码)"`
    ProvinceCity string `orm:"size(128);column(province_city);description(省·市)"`
    Addr string `orm:"column(addr);size(128);description(住址)"`
    // 定义一对一关联外键(会在该表里创建外键关联),关键字:“rel(one)”
    Author *Author `orm:"column(author_id);rel(one);description(一对一外键)"`
}


// 2.自定义模型对应的表名
func (u *Author) TableName() string {
    return "author"
}
func (u *AuthorInfo) TableName() string {
    return "author_info"
}

// 3.注册模型
func init() {
    orm.RegisterModel(new(Author),new(AuthorInfo))
}

 

(2)文章模型(Article)定义

package models

import (
    "time"
)

// 1.定义结构体并使用struct tag定义表关系
type Article struct {
    Id int32 `orm:"column(id);pk;auto;description(ID)"`
    ArticleTitle string `orm:"column(article_title);size(64);description(文章标题)"`
    Desc string    `orm:"column(desc);size(256);description(文章描述)"`
    CreateTime time.Time `orm:"auto_now;type(date);column(create_time);description(文章发布时间)"`
    // 一对多外键关联(会在该表里创建一对多外键关联字段),关键字:“rel(fk)”
    Author *Author `orm:"column(article_id);rel(fk);description(一对多外键)"`
    // 多对多外键关联(会单独创建一个表记录多对多的关联信息),关键字1:“rel(m2m):指定多对多外键关联”,关键字2:“rel_table(test_article_test_tags):指定多对多关联表的名字”
    // 由于是多对多,所以该字段是切片类型
    Tags []*Tags `orm:"rel(m2m);rel_table(article_tags)"`
}


// 2.自定义模型对应的表明
func (u *Article) TableName() string {
    return "article"
}

// 3.注册模型
func init() {
    orm.RegisterModel(new(Article))
}

 

(3)标签模型Tags定义:

package models

import (
    "time"
)

// 1.定义结构体并使用struct tag定义表关系
type Tags struct {
    Id int32 `orm:"column(id);pk;auto;description(ID)"`
    TagName string `orm:"column(tag_name);size(32);description(标签名)"`
    TagDesc string `orm:"column(tag_desc);size(128);description(标签描述)"`
    CreateTime time.Time `orm:"auto_now;type(date);column(create_time);description(标签创建时间)"`
    // 多对多反向查询使用字段(不会在该表里建外键关联),关键字:reverse(many),由于是多对多,所以该字段是切片类型
    Article []*Article `orm:"reverse(many)"`
}

// 2.自定义模型对应的表明
func (u *Tags) TableName() string {
    return "tags"
}

// 3.注册模型
func init() {
    orm.RegisterModel(new(Tags))
}

 

二、连接数据库与建表

(1)在conf目录下创建database.conf文件,添加内容如下:

username = root
userpwd = 1q2w3e$R
dbhost = localhost
dbport = 3306
dbname = test_beego_orm

 

(2)在app.conf里引用database.conf文件,内容如下

appname = beego_orm_test
httpport = 8080
runmode = dev

include "database.conf"        // 引用database.conf文件

 

(3)在main.go文件里处理化连接数据库的字符串

package main

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



func init() {
    // 在配置文件读取数据库连接配置
    username := beego.AppConfig.String("username")
    userpwd := beego.AppConfig.String("userpwd")
    dbhost := beego.AppConfig.String("dbhost")
    dbport := beego.AppConfig.String("dbport")
    dbname := beego.AppConfig.String("dbname")

    // 拼接数据库连接串    
    db_data_source := username + ":" + userpwd + "@tcp(" + dbhost + ":" + dbport + ")/" + dbname + "?charset=utf8"

    // 注册数据库驱动(这里需要导入github.com/go-sql-driver/mysql包,否则编译会报错)
    orm.RegisterDriver("mysql", orm.DRMySQL)

    // 注册数据(参数前一篇文章里有说明)
    orm.RegisterDataBase("default", "mysql", db_data_source, 30)

}

func main() {
    // 命令行支持orm命令的参数
    orm.RunCommand()

    beego.Run()
}

 

(4)命令行将orm模型实现自动建表

E:\Scripts\go\src\beego_dev\beego_orm_test>go run main.go orm syncdb -v
create table `article`
    -- --------------------------------------------------
    --  Table Structure for `beego_orm_test/models.Article`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `article` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT 'ID',
        `article_title` varchar(64) NOT NULL DEFAULT ''  COMMENT '文章标题',
        `desc` varchar(256) NOT NULL DEFAULT ''  COMMENT '文章描述',
        `create_time` date NOT NULL COMMENT '文章发布时间',
        `article_id` integer NOT NULL COMMENT '一对多外键'
    ) ENGINE=InnoDB;

create table `author`
    -- --------------------------------------------------
    --  Table Structure for `beego_orm_test/models.Author`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `author` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT 'ID',
        `author_name` varchar(36) NOT NULL DEFAULT ''  COMMENT '作者名称',
        `age` integer NOT NULL DEFAULT 0  COMMENT '作者年龄',
        `gender` varchar(12) NOT NULL DEFAULT ''  COMMENT '性别'
    ) ENGINE=InnoDB;

create table `author_info`
    -- --------------------------------------------------
    --  Table Structure for `beego_orm_test/models.AuthorInfo`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `author_info` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT 'ID',
        `Phone` varchar(11) NOT NULL DEFAULT ''  COMMENT '电话号码',
        `province_city` varchar(128) NOT NULL DEFAULT ''  COMMENT '省·市',
        `addr` varchar(128) NOT NULL DEFAULT ''  COMMENT '住址',
        `author_id` integer NOT NULL UNIQUE COMMENT '一对一外键'
    ) ENGINE=InnoDB;

create table `tags`
    -- --------------------------------------------------
    --  Table Structure for `beego_orm_test/models.Tags`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `tags` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT 'ID',
        `tag_name` varchar(32) NOT NULL DEFAULT ''  COMMENT '标签名',
        `tag_desc` varchar(128) NOT NULL DEFAULT ''  COMMENT '标签描述',
        `create_time` date NOT NULL COMMENT '标签创建时间'
    ) ENGINE=InnoDB;

create table `article_tags`
    -- --------------------------------------------------
    --  Table Structure for `beego_orm_test/models.ArticleTagss`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `article_tags` (
        `id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `article_id` integer NOT NULL,
        `tags_id` integer NOT NULL
    ) ENGINE=InnoDB;

 

(5)查看建好的表

 

 

 

三、基本增删改查操作

基本增删改查操作都是基于作者表操作的。

3.1、往表里插入数据

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")

    // 插入单条数据
    author := models.Author{AuthorName: "金庸新著", Age: 55, Gender: ""}
    o.Insert(&author)     // 插入一条数据,有两个返回值:插入数据的id和错误

    // 插入多条数据
    authors := []models.Author{{AuthorName: "天蚕土豆", Age: 55, Gender: ""},{AuthorName: "金庸巨著", Age: 50, Gender: "不详"}}
    // 插入多条数据需要传两个参数:最多插入多少条数据和要插入的数据
    // 有两个返回值,一个是共插入了多少条数据,另一个是错误
    o.InsertMulti(100,&authors)


    c.TplName = "basic_operation.html"
}

 

插入后查看数据

 

 

 

3.2、查询数据

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")


    // 查询数据
    // 默认:根据ID查询(指定不指定字段都可以查询)
    author1 := models.Author{Id: 2}
    o.Read(&author1)
    fmt.Println(author1)

    // 根据其他字段查询(根据其他字段查询时需要指定查询的字段)
    author2 := models.Author{AuthorName: "金庸巨著", Gender: "不详"}
    o.Read(&author2, "AuthorName", "Gender")
    fmt.Println(author2)



    c.TplName = "basic_operation.html"
}

查看结果

 

 

 

3.3、查询,如果没有该条数据就创建该数据

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")

    // 查询不到则创建数据
    author3 := models.Author{AuthorName: "金庸再著",Age:56 ,Gender: "不详"}
    // 三个返回值:
    // 第一个返回值:是不是新创建的
    // 第二个返回值:新创建的ID
    // 第三个返回值:错误
    is_new, id, err := o.ReadOrCreate(&author3, "AuthorName", "Age", "Gender")
    if err != nil {
        fmt.Println("ReadOrCreate failed, err:", err)
    }
    if is_new {
        fmt.Println("ReadOrCreate Create_Id:", id)
    } else {
        fmt.Println("ReadOrCreate Read_Result:", author3)
    }


    c.TplName = "basic_operation.html"
}

查看执行结果:

 

 

 

 

 

 

3.4、更新数据

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")



    // 更新数据(先查询数据,然后再更新)
    author4 := models.Author{AuthorName: "金庸再著",Age:56 ,Gender: "不详"}
    err := o.Read(&author4, "AuthorName", "Age", "Gender")
    if err == nil {
        author4.AuthorName = "金庸再著"
        author4.Age = 57
        author4.Gender = ""
        // 将更新后的值更新到数据库(更新到数据库时需要指定字段,指定的字段才会更新到数据库(一个字段都没指定即模型里更改的值全部更新到数据库,至指定了某个字段时更新指定的字段)),返回值是更新的数据条数和错误
        num, err1 := o.Update(&author4, "AuthorName", "Age", "Gender")
        if err != nil {
            fmt.Println("update failed, err:", err1)
        }
        fmt.Println(num)
    }


    c.TplName = "basic_operation.html"
}

 

查看执行后的结果

 

 

3.5、删除数据

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")



    // 删除数据
    author4 := models.Author{AuthorName: "金庸再著",Age:57 ,Gender: ""}
    // 先查询(根据指定的字段查询),如果库里有这条数据就给删除了,有两个返回值,一个是删除了多少行数据,另一个是错误信息
    num, err := o.Delete(&author4, "AuthorName", "Age", "Gender") 
    if err != nil {
        fmt.Println("delete data failed, err:", err)
    }
    fmt.Println(num)

    c.TplName = "basic_operation.html"
}

查看执行结果:

 

 

3.6、新增或更新

如果数据存在就更新,如果不存在就新增数据:

func (c *BasicController) Get() {
    // 开启sql打印
    orm.Debug = true

    // 实例化orm对象与使用数据库
    o := orm.NewOrm()
    o.Using("default")



    // 新增或更新数据:如果数据存在就更新,如果没有数据则新增数据
    author5 := models.Author{AuthorName: "金庸再著",Age:57 ,Gender: ""}
    id, err := o.InsertOrUpdate(&author5, "AuthorName", "Age", "Gender")
    if err != nil {
        fmt.Println("InsertOrUpdate failed, err:", err)
    }
    fmt.Printf("InsertOrUpdate Success, Id: %d\n", id)


    c.TplName = "basic_operation.html"
}

查看执行结果

 

 

至此orm操作数据库的基本增删改查就完成了,下一篇介绍加条件的增删改查操作数据库。

 

posted @ 2020-09-22 17:57  欧-阳  阅读(829)  评论(0)    收藏  举报