0 前言
这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
第五次青训营的大项目是编写一个简易版的抖音后端,这肯定是需要与后端数据库进行打交道的,因而如何高效的访问数据库就成了重中之重。
最开始其实是打算采用SQL拼接的方式直接在代码中编写SQL语句进行对数据库的CRUD,但是后来了解到简单粗暴的进行SQL拼接的方式不仅存在很大的安全隐患(如SQL注入),而且效率也比较低,大量的SQL语句的拼接会让人烦躁。于是在了解到GORM的存在后我决定先进行GORM的学习。
以下是我的 一些学习心得。
1 数据库的连接
最基本的数据库的连接方式:
dsn := "root:123456@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
直接在一条语句中写清楚用户名、密码等内容,当然也可以用像下面这样的方式:
type mysqlConn struct {
user string
pwd string
address string
port string
dbname string
}
//根据内容生成对应的dsn
func (c *mysqlConn) GetDSN() string {
return fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True",
c.user, c.pwd, c.address, c.port, c.dbname)
}
func main(){
dsn := (&mysqlConn{
user: "root",
pwd: "123456",
address: "127.0.0.1",
port: "3306"
dbname: "dbname",
}).GetDSN()
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
}
实际上就是再把连接的数据封装了一下,使用的时候直接修改对应的字段,至少看起来会清晰一些,如果生成的dsn中需要更多的参数,可以自行修改mysqlConn结构体和GetDSN函数,在这里我使用的是MySQL的连接方式,不同的数据库的连接过程可能会有较大的差异,需要查询对应的文档根据具体情况来使用。
2 利用GORM建表
这是我比较喜欢GORM的地方之一,利用GORM的Migrate函数可以很方便的建立数据表,免去了写SQL的麻烦,用起来十分快捷高效 以下是一个利用GORM建表的例子:
//这是GORM中提供的一个结构体,利用GORM进行数据的操作时还可以顺便维护对应的时间项,很方便
type Model struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt DeletedAt `gorm:"index"`
}
//首先根据我们要建立的表的内容写好我们的结构体
type Account struct {
gorm.Model
Username string `gorm:"unique"`
Password string `gorm:"check: length(password) > 4"`
}
func CreateTable(){
dsn := "root:123456@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic(err)
}
//AutoMigrate会自动根据约定生成对应的accounts表
db.AutoMigrate(&Account{})
}
通过Navicat我们可以清晰的看到生成的表的结构:
需要注意的是:golang中用属性名称的首字母大小写区分公私有属性,如果属性字段的首字母为大写,即表明该属性为公有属性,反之则为私有属性;在我们用结构体构造数据表的时候,只有公有属性才会作为表项中属性,例如如果Account结构体中的Password写成了password,则生成的表中将不会含有password属性
另外,在结构体中还可以使用gorm中提供的标签功能,实现sql中的一些约束条件,如我在Username字段中增加了unique的tag,则在生成的表中Username字段会有unique约束,另外我们还可以通过check进行一些约束,例如我在上面通过SQL中的length()函数对Password的长度进行了一些限制