/
db.go
136 lines (119 loc) · 3.38 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
package model
import (
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
"log"
"time"
"we-blog/conf"
)
type Model struct {
ID int `gorm:"primary_key" json:"id"`
CreatedOn int `json:"created_on"`
ModifiedOn int `json:"modified_on"`
DeletedOn int `json:"deleted_on"`
}
var DB *gorm.DB
func init() {
config, _ := conf.GetConfig()
c := config.DatasourceConfig
DB = Open(c.Host, c.Port, c.User, c.Pwd, c.Dbname)
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
return c.TablePrefix + defaultTableName
}
// 启用Logger,显示详细日志
DB.LogMode(true)
// 连接池
DB.DB().SetMaxIdleConns(c.Idles)
DB.DB().SetMaxOpenConns(c.Connections)
// 新增的回调
DB.Callback().Create().Replace("gorm:update_time_stamp", updateTimeStampForCreateCallback)
// 修改的回调
DB.Callback().Update().Replace("gorm:update_time_stamp", updateTimeStampForUpdateCallback)
// 删除的回调
DB.Callback().Delete().Replace("gorm:delete", deleteCallback)
//// 自动迁移模式
//DB.AutoMigrate(
// &SysUsers{},
// &Category{},
//)
// 禁用表明复数
DB.SingularTable(true)
}
func CloseDB() {
defer DB.Close()
}
func Open(host, port, username, password, name string) *gorm.DB {
dbConfig := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true&loc=Local",
username,
password,
host,
port,
name,
)
db, err := gorm.Open("mysql", dbConfig)
if err != nil {
log.Fatalf("【初始数据库连接失败..】 %v ", err)
}
return db
}
// 回调钩子
func updateTimeStampForCreateCallback(scope *gorm.Scope) {
if !scope.HasError() {
nowTime := time.Now().Unix()
if createTimeField, ok := scope.FieldByName("CreatedOn"); ok {
if createTimeField.IsBlank {
createTimeField.Set(nowTime)
}
}
if modifyTimeField, ok := scope.FieldByName("ModifiedOn"); ok {
if modifyTimeField.IsBlank {
modifyTimeField.Set(nowTime)
}
}
}
}
// 回调钩子
func updateTimeStampForUpdateCallback(scope *gorm.Scope) {
// 根据入参获取设置了字面值的参数
// 假设没有指定 update_column 的字段,我们默认在更新回调设置 ModifiedOn 的值
if _, ok := scope.Get("gorm:update_column"); !ok {
scope.SetColumn("ModifiedOn", time.Now().Unix())
}
}
// 软删除
func deleteCallback(scope *gorm.Scope) {
if !scope.HasError() {
var extraOption string
// 检查是否手动指定了delete_option
if str, ok := scope.Get("gorm:delete_option"); ok {
extraOption = fmt.Sprint(str)
}
// 获取我们约定的删除字段,若存在则 UPDATE 软删除,若不存在则 DELETE 硬删除
deletedOnField, hasDeletedOnField := scope.FieldByName("DeletedOn")
if !scope.Search.Unscoped && hasDeletedOnField {
scope.Raw(fmt.Sprintf(
"UPDATE %v SET %v=%v%v%v",
scope.QuotedTableName(),
scope.Quote(deletedOnField.DBName),
// 该方法可以添加值作为SQL的参数,也可用于防范SQL注入
scope.AddToVars(time.Now().Unix()),
addExtraSpaceIfExist(scope.CombinedConditionSql()),
addExtraSpaceIfExist(extraOption),
)).Exec()
} else {
scope.Raw(fmt.Sprintf(
"DELETE FROM %v%v%v",
scope.QuotedTableName(), // 返回引用的表名
addExtraSpaceIfExist(scope.CombinedConditionSql()),
addExtraSpaceIfExist(extraOption),
)).Exec()
}
}
}
func addExtraSpaceIfExist(str string) string {
if str != "" {
return " " + str
}
return ""
}