一、安装gorm
- 安装gorm
gorm.io/gorm
- 安装mysql驱动
gorm.io/driver/mysql
二、连接mysql
在bootstrap/database.go
package bootstrap
import (
"io"
"log"
"os"
"strconv"
"time"
"gin-blog/global"
"gin-blog/models"
"github.com/natefinch/lumberjack"
"go.uber.org/zap"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func InitialDatabase() *gorm.DB {
dbConfig := global.Config.Database
if dbConfig.Database == "" {
global.Log.Error("error", zap.String("database", "数据名称不能为空"))
}
dsn := dbConfig.UserName + ":" + dbConfig.Password + "@tcp(" + dbConfig.Host + ":" + strconv.Itoa(dbConfig.Port) + ")/" + dbConfig.Database + "?charset=" + dbConfig.Charset + "&parseTime=True&loc=Local"
mysqlConfig := mysql.Config{
DSN: dsn, // DSN data source name
DefaultStringSize: 190, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据版本自动配置
}
db, err := gorm.Open(mysql.New(mysqlConfig), &gorm.Config{
DisableForeignKeyConstraintWhenMigrating: true, // 禁用自动创建外键约束
Logger: getGormLoger(),
})
if err != nil {
global.Log.Error("mysql connect failed", zap.String("err", err.Error()))
return nil
}
sqlDb, _ := db.DB()
sqlDb.SetMaxIdleConns(dbConfig.MaxIdleConns)
sqlDb.SetMaxIdleConns(dbConfig.MaxOpenConns)
initMysqlTable(db)
return db
}
func getGormLoger() logger.Interface {
var logMode logger.LogLevel
switch global.Config.Database.LogMode {
case "silent":
logMode = logger.Silent
case "error":
logMode = logger.Error
case "warn":
logMode = logger.Warn
case "info":
logMode = logger.Info
default:
logMode = logger.Info
}
return logger.New(getGormLogWriter(), logger.Config{
SlowThreshold: 200 * time.Millisecond, // 慢 SQL 阈值
LogLevel: logMode, // 日志级别
IgnoreRecordNotFoundError: false, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: global.Config.Database.EnableFileLogWriter, // 禁用彩色打印
})
}
func getGormLogWriter() logger.Writer {
var writer io.Writer
if global.Config.Database.EnableFileLogWriter {
writer = &lumberjack.Logger{
Filename: global.Config.Log.RootDir + "/" + global.Config.Database.LogFilename,
MaxSize: global.Config.Log.MaxSize,
MaxBackups: global.Config.Log.MaxBackups,
MaxAge: global.Config.Log.MaxAge,
Compress: global.Config.Log.Compress,
}
} else {
writer = os.Stdout
}
return log.New(writer, "\r\n", log.LstdFlags)
}
func initMysqlTable(db *gorm.DB) {
err := db.AutoMigrate(
models.User{},
)
if err != nil {
global.Log.Error("autoMigrate table failed", zap.String("error", err.Error()))
os.Exit(0)
}
}
三、在modules目录下新建user.go
type User struct {
gorm.Model
UserName string `json:"userName" gorm:"comment:用户名;"`
Password string `json:"password" gorm:"not null;comment:密码"`
}
四、在api目录下新建user.go
package api
import (
"net/http"
"gin-blog/form"
"gin-blog/global"
"gin-blog/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type user struct {
}
var User = new(user)
func (u user) CreateUser(c *gin.Context) {
var userForm form.CreateUserReq
if err := c.ShouldBindJSON(&userForm); err != nil {
global.Log.Error("获取创建用户的参数错误", zap.String("err", err.Error()))
return
}
user, err := service.User.CreateUser(userForm)
if err != nil {
global.Log.Error("建用户错误", zap.String("err", err.Error()))
return
}
c.JSON(http.StatusOK, user)
}
五、在service新建user.go
package service
import (
"gin-blog/form"
"gin-blog/global"
"gin-blog/models"
)
type user struct {
}
var User = new(user)
func (u user) CreateUser(form form.CreateUserReq) (models.User, error) {
user := models.User{
UserName: form.UserName,
Password: form.Password,
}
err := global.DB.Create(&user).Error
return user, err
}
六、注册路由
package router
import (
"gin-blog/api"
"github.com/gin-gonic/gin"
)
func UserRoute(route *gin.RouterGroup) {
route.POST("/createUser", api.User.CreateUser)
}