/
db.go
175 lines (163 loc) · 4.53 KB
/
db.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// $
// Created by dkedTeam.
// Author: GJing
// Date: 2022/9/9$ 15:49$
package database
import (
"database/sql"
"fmt"
"github.com/gjing1st/hertz-admin/internal/apiserver/store/database/initdata"
"github.com/gjing1st/hertz-admin/internal/pkg/config"
log "github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/plugin/dbresolver"
log1 "log"
"os"
"time"
)
var (
db *gorm.DB
)
const (
DriverPostgresql = "postgresql"
DriverMysql = "mysql"
DriverMongo = "mongodb"
)
// InitDB
//
// @description: 初始化数据库
// @param:
// @author: GJing
// @email: gjing1st@gmail.com
// @date: 2022/4/6 22:37
// @success:
func InitDB() {
var err error
var dsn = MysqlEmptyDsn()
createSql := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;", config.Config.Mysql.DBName)
// 创建数据库
if err = createDatabase(dsn, "mysql", createSql); err != nil {
log.WithFields(log.Fields{"err": err.Error()}).Panic(DriverMysql + "数据库创建失败")
return
}
//数据库驱动
dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
config.Config.Mysql.UserName,
config.Config.Mysql.Password,
config.Config.Mysql.Host,
config.Config.Mysql.Port,
config.Config.Mysql.DBName,
)
newLogger := logger.New(
log1.New(os.Stdout, "\r\n", log1.LstdFlags), // io writer(日志输出的目标,前缀和日志包含的内容)
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Error, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误
Colorful: false, // 禁用彩色打印
},
)
fmt.Println("========dsn", dsn)
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger, //日志
DisableForeignKeyConstraintWhenMigrating: true, //外键
PrepareStmt: true, //预编译缓存
})
if err != nil {
log.WithFields(log.Fields{"err": err.Error()}).Panic(DriverMysql + "数据库连接失败")
return
}
// 读写分离
slaveDsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
config.Config.Slave.UserName,
config.Config.Slave.Password,
config.Config.Slave.Host,
config.Config.Slave.Port,
config.Config.Slave.DBName,
)
err = db.Use(
dbresolver.Register(dbresolver.Config{
Replicas: []gorm.Dialector{mysql.Open(slaveDsn)},
}).
//设置从库连接池
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(time.Hour).
SetMaxIdleConns(config.Config.Mysql.MinConns).
SetMaxOpenConns(config.Config.Mysql.MaxConns),
)
if err != nil {
log.WithFields(log.Fields{"err": err.Error()}).Error(DriverMysql + "配置数据库读写分离失败")
return
}
// 获取通用数据库对象 sql.DB ,然后使用其提供的功能
sqlDB, err := db.DB()
if err != nil {
log.WithFields(log.Fields{"err": err.Error()}).Panic(DriverMysql + "数据库连接失败")
return
}
// SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。
sqlDB.SetMaxIdleConns(config.Config.Mysql.MinConns)
// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(config.Config.Mysql.MaxConns)
// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
log.Info("init db success")
}
// GetDB
//
// @description: 获取数据库连接
// @param:
// @author: GJing
// @email: gjing1st@gmail.com
// @date: 2022/4/6 22:38
// @success:
func GetDB() *gorm.DB {
if db == nil {
InitDB()
}
// 初始化表和表数据
initdata.InitData(db)
return db
}
// MysqlEmptyDsn
//
// @description: mysql配置
// @param:
// @author: GJing
// @email: guojing@tna.cn
// @date: 2022/10/26 18:15
// @success:
func MysqlEmptyDsn() string {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/", config.Config.Mysql.UserName,
config.Config.Mysql.Password,
config.Config.Mysql.Host,
config.Config.Mysql.Port)
}
// createDatabase
//
// @description: 创建数据库
// @param:
// @author: GJing
// @email: guojing@tna.cn
// @date: 2022/10/26 18:15
// @success:
func createDatabase(dsn string, driver string, createSql string) error {
db, err := sql.Open(driver, dsn)
//fmt.Println("dsn", dsn)
if err != nil {
return err
}
defer func(db *sql.DB) {
err = db.Close()
if err != nil {
fmt.Println(err)
}
}(db)
if err = db.Ping(); err != nil {
return err
}
_, err = db.Exec(createSql)
return err
}