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操作数据库的基本增删改查就完成了,下一篇介绍加条件的增删改查操作数据库。