• Go项目中beego的orm使用和gorm的使用


      按照beego官方文档练习ORM的使用,model创建完始终没找到办法创建表,于是使用gorm翻译文档官方文档进行了练习,使用起来还是比较简单。

      安装:

      方法一:Terminal打开,go get -u github.com/jinzhu/gorm

      方法二:复制地址https://github.com/jinzhu/gorm,到GoLand直接会提示是否将gorm添加到GOPATH,确认添加会自动下载

      建model,models.go内容如下:

    package models
    
    import (
    	"github.com/jinzhu/gorm"
    )
    
    type User struct {
    	gorm.Model
    	Name    string
    	Profile Profile `gorm:"ForeignKey:UserRefer"` // 一个User包含一个Profile
    	Post    []Post                                // 一个User包含多个Post UserID为外键
    }
    
    type Profile struct {
    	gorm.Model
    	Age       int16
    	UserRefer uint
    }
    
    type Post struct {
    	gorm.Model
    	Title  string
    	UserID uint
    	Tag    []*Tag `gorm:"many2many:post_tag;"`
    }
    
    type Tag struct {
    	gorm.Model
    	Name  string
    	Posts []*Post `gorm:"many2many:post_tag;"`
    }
    

      连接数据库,main.go部分内容:

    package main
    
    import (
    	"fmt"
    	"github.com/jinzhu/gorm"
    	_ "github.com/jinzhu/gorm/dialects/mysql"
    	"myproject/models"
    	_ "myproject/routers"
    )
    
    var db *gorm.DB
    
    func main() {
    	// 连接数据库
    	var err error
    	db, err = gorm.Open("mysql", "root:nola123456@/default?charset=utf8&parseTime=True&loc=Local")
    	if err != nil {
    		panic(err)
    	}
    	defer db.Close()
            ...      
    }
    

      创建表,main.go部分内容:

      gorm文档给出自动迁移模式,警告:自动迁移仅仅会创建表,缺少列和索引,并且不会改变现有列的类型或删除未使用的列以保护数据。

    db.AutoMigrate(&models.User{}, &models.Profile{}, &models.Post{}, &models.Tag{})
    

      使用如下方式创建表(代码有点繁琐,还在探索中):

    func main() {
            ...
    	// 创建表User
    	if !db.HasTable(&models.User{}) {
    		if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.User{}).Error; err != nil {
    			panic(err)
    		}
    	}
    
    	// 创建表Profile
    	if !db.HasTable(&models.Profile{}) {
    		if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Profile{}).Error; err != nil {
    			panic(err)
    		}
    	}
    
    	// 创建表Post
    	if !db.HasTable(&models.Post{}) {
    		if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Post{}).Error; err != nil {
    			panic(err)
    		}
    	}
    
    	// 创建表Tag
    	if !db.HasTable(&models.Tag{}) {
    		if err := db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&models.Tag{}).Error; err != nil {
    			panic(err)
    		}
    	}
            ...
    }
    

      运行main.go,数据库表创建完毕:

        

      CRUD,main.go插入部分:

    func main() {
            ...
    	// 插入
    	profile := models.Profile{Age: 30}
    	profile1 := models.Profile{Age: 25}
    	db.Create(&profile)
    	db.Create(&profile1)
    	fmt.Println(profile)
    	fmt.Println(profile1)
    	db.Create(&models.User{Profile: profile, Name: "silence"})
    	db.Create(&models.User{Profile: profile1, Name: "silence 2"})
    	db.Create(&models.User{Profile: profile, Name: "nola"})
    	db.Create(&models.User{Profile: profile1, Name: "alice"})
            ...
    }

      CRUD,main.go查询部分:

    func main() {
           ...
    	//查询
    	var count int
    	db.First(&models.User{})                                  // 第一条记录
    	db.Last(&models.User{})                                 // 最后一条记录
    	db.Find(&models.User{})                                 // 所有记录
    	db.First(&models.User{}, 1)                             // 使用主键获取记录
    	db.Where("name = ?", "nola").First(&models.User{})      // where条件查询第一个匹配记录
    	db.Where("name = ?", "nola").Find(&models.User{})        // where条件查询所有匹配记录
    	db.Where("name <> ?", "nola").Find(&models.User{})        // where条件查询name不为nola的所有user
    	db.Where("name in (?)", []string{"silence", "silence 2"}) // in
    	db.Where("name LIKE ?", "%sil%").Find(&models.User{})    // LIKE
    	db.Select([]string{"user_refer", "age"}).Find(&models.Profile{}) // 指定检索字段
    	db.Select("name").Find(&models.User{})                          // 指定检索字段
    	db.Order("name desc").Find(&models.User{})                      // 排序
    	db.Limit(3).Find(&models.User{})                                 // limit
    	counts := db.Where("name = ?", "rose").Find(&models.User{}).Count(&count)  // count
    	fmt.Println(counts)
            ...
    }

      CRUD,main.go更新部分:

    func main() {
            ...
    	// 更新
    	db.Table("users").Where("id in (?)", []int{30, 34}).Update(map[string]interface{}{"name":"hello"})  // 批量更新
    	affected_nums := db.Model(&models.User{}).Where("name = ?", "jack").Update(models.User{Name:"jim"}).RowsAffected  // 返回影响行数
    	fmt.Println(affected_nums)
            ...
    }

      CRUD,main.go删除部分:

    func main() {
            ...
    	// 删除
    	db.Where("name LIKE ?", "%len%").Delete(models.User{})
    	db.Delete(models.Profile{}, "age = ?", "30")  // model存在deleted_at字段为软删除 记录删除时间
    	fmt.Println(db.Where("age = ?", "30").Find(&models.Profile{}).Value)  // 软删除的记录查询被忽略
    	fmt.Println(db.Unscoped().Where("age = ?", "30").Find(&models.Profile{}).Value)  // 查询软删除的记录
    	db.Unscoped().Delete(models.Profile{}, "age = ?", "30")  // 永久删除记录
    }
    

      

      习惯Django那种建好model进行迁移,也有一些人习惯利用sql语句去生成models.go文件,个人感觉很别扭。gorm使用起来很舒服,它还有很多高级用法,值得慢慢研究。。。


      着实不甘心,beego的orm连注册model都有,怎能没有创建同步表呢?参考csdn上一篇文章,再试一下:

      创建项目:cd src工作间 - bee new useBeegoORM创建项目

      useBeegoORM/models/models.go内容如下:

    package models
    
    type User struct {
    	Id      int
    	Name    string
    	Profile *Profile `orm:"rel(one)"`     // 一对一关系
    	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)"`
    }
    

      useBeegoORM/main.go内容如下:

    package main
    
    import (
    	_ "github.com/Go-SQL-Driver/MySQL" // 引入driver
    	"github.com/astaxie/beego"
    	"github.com/astaxie/beego/orm"
    
    	"useBeegoORM/models"  // 引入model
    	_ "useBeegoORM/routers"
    )
    
    func init() {
    	// 注册driver
    	orm.RegisterDriver("mysql", orm.DRMySQL)
    
    	// 需要在init中注册定义的model
    	orm.RegisterModel(new(models.User), new(models.Profile), new(models.Post), new(models.Tag))
    
    	// 注册数据库 ORM必须注册一个别名为default的数据库作为默认使用
    	orm.RegisterDataBase("default", "mysql", "root:nola123456@/orm_test?charset=utf8")
    
    	// 自动创建表 参数二开启创建表 参数三开启更新表【此句重点】
    	orm.RunSyncdb("default", true, true)
    }
    
    func main() {
    	beego.Run()
    }
    

      运行会自动创建表,同步到数据库,效果如下:

     

      创建的表终于同步到数据库了~。~

      接着看看CRUD的使用:

      

    package main
    
    import (
    	_ "github.com/Go-SQL-Driver/MySQL" // 引入driver
    	//"github.com/astaxie/beego"
    	"github.com/astaxie/beego/orm"
    
    	"fmt"
    	"useBeegoORM/models" // 引入model
    	_ "useBeegoORM/routers"
    )
    
    func init() {
    	// 注册driver
    	orm.RegisterDriver("mysql", orm.DRMySQL)
    
    	// 需要在init中注册定义的model
    	orm.RegisterModel(new(models.User), new(models.Profile), new(models.Post), new(models.Tag))
    
    	// 注册数据库 ORM必须注册一个别名为default的数据库作为默认使用
    	orm.RegisterDataBase("default", "mysql", "root:nola123456@/orm_test?charset=utf8")
    
    	// 自动创建表 参数二开启创建表 参数三开启更新表【此句重点】
    	//orm.RunSyncdb("default", true, true)
    }
    
    func main() {
    	// 对象的CRUD
    	o := orm.NewOrm() // 创建一个Ormer
    	user := new(models.User)
    	profile := new(models.Profile)
    	profile.Age = 30
    	user.Name = "silence"
    	user.Profile = profile
    	fmt.Println(o.Insert(user)) // Insert
    	fmt.Println(o.Insert(profile))
    
    	user.Name = "Your"
    	fmt.Println(o.Update(user)) // Update
    	fmt.Println(o.Read(user))   // Read
    	fmt.Println(o.Delete(user)) // Delete
    	//beego.Run()
    }
    

      查看数据:

      可增减数据,第2步submit,相应的会打印console。

      ORM的操作还需慢慢研究。有关GoLand配置数据库以及配置远程host,用过jetbrains公司的产品如PyCharm等,配置风格都类似。

      明天有时间写个详细步骤留存,供大家参考~

  • 相关阅读:
    Shell基础:什么是shell脚本、2种脚本解释器、#!约定解释器类型、运行shell脚本的2种方式、shell变量命令规范/赋值/如何使用/只读变量/删除变量/变量类型、shell字符串及其常用方法、shell数组及其常用方法、shell注释
    Linux su命令:su命令语法、su root与su
    docker容器内使用apt报错E: List directory /var/lib/apt/lists/partial is missing.
    浅析事务是什么、mysql是如何实现事务提交和回滚的、保证事务持久性redo log的实现原理、保证事务一致性undo log的实现原理、事务ACID特性及其实现原理
    浅析前后端分离架构下的API安全问题:JWT保证token不被盗用的方案(即如何防范Replay Attacks)
    浅析如何保证缓存与数据库的双写一致性:4种更新缓存的设计模式理解
    浅析SpringCloud中断路器是什么、断路器的作用以及在Feign中使用断路器
    浅析后端微服务涉及到定时任务时如何解决多集群定时任务重复执行并发的方案对比
    Linux连续执行多条命令的写法区别
    Dockerfile中RUN/CMD/ENTRYPOINT命令区别
  • 原文地址:https://www.cnblogs.com/NolaLi/p/10724741.html
Copyright © 2020-2023  润新知