设计模式之 Database/SQL 与 GORM 实践 | 青训营笔记

103 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记

连接数据库

dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

这两行代码即可完成数据库的连接,但是这种操作需要在每一次需要用到数据库的时候都要写上面两行代码,重新建立数据库的连接,这样增加了程序运行的时间,而且写起来比较麻烦。

为了提高数据库的连接的使用率,可以使用gorm连接池

package utils
​
//定义全局的db对象,我们执行数据库操作主要通过他实现。
var _db *gorm.DB
​
//包初始化函数,golang特性,每个包初始化的时候会自动执行init函数,这里用来初始化gorm。
func init() {
    dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    // 声明err变量,下面不能使用:=赋值运算符,否则_db变量会当成局部变量,导致外部无法访问_db变量
    var err error
    //连接MYSQL, 获得DB类型实例,用于后面的数据库读写操作。
    _db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("连接数据库失败, error=" + err.Error())
    }
    sqlDB, _ := db.DB()
    sqlDB.SetMaxOpenConns(100)   //设置数据库连接池最大连接数
    sqlDB.SetMaxIdleConns(20)   //连接池最大允许的空闲连接数,如果没有sql任务需要执行的连接数大于20,超过的连接会被连接池关闭。
}
​
//其他包可以通过这个方法使用数据库
func GetDB() *gorm.DB {
    return _db
}

使用实例:

package main
​
import utils
​
func main() {
    //获取DB
    db := tools.GetDB()
    
    //执行数据库查询操作
    u := User{}
    db.Where("username = ?", "张三").First(&u)
}

Gorm操作

gorm的一些操作可以查看gorm的官网,里面讲的比较全面

link.juejin.cn/?target=htt…

这里讲一下我在使用gorm进行关联查询时遇到的一些问题

如下有两个结构体

type Video struct {
    Id            int64  
    Author        User  
    PlayUrl       string 
    CoverUrl      string 
    FavoriteCount int64  
    CommentCount  int64  
    IsFavorite    bool   
    PublishTime   int64 
}
​
type User struct {
    Id            int64  
    Name          string
    FollowCount   int64  
    FollowerCount int64  
    IsFollow      bool  
}

Video里有一个类型是User,我使用db.AutoMigrate(&Video{})向数据库中建表发生了错误,提示没有正确外键。我在数据库中单独建立了这两张表,但是进行关联查询时也出现了错误,还是外键的问题。可是我明明已经定义了外键。

结果我才发现,Video中不能只有User这个属性,还要指定User的ID

type Video struct {
    Id            int64  
    Author        User   
    AuthorID      int64  //指定AuthorID 
    PlayUrl       string 
    CoverUrl      string 
    FavoriteCount int64  
    CommentCount  int64  
    IsFavorite    bool   
    PublishTime   int64  
}

问题得到解决