Gorm连接Mysql时相关配置问题的看法

连接数据库

下面是某个博客网站使用gorm连接mysql的代码片段。

    if DB, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{Logger: newLogger}); err == nil {
        sqlDB, _ := DB.DB()
        sqlDB.SetMaxOpenConns(global.CONFIG.MySQLConfig.MaxOpenConns) // 设置数据库最大连接数
        sqlDB.SetMaxIdleConns(global.CONFIG.MySQLConfig.MaxIdleConns) // 设置上数据库最大闲置连接数
        global.DB = DB
    } else {
        panic("connect server failed")
    }

gorm.Open()需要两个参数,一个是关于mysql的相关配置,另一个是gorm的相关配置。gorm.Open()的作用就是连接数据库,初始化一些配置信息,并返回一个gorm.DB结构体,这个结构体封装了GORM框架所有的数据库操作方法。

gorm.DB这个结构体的内容如下:

type DB struct {
	*Config
	Error        error
	RowsAffected int64
	Statement    *Statement
	clone        int
}

gorm.DB这个结构体的第一个变量是一个指针,指向gorm包里面的Config结构体,这个结构体的主要作用就是可以自定义设置数据库的一些配置信息。比如关于事务、表名、外键、创建时间、预编译等配置信息可以自定义配置,如果不去配置这些信息就会使用系统默认的配置。关于这个Config结构体详见这几篇博客文章:

对代码中sqlDb, _ := DB.DB()的理解如下:DB这个结构体封装了GORM框架所有的数据库操作方法。但是为什么需要使用sqlDb对象来操作连接池呢?用DB对象不行吗?DB()方法的源代码如下所示:

// DB returns `*sql.DB`
func (db *DB) DB() (*sql.DB, error) {
	connPool := db.ConnPool

	if dbConnector, ok := connPool.(GetDBConnector); ok && dbConnector != nil {
		return dbConnector.GetDBConn()
	}

	if sqldb, ok := connPool.(*sql.DB); ok {
		return sqldb, nil
	}

	return nil, ErrInvalidDB
}

从源码中可以看到,该方法的接收者是gorm包里面的bd对象(该对象的类型就是前面讲的DB结构体类型),但返回值是sql包里面的DB类型(并不是gorm包里面的DB类型)。再来看看sql包里面的DB类型是什么样子:

type DB struct {
	// Atomic access only. At top of struct to prevent mis-alignment
	// on 32-bit platforms. Of type time.Duration.
	waitDuration int64 // Total time waited for new connections.

	connector driver.Connector
	// numClosed is an atomic counter which represents a total number of
	// closed connections. Stmt.openStmt checks it before cleaning closed
	// connections in Stmt.css.
	numClosed uint64

	mu           sync.Mutex    // protects following fields
	freeConn     []*driverConn // free connections ordered by returnedAt oldest to newest
	connRequests map[uint64]chan connRequest
	nextRequest  uint64 // Next key to use in connRequests.
	numOpen      int    // number of opened and pending open connections
	// Used to signal the need for new connections
	// a goroutine running connectionOpener() reads on this chan and
	// maybeOpenNewConnections sends on the chan (one send per needed connection)
	// It is closed during db.Close(). The close tells the connectionOpener
	// goroutine to exit.
	openerCh          chan struct{}
	closed            bool
	dep               map[finalCloser]depSet
	lastPut           map[*driverConn]string // stacktrace of last conn's put; debug only
	maxIdleCount      int                    // zero means defaultMaxIdleConns; negative means 0
	maxOpen           int                    // <= 0 means unlimited
	maxLifetime       time.Duration          // maximum amount of time a connection may be reused
	maxIdleTime       time.Duration          // maximum amount of time a connection may be idle before being closed
	cleanerCh         chan struct{}
	waitCount         int64 // Total number of connections waited for.
	maxIdleClosed     int64 // Total number of connections closed due to idle count.
	maxIdleTimeClosed int64 // Total number of connections closed due to idle time.
	maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit.

	stop func() // stop cancels the connection opener.
}

上面sql包里面的DB结构体的大致内容就是关于数据库的连接数量,连接状态和时间等信息。那么现在回到DB()方法里面。该方法的主要功能就是创建一个连接池,然后就能通过一些参数来设置连接池或者关闭连接。下面是一些网上博主的观点:

创建gorm.DB对象的时候连接并没有被创建,在具体使用的时候才会创建。gorm内部,准确的说是database/sql内部会维护一个连接池,可以通过参数设置最大空闲连接数,连接最大空闲时间等。使用者不需要管连接的创建和关闭。

以上就对gorm的连接做了一个大致的分析,由于数据库底层驱动,引擎这些底层原理还没有怎么了解过,所以上面的解释也不是很深入。

mysql.Config的各个字段

MySQL 驱动程序提供了一些配置可以在初始化过程中使用

type Config struct {
    DriverName                    string
    ServerVersion                 string
    DSN                           string
    DSNConfig                     *mysql.Config
    Conn                          gorm.ConnPool
    SkipInitializeWithVersion     bool
    DefaultStringSize             uint
    DefaultDatetimePrecision      *int
    DisableWithReturning          bool
    DisableDatetimePrecision      bool
    DontSupportRenameIndex        bool
    DontSupportRenameColumn       bool
    DontSupportForShareClause     bool
    DontSupportNullAsDefaultValue bool
    DontSupportRenameColumnUnique bool
}

DSN(数据源名称)只是连接数据库的其中一个参数,通过这一个参数就能连接数据库。像其他参数,比如

DriverName:可以自定义驱动名;

Conn:可以通过一个现有的数据库连接来初始化 *gorm.DB;

SkipInitializeWithVersion:是否根据当前 MySQL 版本自动配置

DefaultStringSize:为字符串(string)字段设置大小。默认情况下,对于没有大小、没有主键、没有定义索引且没有默认值的字段,将使用db类型“longext”

DisableDatetimePrecision:禁用日期时间精度支持。但是这在MySQL 5.6之前不支持

DefaultDatetimePrecision:默认日期时间精度。比如:DefaultDatetimePrecision:&datetimePrecision

DontSupportRenameIndex:重命名索引时删除并创建索引。但是在MySQL 5.7、MariaDB之前不支持重命名索引

DontSupportRenameColumn:重命名列时使用change。但是在MySQL 8、MariaDB之前不支持重命名

其他的字段用的非常少,当有需要的时候在去研究。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang中使用MySQL连接池与GORM ORM库可以提高性能和效率。下面是一个简单的示例代码,展示如何使用GORMMySQL连接池: ```go import ( "fmt" "log" "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { // 配置MySQL连接信息 dsn := "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local" // 使用连接池创建数据库连接 db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal(err) } // 设置连接池的最大空闲连接数和最大打开连接数 sqlDB, err := db.DB() if err != nil { log.Fatal(err) } sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) // 使用GORM进行数据库操作 // 这里可以写入你的业务逻辑 // 关闭数据库连接 err = db.Close() if err != nil { log.Fatal(err) } fmt.Println("MySQL连接池示例代码执行完毕") } ``` 在上面的示例中,我们首先配置MySQL连接信息,包括用户名、密码、主机和端口以及数据库名称。然后使用`gorm.Open`方法打开数据库连接,并通过`db.DB()`方法获取到底层的`*sql.DB`实例,以便设置连接池的最大空闲连接数和最大打开连接数。最后,我们可以使用GORM进行数据库操作。在结束,记得调用`db.Close()`关闭数据库连接。 请注意,上述示例代码中使用了`gorm.io/gorm`和`gorm.io/driver/mysql`模块,这是GORM的最新版本。在你的代码中,可能需要替换成你当前使用的GORM版本的模块路径。 希望对你有帮助!如有更多问题,请随提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值