소스 검색

改成支持单数据库和单服务

qdy 2 달 전
부모
커밋
965564f82f
10개의 변경된 파일973개의 추가작업 그리고 322개의 파일을 삭제
  1. 93
    93
      dbstart/db_bootstrapper.go
  2. 204
    170
      factory/database/db_factory.go
  3. 6
    11
      factory/doris/doris_factory.go
  4. 2
    8
      factory/http/http_factory.go
  5. 591
    0
      factory/mongodb/mongodb_factory.go
  6. 2
    6
      factory/rabbitmq/rabbitmq_factory.go
  7. 11
    11
      factory/redis/redis_factory.go
  8. 9
    0
      go.mod
  9. 43
    0
      go.sum
  10. 12
    23
      test.go

+ 93
- 93
dbstart/db_bootstrapper.go 파일 보기

@@ -1,95 +1,95 @@
1 1
 package dbstart
2 2
 
3
-import (
4
-	"log"
5
-
6
-	"git.x2erp.com/qdy/go-base/config"
7
-	"git.x2erp.com/qdy/go-base/logger"
8
-	"git.x2erp.com/qdy/go-db/factory/database"
9
-)
10
-
11
-// DBBootstrapper 数据库启动器
12
-type DBBootstrapper struct {
13
-	DBFactories map[string]*database.DBFactory // 改为map存储多个数据库实例
14
-	cfg         config.IConfig
15
-}
16
-
17
-// NewDBBootstrapper 创建数据库启动器
18
-func NewDBBootstrapper(cfg config.IConfig) *DBBootstrapper {
19
-	return &DBBootstrapper{
20
-		DBFactories: make(map[string]*database.DBFactory),
21
-		cfg:         cfg,
22
-	}
23
-}
24
-
25
-// Init 初始化默认数据库
26
-func (db *DBBootstrapper) Init() *DBBootstrapper {
27
-	if db.cfg == nil {
28
-		log.Fatal("配置未初始化,请先传入配置")
29
-	}
30
-
31
-	// 初始化默认数据库
32
-	dbCfg := db.cfg.GetDatabase()
33
-	if dbCfg == nil {
34
-		log.Fatal("默认数据库配置未找到")
35
-	}
36
-
37
-	log.Printf("正在连接默认数据库: %s:%d/%s",
38
-		dbCfg.Host, dbCfg.Port, dbCfg.Database)
39
-
40
-	dbFactory, err := database.GetDefaultDBFactory()
41
-	if err != nil {
42
-		log.Fatalf("默认数据库连接失败: %v", err)
43
-	}
44
-
45
-	db.DBFactories["default"] = dbFactory
46
-	log.Println("默认数据库连接成功")
47
-
48
-	return db
49
-}
50
-
51
-// GetDBFactory 获取数据库工厂
52
-func (db *DBBootstrapper) GetDBFactory(dbName string) *database.DBFactory {
53
-	// 如果已经初始化,直接返回
54
-	if factory, exists := db.DBFactories[dbName]; exists {
55
-		return factory
56
-	}
57
-
58
-	// 如果还没初始化,按需初始化
59
-	dbFactory, err := database.GetDBFactory(dbName)
60
-	if err != nil {
61
-		log.Printf("❌ 获取数据库 '%s' 失败: %v", dbName, err)
62
-		return nil
63
-	}
64
-
65
-	db.DBFactories[dbName] = dbFactory
66
-	return dbFactory
67
-}
68
-
69
-// GetDefaultDBFactory 获取默认数据库工厂
70
-func (db *DBBootstrapper) GetDefaultDBFactory() *database.DBFactory {
71
-	return db.GetDBFactory("default")
72
-}
73
-
74
-// Close 关闭所有数据库连接
75
-func (db *DBBootstrapper) Close() {
76
-
77
-	for name, factory := range db.DBFactories {
78
-		logger.Info("正在关闭数据库: %s, factory: %v", name, factory)
79
-		if factory != nil {
80
-			factory.Close()
81
-			logger.Info("数据库 '%s' 连接已关闭", name)
82
-		} else {
83
-			logger.Error("⚠️  警告: 数据库 '%s' 的 factory 为 nil", name)
84
-		}
85
-	}
86
-
87
-	// 清空map
88
-	db.DBFactories = make(map[string]*database.DBFactory)
89
-	logger.Info("所有数据库连接已关闭.")
90
-}
91
-
92
-// 在 dbstart 包中
93
-func (db *DBBootstrapper) OnShutdown() {
94
-	db.Close()
95
-}
3
+// import (
4
+// 	"log"
5
+
6
+// 	"git.x2erp.com/qdy/go-base/config"
7
+// 	"git.x2erp.com/qdy/go-base/logger"
8
+// 	"git.x2erp.com/qdy/go-db/factory/database"
9
+// )
10
+
11
+// // DBBootstrapper 数据库启动器
12
+// type DBBootstrapper struct {
13
+// 	DBFactories map[string]*database.DBFactory // 改为map存储多个数据库实例
14
+// 	cfg         config.IConfig
15
+// }
16
+
17
+// // NewDBBootstrapper 创建数据库启动器
18
+// func NewDBBootstrapper(cfg config.IConfig) *DBBootstrapper {
19
+// 	return &DBBootstrapper{
20
+// 		DBFactories: make(map[string]*database.DBFactory),
21
+// 		cfg:         cfg,
22
+// 	}
23
+// }
24
+
25
+// // Init 初始化默认数据库
26
+// func (db *DBBootstrapper) Init() *DBBootstrapper {
27
+// 	if db.cfg == nil {
28
+// 		log.Fatal("配置未初始化,请先传入配置")
29
+// 	}
30
+
31
+// 	// // 初始化默认数据库
32
+// 	// dbCfg := db.cfg.GetDatabaseConfig()
33
+// 	// if dbCfg == nil {
34
+// 	// 	log.Fatal("默认数据库配置未找到")
35
+// 	// }
36
+
37
+// 	// log.Printf("正在连接默认数据库: %s:%d/%s",
38
+// 	// 	dbCfg.Host, dbCfg.Port, dbCfg.Database)
39
+
40
+// 	dbFactory, err := database.GetDefaultDBFactory()
41
+// 	if err != nil {
42
+// 		log.Fatalf("默认数据库连接失败: %v", err)
43
+// 	}
44
+
45
+// 	db.DBFactories["default"] = dbFactory
46
+// 	log.Println("默认数据库连接成功")
47
+
48
+// 	return db
49
+// }
50
+
51
+// // GetDBFactory 获取数据库工厂
52
+// func (db *DBBootstrapper) GetDBFactory(dbName string) *database.DBFactory {
53
+// 	// 如果已经初始化,直接返回
54
+// 	if factory, exists := db.DBFactories[dbName]; exists {
55
+// 		return factory
56
+// 	}
57
+
58
+// 	// 如果还没初始化,按需初始化
59
+// 	dbFactory, err := database.GetDBFactory(dbName)
60
+// 	if err != nil {
61
+// 		log.Printf("❌ 获取数据库 '%s' 失败: %v", dbName, err)
62
+// 		return nil
63
+// 	}
64
+
65
+// 	db.DBFactories[dbName] = dbFactory
66
+// 	return dbFactory
67
+// }
68
+
69
+// // GetDefaultDBFactory 获取默认数据库工厂
70
+// func (db *DBBootstrapper) GetDefaultDBFactory() *database.DBFactory {
71
+// 	return db.GetDBFactory("default")
72
+// }
73
+
74
+// // Close 关闭所有数据库连接
75
+// func (db *DBBootstrapper) Close() {
76
+
77
+// 	for name, factory := range db.DBFactories {
78
+// 		logger.Info("正在关闭数据库: %s, factory: %v", name, factory)
79
+// 		if factory != nil {
80
+// 			factory.Close()
81
+// 			logger.Info("数据库 '%s' 连接已关闭", name)
82
+// 		} else {
83
+// 			logger.Error("⚠️  警告: 数据库 '%s' 的 factory 为 nil", name)
84
+// 		}
85
+// 	}
86
+
87
+// 	// 清空map
88
+// 	db.DBFactories = make(map[string]*database.DBFactory)
89
+// 	logger.Info("所有数据库连接已关闭.")
90
+// }
91
+
92
+// // 在 dbstart 包中
93
+// func (db *DBBootstrapper) OnShutdown() {
94
+// 	db.Close()
95
+// }

+ 204
- 170
factory/database/db_factory.go 파일 보기

@@ -6,7 +6,9 @@ import (
6 6
 	"sync"
7 7
 
8 8
 	"git.x2erp.com/qdy/go-base/config"
9
+	"git.x2erp.com/qdy/go-base/config/subconfigs"
9 10
 	"git.x2erp.com/qdy/go-base/ctx"
11
+	"git.x2erp.com/qdy/go-base/logger"
10 12
 	"git.x2erp.com/qdy/go-base/types"
11 13
 	"git.x2erp.com/qdy/go-db/drivers"
12 14
 	"git.x2erp.com/qdy/go-db/functions"
@@ -14,239 +16,149 @@ import (
14 16
 	"github.com/jmoiron/sqlx"
15 17
 )
16 18
 
19
+// DBFactory 数据库工厂(全局单例模式)
17 20
 type DBFactory struct {
18
-	db   *sqlx.DB
19
-	name string // 记录数据库配置名称
21
+	db     *sqlx.DB
22
+	config *subconfigs.DatabaseConfig
20 23
 }
21 24
 
22 25
 var (
23
-	// 多实例存储:配置名称 -> DBFactory 实例
24
-	instances = make(map[string]*DBFactory)
25
-	// 每个配置名称对应的once,确保线程安全
26
-	onceMap = make(map[string]*sync.Once)
27
-	// 保护instances和onceMap的读写锁
28
-	instancesMutex sync.RWMutex
26
+	instanceDB     *DBFactory
27
+	instanceDBOnce sync.Once
28
+	initErrDB      error
29 29
 )
30 30
 
31
-// GetDBFactory 获取指定名称的数据库工厂单例
32
-func GetDBFactory(dbName string) (*DBFactory, error) {
33
-	// 获取或创建该名称的once对象
34
-	instancesMutex.Lock()
35
-	once, exists := onceMap[dbName]
36
-	if !exists {
37
-		once = &sync.Once{}
38
-		onceMap[dbName] = once
39
-	}
40
-	instancesMutex.Unlock()
31
+// CreateDBFactory 获取数据库工厂单例
32
+func CreateDBFactory(cfg config.IConfig) *DBFactory {
33
+	config := cfg.GetDatabaseConfig()
34
+	instanceDBOnce.Do(func() {
41 35
 
42
-	var initErr error
43
-	var instance *DBFactory
44
-	var msg = fmt.Sprintf("DBFactory '%s' instance retrieved from memory.\n", dbName)
36
+		if config == nil {
37
+			log.Fatal("配置未初始化,请先在yaml进行配置")
38
+		}
45 39
 
46
-	once.Do(func() {
47
-		// 使用配置单例
48
-		cfg, err := config.GetConfig()
49
-		if err != nil {
50
-			initErr = fmt.Errorf("failed to load config: %v", err)
51
-			return
40
+		// 设置默认值
41
+		if config.MaxOpenConns == 0 {
42
+			config.MaxOpenConns = 100
43
+		}
44
+		if config.MaxIdleConns == 0 {
45
+			config.MaxIdleConns = 10
46
+		}
47
+		if config.ConnMaxLifetime == 0 {
48
+			config.ConnMaxLifetime = 5 * 60 // 5分钟,单位秒
52 49
 		}
53 50
 
54
-		// 获取指定名称的数据库配置
55
-		dbConfig := cfg.GetDatabaseConfig(dbName)
56
-		if dbConfig == nil {
57
-			initErr = fmt.Errorf("database configuration '%s' not found", dbName)
51
+		// 验证配置
52
+		if config.Type == "" {
53
+			initErrDB = fmt.Errorf("database type must be configured")
54
+			return
55
+		}
56
+		if config.Host == "" {
57
+			initErrDB = fmt.Errorf("database host must be configured")
58
+			return
59
+		}
60
+		if config.Database == "" {
61
+			initErrDB = fmt.Errorf("database name must be configured")
58 62
 			return
59 63
 		}
60 64
 
61
-		// // 检查数据库配置是否完整
62
-		// if !dbConfig.IsConfigured() {
63
-		// 	initErr = fmt.Errorf("database configuration '%s' is incomplete", dbName)
64
-		// 	return
65
-		// }
66
-
67
-		// 获取数据库类型
68
-		dbType := dbConfig.Type
69
-		log.Printf("Creating database connection for '%s' with type: %s\n", dbName, dbType)
65
+		log.Printf("Creating database connection...")
70 66
 
71 67
 		// 获取对应的驱动
72
-		dbDriver, err := drivers.Get(dbType)
68
+		dbDriver, err := drivers.Get(config.Type)
73 69
 		if err != nil {
74
-			initErr = fmt.Errorf("failed to get database driver: %v", err)
70
+			initErrDB = fmt.Errorf("failed to get database driver: %v", err)
75 71
 			return
76 72
 		}
77 73
 
78 74
 		// 将内部 DBConfig 转换为 drivers.DBConfig
79 75
 		driverConfig := drivers.DBConfig{
80
-			Type:            dbConfig.Type,
81
-			Host:            dbConfig.Host,
82
-			Port:            dbConfig.Port,
83
-			Username:        dbConfig.Username,
84
-			Password:        dbConfig.Password,
85
-			Database:        dbConfig.Database,
86
-			MaxOpenConns:    dbConfig.MaxOpenConns,
87
-			MaxIdleConns:    dbConfig.MaxIdleConns,
88
-			ConnMaxLifetime: dbConfig.ConnMaxLifetime,
76
+			Type:            config.Type,
77
+			Host:            config.Host,
78
+			Port:            config.Port,
79
+			Username:        config.Username,
80
+			Password:        config.Password,
81
+			Database:        config.Database,
82
+			MaxOpenConns:    config.MaxOpenConns,
83
+			MaxIdleConns:    config.MaxIdleConns,
84
+			ConnMaxLifetime: config.ConnMaxLifetime,
89 85
 		}
90 86
 
91 87
 		// 创建数据库连接
92 88
 		db, err := dbDriver.Open(driverConfig)
93 89
 		if err != nil {
94
-			initErr = fmt.Errorf("failed to open database connection for '%s': %v", dbName, err)
90
+			initErrDB = fmt.Errorf("failed to open database connection: %v", err)
95 91
 			return
96 92
 		}
97 93
 
98 94
 		// 测试连接
99
-		if err := functions.TestConnection(db, dbType); err != nil {
95
+		if err := functions.TestConnection(db, config.Type); err != nil {
100 96
 			db.Close()
101
-			initErr = fmt.Errorf("database connection test failed for '%s': %v", dbName, err)
97
+			initErrDB = fmt.Errorf("database connection test failed: %v", err)
102 98
 			return
103 99
 		}
104 100
 
105
-		msg = fmt.Sprintf("DBFactory '%s' is successfully created.\n", dbName)
106
-		instance = &DBFactory{
107
-			db:   db,
108
-			name: dbName,
109
-		}
101
+		log.Printf("DBFactory is successfully created.\n")
110 102
 
111
-		// 保存实例到map
112
-		instancesMutex.Lock()
113
-		instances[dbName] = instance
114
-		instancesMutex.Unlock()
103
+		instanceDB = &DBFactory{
104
+			db:     db,
105
+			config: config,
106
+		}
115 107
 	})
116 108
 
117
-	if initErr != nil {
118
-		return nil, initErr
109
+	if initErrDB != nil {
110
+		log.Fatalf("DBFactory is error: '%v'", initErrDB)
119 111
 	}
120 112
 
121
-	log.Print(msg)
122
-
123
-	// 从map中获取实例
124
-	instancesMutex.RLock()
125
-	instance = instances[dbName]
126
-	instancesMutex.RUnlock()
127
-
128
-	return instance, nil
129
-}
130
-
131
-// GetDefaultDBFactory 获取默认数据库工厂(向后兼容)
132
-func GetDefaultDBFactory() (*DBFactory, error) {
133
-	return GetDBFactory("default")
134
-}
135
-
136
-// GetAllDBFactories 获取所有已创建的数据库工厂实例
137
-func GetAllDBFactories() map[string]*DBFactory {
138
-	instancesMutex.RLock()
139
-	defer instancesMutex.RUnlock()
140
-
141
-	// 创建副本,避免外部修改
142
-	result := make(map[string]*DBFactory)
143
-	for k, v := range instances {
144
-		result[k] = v
145
-	}
146
-	return result
147
-}
148
-
149
-// GetDBFactoryNames 获取所有可用的数据库配置名称
150
-func GetDBFactoryNames() []string {
151
-	cfg, err := config.GetConfig()
152
-	if err != nil {
153
-		return []string{}
154
-	}
155
-
156
-	dbs := cfg.GetDatabases()
157
-	if dbs == nil {
158
-		return []string{}
159
-	}
160
-
161
-	return dbs.GetAllDatabaseNames()
162
-}
163
-
164
-// CloseInstance 关闭指定名称的数据库连接
165
-func CloseInstance(dbName string) error {
166
-	instancesMutex.Lock()
167
-	defer instancesMutex.Unlock()
168
-
169
-	if instance, exists := instances[dbName]; exists {
170
-		err := instance.Close()
171
-		delete(instances, dbName)
172
-		delete(onceMap, dbName)
173
-		return err
174
-	}
175
-
176
-	return fmt.Errorf("database instance '%s' not found", dbName)
177
-}
178
-
179
-// CloseAll 关闭所有数据库连接
180
-func CloseAll() {
181
-	instancesMutex.Lock()
182
-	defer instancesMutex.Unlock()
183
-
184
-	for name, instance := range instances {
185
-		if err := instance.Close(); err != nil {
186
-			log.Printf("Error closing database instance '%s': %v\n", name, err)
187
-		}
188
-		delete(instances, name)
189
-		delete(onceMap, name)
190
-	}
191
-
192
-	// 重新初始化maps
193
-	instances = make(map[string]*DBFactory)
194
-	onceMap = make(map[string]*sync.Once)
195
-
196
-	log.Println("All database connections closed gracefully")
113
+	return instanceDB
197 114
 }
198 115
 
199 116
 // ========== DBFactory 实例方法 ==========
200 117
 
201
-// GetDB 获取数据库连接(线程安全)
202
-func (f *DBFactory) GetDB() interface{} {
118
+// GetDB 获取数据库连接
119
+func (f *DBFactory) GetDB() *sqlx.DB {
203 120
 	return f.db
204 121
 }
205 122
 
123
+func (f *DBFactory) GetName() string {
124
+	return "DBFactory"
125
+}
126
+
206 127
 // Close 关闭数据库连接
207
-func (f *DBFactory) Close() error {
128
+func (f *DBFactory) Close() {
208 129
 	if f.db != nil {
209 130
 		err := f.db.Close()
131
+		if err != nil {
132
+			logger.Errorf("failed to close database connection: %v", err)
133
+		}
134
+		log.Printf("Database connection closed gracefully\n")
210 135
 		f.db = nil
211
-		log.Printf("Database connection '%s' closed gracefully\n", f.name)
212
-		return err
213 136
 	}
214
-	return nil
215 137
 }
216 138
 
217
-// GetDBType 得到当前使用数据库类型
218
-func (f *DBFactory) GetDBType() string {
219
-	// 通过配置获取当前数据库的类型
220
-	cfg, err := config.GetConfig()
221
-	if err != nil {
222
-		return ""
223
-	}
224
-
225
-	dbConfig := cfg.GetDatabaseConfig(f.name)
226
-	if dbConfig == nil {
227
-		return ""
228
-	}
229
-
230
-	return dbConfig.Type
139
+// GetConfig 获取配置信息
140
+func (f *DBFactory) GetConfig() subconfigs.DatabaseConfig {
141
+	return *f.config
231 142
 }
232 143
 
233
-// GetDBName 获取数据库配置名称
234
-func (f *DBFactory) GetDBName() string {
235
-	return f.name
144
+// TestConnection 测试连接
145
+func (f *DBFactory) TestConnection() error {
146
+	return functions.TestConnection(f.db, f.config.Type)
236 147
 }
237 148
 
149
+// ========== 快捷操作方法 ==========
150
+
238 151
 // QueryToJSON 快捷查询,直接返回 JSON 字节流
239 152
 func (f *DBFactory) QueryToJSON(sql string, reqCtx *ctx.RequestContext) *types.QueryResult[[]map[string]interface{}] {
240 153
 	return functions.QueryToJSON(f.db, sql, reqCtx)
241 154
 }
242 155
 
243
-// QueryParamsToJSON 位置参数查询并返回 JSON 字节数据
156
+// QueryPositionalToJSON 位置参数查询并返回 JSON 字节数据
244 157
 func (f *DBFactory) QueryPositionalToJSON(sql string, params []interface{}, reqCtx *ctx.RequestContext) *types.QueryResult[[]map[string]interface{}] {
245 158
 	return functions.QueryPositionalToJSON(f.db, sql, params, reqCtx)
246 159
 }
247 160
 
248 161
 // QueryParamsNameToJSON 命名参数查询并返回 JSON 字节数据
249
-// params 可以是 map[string]interface{} 或结构体
250 162
 func (f *DBFactory) QueryParamsNameToJSON(sql string, params map[string]interface{}, reqCtx *ctx.RequestContext) *types.QueryResult[[]map[string]interface{}] {
251 163
 	return functions.QueryParamsNameToJSON(f.db, sql, params, reqCtx)
252 164
 }
@@ -256,13 +168,12 @@ func (f *DBFactory) QueryToCSV(sql string, writerHeader bool, reqCtx *ctx.Reques
256 168
 	return functions.QueryToCSV(f.db, sql, writerHeader, reqCtx)
257 169
 }
258 170
 
259
-// QueryParamsToCSV 位置参数查询并返回 CSV 字节数据
171
+// QueryPositionalToCSV 位置参数查询并返回 CSV 字节数据
260 172
 func (f *DBFactory) QueryPositionalToCSV(sql string, writerHeader bool, params []interface{}, reqCtx *ctx.RequestContext) ([]byte, error) {
261 173
 	return functions.QueryPositionalToCSV(f.db, sql, writerHeader, params, reqCtx)
262 174
 }
263 175
 
264 176
 // QueryParamsNameToCSV 命名参数查询并返回 CSV 字节数据
265
-// params 可以是 map[string]interface{} 或结构体
266 177
 func (f *DBFactory) QueryParamsNameToCSV(sql string, writerHeader bool, params map[string]interface{}, reqCtx *ctx.RequestContext) ([]byte, error) {
267 178
 	return functions.QueryParamsNameToCSV(f.db, sql, writerHeader, params, reqCtx)
268 179
 }
@@ -282,11 +193,134 @@ func (f *DBFactory) ExecuteMultipleDDL(ddlSQLs []string) error {
282 193
 	return functions.ExecuteMultipleDDL(f.db, ddlSQLs)
283 194
 }
284 195
 
196
+// GetDBType 得到当前使用数据库类型
197
+func (f *DBFactory) GetDBType() string {
198
+	return f.config.Type
199
+}
200
+
201
+// GetDatabaseName 获取数据库名称
202
+func (f *DBFactory) GetDatabaseName() string {
203
+	return f.config.Database
204
+}
205
+
206
+// GetHost 获取数据库主机
207
+func (f *DBFactory) GetHost() string {
208
+	return f.config.Host
209
+}
210
+
211
+// GetPort 获取数据库端口
212
+func (f *DBFactory) GetPort() int {
213
+	return f.config.Port
214
+}
215
+
216
+// BeginTx 开始事务
217
+func (f *DBFactory) BeginTx() (*sqlx.Tx, error) {
218
+	return f.db.Beginx()
219
+}
220
+
221
+// GetStats 获取数据库连接统计信息
222
+func (f *DBFactory) GetStats() interface{} {
223
+	return f.db.Stats()
224
+}
225
+
226
+// Ping 测试数据库连接是否正常
227
+func (f *DBFactory) Ping() error {
228
+	return f.db.Ping()
229
+}
230
+
285 231
 // GetAvailableDrivers 获取可用的数据库驱动
286 232
 func (f *DBFactory) GetAvailableDrivers() []string {
287 233
 	return drivers.GetAllDrivers()
288 234
 }
289 235
 
290
-func (f *DBFactory) TestConnection(dbType string) error {
291
-	return functions.TestConnection(f.db, dbType)
236
+// ========== 新增的简化操作方法 ==========
237
+
238
+// QueryOne 查询单条记录
239
+func (f *DBFactory) QueryOne(sql string, dest interface{}) error {
240
+	return f.db.Get(dest, sql)
241
+}
242
+
243
+// QueryOneWithParams 带参数查询单条记录
244
+func (f *DBFactory) QueryOneWithParams(sql string, dest interface{}, params ...interface{}) error {
245
+	return f.db.Get(dest, sql, params...)
246
+}
247
+
248
+// QueryMany 查询多条记录
249
+func (f *DBFactory) QueryMany(sql string, dest interface{}) error {
250
+	return f.db.Select(dest, sql)
251
+}
252
+
253
+// QueryManyWithParams 带参数查询多条记录
254
+func (f *DBFactory) QueryManyWithParams(sql string, dest interface{}, params ...interface{}) error {
255
+	return f.db.Select(dest, sql, params...)
256
+}
257
+
258
+// Execute 执行更新操作
259
+func (f *DBFactory) Execute(sql string) (int64, error) {
260
+	result, err := f.db.Exec(sql)
261
+	if err != nil {
262
+		return 0, err
263
+	}
264
+	return result.RowsAffected()
265
+}
266
+
267
+// ExecuteWithParams 带参数执行更新操作
268
+func (f *DBFactory) ExecuteWithParams(sql string, params ...interface{}) (int64, error) {
269
+	result, err := f.db.Exec(sql, params...)
270
+	if err != nil {
271
+		return 0, err
272
+	}
273
+	return result.RowsAffected()
274
+}
275
+
276
+// QueryMap 查询单条记录到map
277
+func (f *DBFactory) QueryMap(sql string) (map[string]interface{}, error) {
278
+	result := make(map[string]interface{})
279
+	err := f.db.QueryRowx(sql).MapScan(result)
280
+	return result, err
281
+}
282
+
283
+// QueryMapWithParams 带参数查询单条记录到map
284
+func (f *DBFactory) QueryMapWithParams(sql string, params ...interface{}) (map[string]interface{}, error) {
285
+	result := make(map[string]interface{})
286
+	err := f.db.QueryRowx(sql, params...).MapScan(result)
287
+	return result, err
288
+}
289
+
290
+// QuerySliceMap 查询多条记录到map切片
291
+func (f *DBFactory) QuerySliceMap(sql string) ([]map[string]interface{}, error) {
292
+	rows, err := f.db.Queryx(sql)
293
+	if err != nil {
294
+		return nil, err
295
+	}
296
+	defer rows.Close()
297
+
298
+	var results []map[string]interface{}
299
+	for rows.Next() {
300
+		result := make(map[string]interface{})
301
+		if err := rows.MapScan(result); err != nil {
302
+			return nil, err
303
+		}
304
+		results = append(results, result)
305
+	}
306
+	return results, nil
307
+}
308
+
309
+// QuerySliceMapWithParams 带参数查询多条记录到map切片
310
+func (f *DBFactory) QuerySliceMapWithParams(sql string, params ...interface{}) ([]map[string]interface{}, error) {
311
+	rows, err := f.db.Queryx(sql, params...)
312
+	if err != nil {
313
+		return nil, err
314
+	}
315
+	defer rows.Close()
316
+
317
+	var results []map[string]interface{}
318
+	for rows.Next() {
319
+		result := make(map[string]interface{})
320
+		if err := rows.MapScan(result); err != nil {
321
+			return nil, err
322
+		}
323
+		results = append(results, result)
324
+	}
325
+	return results, nil
292 326
 }

+ 6
- 11
factory/doris/doris_factory.go 파일 보기

@@ -25,20 +25,15 @@ type DorisFactory struct {
25 25
 }
26 26
 
27 27
 var (
28
-	instance     *DorisFactory
29
-	instanceOnce sync.Once
28
+	instanceDoris     *DorisFactory
29
+	instanceDorisOnce sync.Once
30 30
 )
31 31
 
32 32
 // GetDorisFactory 获取Doris工厂单例
33 33
 func GetDorisFactory(httpFactory *http.HTTPFactory) (*DorisFactory, error) {
34 34
 	var initErr error
35
-	instanceOnce.Do(func() {
36
-		cfg, err := config.GetConfig()
37
-
38
-		if err != nil {
39
-			initErr = fmt.Errorf("failed to load config: %v", err)
40
-			return
41
-		}
35
+	instanceDorisOnce.Do(func() {
36
+		cfg := config.GetConfig()
42 37
 
43 38
 		if !cfg.IsDorisConfigured() {
44 39
 			initErr = fmt.Errorf("doris configuration is incomplete")
@@ -46,7 +41,7 @@ func GetDorisFactory(httpFactory *http.HTTPFactory) (*DorisFactory, error) {
46 41
 		}
47 42
 
48 43
 		dorisConfig := cfg.GetDorisConfig()
49
-		instance = &DorisFactory{
44
+		instanceDoris = &DorisFactory{
50 45
 			client:   httpFactory.GetUnderlyingClient(),
51 46
 			FEHost:   dorisConfig.FEHost,
52 47
 			FEPort:   dorisConfig.FEPort,
@@ -61,7 +56,7 @@ func GetDorisFactory(httpFactory *http.HTTPFactory) (*DorisFactory, error) {
61 56
 		return nil, initErr
62 57
 	}
63 58
 
64
-	return instance, nil
59
+	return instanceDoris, nil
65 60
 }
66 61
 
67 62
 // InsertCSV 插入CSV数据到Doris

+ 2
- 8
factory/http/http_factory.go 파일 보기

@@ -2,7 +2,6 @@ package http
2 2
 
3 3
 import (
4 4
 	"encoding/base64"
5
-	"fmt"
6 5
 	"net/http"
7 6
 	"sync"
8 7
 	"time"
@@ -31,14 +30,9 @@ var (
31 30
 // GetHTTPFactory 获取HTTP工厂单例实例
32 31
 func GetHTTPFactory() (*HTTPFactory, error) {
33 32
 	httpFactoryOnce.Do(func() {
34
-		cfg, err := config.GetConfig()
33
+		cfg := config.GetConfig()
35 34
 
36
-		if err != nil {
37
-			httpFactoryInitErr = fmt.Errorf("failed to load config: %v", err)
38
-			return
39
-		}
40
-
41
-		httpConfig := cfg.GetHTTP()
35
+		httpConfig := cfg.GetHTTPConfig()
42 36
 
43 37
 		// 创建共享的resty客户端(线程安全)
44 38
 		client := resty.New()

+ 591
- 0
factory/mongodb/mongodb_factory.go 파일 보기

@@ -0,0 +1,591 @@
1
+package mongodb
2
+
3
+import (
4
+	"context"
5
+	"crypto/tls"
6
+	"fmt"
7
+	"log"
8
+	"sync"
9
+	"time"
10
+
11
+	"git.x2erp.com/qdy/go-base/config/subconfigs"
12
+	"git.x2erp.com/qdy/go-base/logger"
13
+	"go.mongodb.org/mongo-driver/bson"
14
+	"go.mongodb.org/mongo-driver/mongo"
15
+	"go.mongodb.org/mongo-driver/mongo/options"
16
+	"go.mongodb.org/mongo-driver/mongo/readpref"
17
+)
18
+
19
+// MongoDBFactory MongoDB工厂(全局单例模式)
20
+type MongoDBFactory struct {
21
+	client *mongo.Client
22
+	db     *mongo.Database
23
+	config *subconfigs.MongoDBConfig
24
+	//mu     sync.RWMutex // 添加读写锁保护
25
+}
26
+
27
+var (
28
+	instanceMongodb     *MongoDBFactory
29
+	instanceMongodbOnce sync.Once
30
+	initErr             error
31
+)
32
+
33
+// GetMongoDBFactory 获取MongoDB工厂单例
34
+func GetMongoDBFactory(config *subconfigs.MongoDBConfig) *MongoDBFactory {
35
+
36
+	instanceMongodbOnce.Do(func() {
37
+		if config == nil {
38
+			log.Fatal("配置未初始化,请先在yaml进行配置")
39
+		}
40
+
41
+		// 设置默认值
42
+		if config.Timeout == 0 {
43
+			config.Timeout = 20 * time.Second
44
+		}
45
+		if config.MaxPoolSize == 0 {
46
+			config.MaxPoolSize = 100
47
+		}
48
+		if config.MinPoolSize == 0 {
49
+			config.MinPoolSize = 10
50
+		}
51
+		if config.AuthSource == "" {
52
+			config.AuthSource = "admin"
53
+		}
54
+
55
+		// 验证配置
56
+		if config.URI == "" {
57
+			initErr = fmt.Errorf("mongodb URI must be configured")
58
+			return
59
+		}
60
+		if config.Database == "" {
61
+			initErr = fmt.Errorf("mongodb database name must be configured")
62
+			return
63
+		}
64
+
65
+		log.Printf("Creating MongoDB connection...")
66
+
67
+		// 创建客户端选项
68
+		clientOptions := options.Client().
69
+			ApplyURI(config.URI).
70
+			SetConnectTimeout(config.Timeout).
71
+			SetSocketTimeout(config.Timeout).
72
+			SetServerSelectionTimeout(config.Timeout).
73
+			SetMaxPoolSize(config.MaxPoolSize).
74
+			SetMinPoolSize(config.MinPoolSize).
75
+			SetMaxConnIdleTime(5 * time.Minute).
76
+			SetHeartbeatInterval(10 * time.Second)
77
+
78
+		// 设置认证
79
+		if config.Username != "" && config.Password != "" {
80
+			clientOptions.SetAuth(options.Credential{
81
+				Username:   config.Username,
82
+				Password:   config.Password,
83
+				AuthSource: config.AuthSource,
84
+			})
85
+		}
86
+
87
+		// 设置SSL
88
+		if config.SSL {
89
+			clientOptions.SetTLSConfig(&tls.Config{
90
+				InsecureSkipVerify: false,
91
+			})
92
+		}
93
+
94
+		// 创建上下文
95
+		ctx, cancel := context.WithTimeout(context.Background(), config.Timeout)
96
+		defer cancel()
97
+
98
+		log.Printf(" context.WithTimeout ... successfully.")
99
+
100
+		// 连接MongoDB
101
+		client, err := mongo.Connect(ctx, clientOptions)
102
+		if err != nil {
103
+			initErr = fmt.Errorf("failed to connect to MongoDB: %v", err)
104
+			return
105
+		}
106
+
107
+		log.Printf(" mongo.connect ... successfully.")
108
+
109
+		// // 测试连接
110
+		// if err := client.Ping(ctx, nil); err != nil {
111
+		// 	initErr = fmt.Errorf("failed to ping MongoDB: %v", err)
112
+		// 	return
113
+		// }
114
+
115
+		// 获取数据库
116
+		database := client.Database(config.Database)
117
+
118
+		log.Printf("MongoDBFactory is successfully created.\n")
119
+
120
+		instanceMongodb = &MongoDBFactory{
121
+			client: client,
122
+			db:     database,
123
+			config: config,
124
+		}
125
+	})
126
+
127
+	if initErr != nil {
128
+		//logger.Errorf("MongoDBFactory is error:'%v'", initErr)
129
+		log.Fatalf("MongoDBFactory is error:'%v'", initErr)
130
+		//return nil
131
+	}
132
+
133
+	return instanceMongodb
134
+}
135
+
136
+// ========== MongoDBFactory 实例方法 ==========
137
+
138
+// GetClient 获取MongoDB客户端
139
+func (f *MongoDBFactory) GetClient() *mongo.Client {
140
+	return f.client
141
+}
142
+
143
+// GetDatabase 获取数据库
144
+func (f *MongoDBFactory) GetDatabase() *mongo.Database {
145
+	return f.db
146
+}
147
+
148
+// GetCollection 获取集合(类似获取数据库连接)
149
+func (f *MongoDBFactory) GetCollection(collectionName string) *mongo.Collection {
150
+	return f.db.Collection(collectionName)
151
+}
152
+
153
+// Close 关闭MongoDB连接
154
+func (f *MongoDBFactory) Close() {
155
+	if f.client != nil {
156
+		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
157
+		defer cancel()
158
+
159
+		err := f.client.Disconnect(ctx)
160
+		if err != nil {
161
+			logger.Errorf("failed to disconnect MongoDB: %v", err)
162
+			//return fmt.Errorf("failed to disconnect MongoDB: %v", err)
163
+		}
164
+
165
+		log.Printf("MongoDB connection closed gracefully\n")
166
+		f.client = nil
167
+		f.db = nil
168
+	}
169
+
170
+}
171
+
172
+// GetConfig 获取配置信息
173
+func (f *MongoDBFactory) GetConfig() subconfigs.MongoDBConfig {
174
+	return *f.config
175
+}
176
+
177
+// TestConnection 测试连接
178
+func (f *MongoDBFactory) TestConnection() error {
179
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
180
+	defer cancel()
181
+
182
+	return f.client.Ping(ctx, readpref.Primary())
183
+}
184
+
185
+// ========== 快捷操作方法(增强版) ==========
186
+
187
+// InsertOne 插入单个文档,返回是否成功
188
+func (f *MongoDBFactory) InsertOne(collectionName string, document interface{}) bool {
189
+	collection := f.GetCollection(collectionName)
190
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
191
+	defer cancel()
192
+
193
+	_, err := collection.InsertOne(ctx, document)
194
+	if err != nil {
195
+		logger.Errorf("插入文档失败,集合:%s,错误:%v", collectionName, err)
196
+		return false
197
+	}
198
+	return true
199
+}
200
+
201
+// InsertOneWithResult 插入单个文档并返回结果
202
+func (f *MongoDBFactory) InsertOneWithResult(collectionName string, document interface{}) (*mongo.InsertOneResult, bool) {
203
+	collection := f.GetCollection(collectionName)
204
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
205
+	defer cancel()
206
+
207
+	result, err := collection.InsertOne(ctx, document)
208
+	if err != nil {
209
+		logger.Errorf("插入文档失败,集合:%s,错误:%v", collectionName, err)
210
+		return nil, false
211
+	}
212
+	return result, true
213
+}
214
+
215
+// InsertMany 插入多个文档,返回是否成功
216
+func (f *MongoDBFactory) InsertMany(collectionName string, documents []interface{}) bool {
217
+	collection := f.GetCollection(collectionName)
218
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
219
+	defer cancel()
220
+
221
+	_, err := collection.InsertMany(ctx, documents)
222
+	if err != nil {
223
+		logger.Errorf("批量插入文档失败,集合:%s,错误:%v", collectionName, err)
224
+		return false
225
+	}
226
+	return true
227
+}
228
+
229
+// InsertManyWithResult 插入多个文档并返回结果
230
+func (f *MongoDBFactory) InsertManyWithResult(collectionName string, documents []interface{}) (*mongo.InsertManyResult, bool) {
231
+	collection := f.GetCollection(collectionName)
232
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
233
+	defer cancel()
234
+
235
+	result, err := collection.InsertMany(ctx, documents)
236
+	if err != nil {
237
+		logger.Errorf("批量插入文档失败,集合:%s,错误:%v", collectionName, err)
238
+		return nil, false
239
+	}
240
+	return result, true
241
+}
242
+
243
+// FindOne 查询单个文档,返回解码后的对象
244
+func (f *MongoDBFactory) FindOne(collectionName string, filter interface{}, result interface{}) error {
245
+	collection := f.GetCollection(collectionName)
246
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
247
+	defer cancel()
248
+
249
+	err := collection.FindOne(ctx, filter).Decode(result)
250
+	if err != nil {
251
+		if err != mongo.ErrNoDocuments {
252
+			logger.Errorf("查询文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
253
+		}
254
+		return err
255
+	}
256
+	return nil
257
+}
258
+
259
+// FindOneAndDecode 查询单个文档并自动解码(简化版)
260
+func (f *MongoDBFactory) FindOneAndDecode(collectionName string, filter interface{}) (interface{}, error) {
261
+	collection := f.GetCollection(collectionName)
262
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
263
+	defer cancel()
264
+
265
+	var result map[string]interface{}
266
+	err := collection.FindOne(ctx, filter).Decode(&result)
267
+	if err != nil {
268
+		if err != mongo.ErrNoDocuments {
269
+			logger.Errorf("查询文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
270
+		}
271
+		return nil, err
272
+	}
273
+	return result, nil
274
+}
275
+
276
+// Find 查询多个文档,返回对象数组
277
+func (f *MongoDBFactory) Find(collectionName string, filter interface{}, results interface{}, opts ...*options.FindOptions) error {
278
+	collection := f.GetCollection(collectionName)
279
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
280
+	defer cancel()
281
+
282
+	cursor, err := collection.Find(ctx, filter, opts...)
283
+	if err != nil {
284
+		logger.Errorf("查询文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
285
+		return err
286
+	}
287
+	defer cursor.Close(ctx)
288
+
289
+	// 解码到传入的切片指针中
290
+	if err = cursor.All(ctx, results); err != nil {
291
+		logger.Errorf("解码查询结果失败,集合:%s,错误:%v", collectionName, err)
292
+		return err
293
+	}
294
+	return nil
295
+}
296
+
297
+// FindAll 查询所有文档,返回对象数组
298
+func (f *MongoDBFactory) FindAll(collectionName string, results interface{}) error {
299
+	return f.Find(collectionName, bson.M{}, results)
300
+}
301
+
302
+// UpdateOneWithResult 更新单个文档并返回结果
303
+func (f *MongoDBFactory) UpdateOneWithResult(collectionName string, filter interface{}, update interface{}) (*mongo.UpdateResult, bool) {
304
+	collection := f.GetCollection(collectionName)
305
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
306
+	defer cancel()
307
+
308
+	result, err := collection.UpdateOne(ctx, filter, update)
309
+	if err != nil {
310
+		logger.Errorf("更新文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
311
+		return nil, false
312
+	}
313
+	return result, true
314
+}
315
+
316
+// CountDocuments 统计文档数量,返回数量
317
+func (f *MongoDBFactory) CountDocuments(collectionName string, filter interface{}) (int64, error) {
318
+	collection := f.GetCollection(collectionName)
319
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
320
+	defer cancel()
321
+
322
+	count, err := collection.CountDocuments(ctx, filter)
323
+	if err != nil {
324
+		logger.Errorf("统计文档数量失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
325
+		return 0, err
326
+	}
327
+	return count, nil
328
+}
329
+
330
+// Aggregate 聚合查询,返回对象数组
331
+func (f *MongoDBFactory) Aggregate(collectionName string, pipeline interface{}, results interface{}) error {
332
+	collection := f.GetCollection(collectionName)
333
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
334
+	defer cancel()
335
+
336
+	cursor, err := collection.Aggregate(ctx, pipeline)
337
+	if err != nil {
338
+		logger.Errorf("聚合查询失败,集合:%s,管道:%v,错误:%v", collectionName, pipeline, err)
339
+		return err
340
+	}
341
+	defer cursor.Close(ctx)
342
+
343
+	if err = cursor.All(ctx, results); err != nil {
344
+		logger.Errorf("解码聚合结果失败,集合:%s,错误:%v", collectionName, err)
345
+		return err
346
+	}
347
+	return nil
348
+}
349
+
350
+// FindOneAndUpdate 查找并更新,返回更新后的文档
351
+func (f *MongoDBFactory) FindOneAndUpdate(collectionName string, filter interface{}, update interface{}, result interface{}) error {
352
+	collection := f.GetCollection(collectionName)
353
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
354
+	defer cancel()
355
+
356
+	err := collection.FindOneAndUpdate(ctx, filter, update).Decode(result)
357
+	if err != nil {
358
+		if err != mongo.ErrNoDocuments {
359
+			logger.Errorf("查找并更新失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
360
+		}
361
+		return err
362
+	}
363
+	return nil
364
+}
365
+
366
+// FindOneAndDelete 查找并删除,返回删除的文档
367
+func (f *MongoDBFactory) FindOneAndDelete(collectionName string, filter interface{}, result interface{}) error {
368
+	collection := f.GetCollection(collectionName)
369
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
370
+	defer cancel()
371
+
372
+	err := collection.FindOneAndDelete(ctx, filter).Decode(result)
373
+	if err != nil {
374
+		if err != mongo.ErrNoDocuments {
375
+			logger.Errorf("查找并删除失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
376
+		}
377
+		return err
378
+	}
379
+	return nil
380
+}
381
+
382
+// BulkWrite 批量写入操作,返回是否成功
383
+func (f *MongoDBFactory) BulkWrite(collectionName string, operations []mongo.WriteModel) bool {
384
+	collection := f.GetCollection(collectionName)
385
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
386
+	defer cancel()
387
+
388
+	_, err := collection.BulkWrite(ctx, operations)
389
+	if err != nil {
390
+		logger.Errorf("批量写入操作失败,集合:%s,错误:%v", collectionName, err)
391
+		return false
392
+	}
393
+	return true
394
+}
395
+
396
+// CreateIndex 创建索引,返回是否成功
397
+func (f *MongoDBFactory) CreateIndex(collectionName string, keys interface{}, opts ...*options.IndexOptions) bool {
398
+	collection := f.GetCollection(collectionName)
399
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
400
+	defer cancel()
401
+
402
+	indexModel := mongo.IndexModel{
403
+		Keys: keys,
404
+	}
405
+
406
+	if len(opts) > 0 && opts[0] != nil {
407
+		indexModel.Options = opts[0]
408
+	}
409
+
410
+	_, err := collection.Indexes().CreateOne(ctx, indexModel)
411
+	if err != nil {
412
+		logger.Errorf("创建索引失败,集合:%s,键:%v,错误:%v", collectionName, keys, err)
413
+		return false
414
+	}
415
+	return true
416
+}
417
+
418
+// FindWithPagination 分页查询,返回对象数组
419
+func (f *MongoDBFactory) FindWithPagination(
420
+	collectionName string,
421
+	filter interface{},
422
+	skip, limit int64,
423
+	sort interface{},
424
+	results interface{},
425
+) error {
426
+	//collection := f.GetCollection(collectionName)
427
+	//ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
428
+	//defer cancel()
429
+
430
+	findOptions := options.Find().
431
+		SetSkip(skip).
432
+		SetLimit(limit)
433
+
434
+	if sort != nil {
435
+		findOptions.SetSort(sort)
436
+	}
437
+
438
+	return f.Find(collectionName, filter, results, findOptions)
439
+}
440
+
441
+// FindOneByID 根据ID查询文档
442
+func (f *MongoDBFactory) FindOneByID(collectionName string, id interface{}, result interface{}) error {
443
+	return f.FindOne(collectionName, bson.M{"_id": id}, result)
444
+}
445
+
446
+// Exists 检查文档是否存在
447
+func (f *MongoDBFactory) Exists(collectionName string, filter interface{}) (bool, error) {
448
+	count, err := f.CountDocuments(collectionName, filter)
449
+	if err != nil {
450
+		return false, err
451
+	}
452
+	return count > 0, nil
453
+}
454
+
455
+// FindAndCount 查询文档并返回总数(用于分页场景)
456
+func (f *MongoDBFactory) FindAndCount(
457
+	collectionName string,
458
+	filter interface{},
459
+	skip, limit int64,
460
+	sort interface{},
461
+	results interface{},
462
+) (int64, error) {
463
+	// 查询数据
464
+	err := f.FindWithPagination(collectionName, filter, skip, limit, sort, results)
465
+	if err != nil {
466
+		return 0, err
467
+	}
468
+
469
+	// 查询总数
470
+	total, err := f.CountDocuments(collectionName, filter)
471
+	if err != nil {
472
+		return 0, err
473
+	}
474
+
475
+	return total, nil
476
+}
477
+
478
+// UpdateOne 更新单个文档,返回是否执行成功和影响记录数
479
+func (f *MongoDBFactory) UpdateOne(collectionName string, filter interface{}, update interface{}) (bool, int64) {
480
+	collection := f.GetCollection(collectionName)
481
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
482
+	defer cancel()
483
+
484
+	result, err := collection.UpdateOne(ctx, filter, update)
485
+	if err != nil {
486
+		logger.Errorf("更新文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
487
+		return false, 0
488
+	}
489
+
490
+	// 返回执行成功 和 实际更新的文档数
491
+	return true, result.ModifiedCount
492
+}
493
+
494
+// UpdateOneWithMatch 更新单个文档,只有匹配到文档才返回成功
495
+func (f *MongoDBFactory) UpdateOneWithMatch(collectionName string, filter interface{}, update interface{}) bool {
496
+	success, modifiedCount := f.UpdateOne(collectionName, filter, update)
497
+	return success && modifiedCount > 0
498
+}
499
+
500
+// UpdateMany 更新多个文档,返回是否执行成功和影响记录数
501
+func (f *MongoDBFactory) UpdateMany(collectionName string, filter interface{}, update interface{}) (bool, int64) {
502
+	collection := f.GetCollection(collectionName)
503
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
504
+	defer cancel()
505
+
506
+	result, err := collection.UpdateMany(ctx, filter, update)
507
+	if err != nil {
508
+		logger.Errorf("批量更新文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
509
+		return false, 0
510
+	}
511
+
512
+	return true, result.ModifiedCount
513
+}
514
+
515
+// DeleteOne 删除单个文档,返回是否执行成功和删除的记录数
516
+func (f *MongoDBFactory) DeleteOne(collectionName string, filter interface{}) (bool, int64) {
517
+	collection := f.GetCollection(collectionName)
518
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
519
+	defer cancel()
520
+
521
+	result, err := collection.DeleteOne(ctx, filter)
522
+	if err != nil {
523
+		logger.Errorf("删除文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
524
+		return false, 0
525
+	}
526
+
527
+	// 返回执行成功 和 实际删除的文档数
528
+	return true, result.DeletedCount
529
+}
530
+
531
+// DeleteOneWithMatch 删除单个文档,只有删除了文档才返回成功
532
+func (f *MongoDBFactory) DeleteOneWithMatch(collectionName string, filter interface{}) bool {
533
+	success, deletedCount := f.DeleteOne(collectionName, filter)
534
+	return success && deletedCount > 0
535
+}
536
+
537
+// DeleteMany 删除多个文档,返回是否执行成功和删除的记录数
538
+func (f *MongoDBFactory) DeleteMany(collectionName string, filter interface{}) (bool, int64) {
539
+	collection := f.GetCollection(collectionName)
540
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
541
+	defer cancel()
542
+
543
+	result, err := collection.DeleteMany(ctx, filter)
544
+	if err != nil {
545
+		logger.Errorf("批量删除文档失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
546
+		return false, 0
547
+	}
548
+
549
+	return true, result.DeletedCount
550
+}
551
+
552
+// UpsertOne 更新或插入文档(upsert操作)
553
+func (f *MongoDBFactory) UpsertOne(collectionName string, filter interface{}, update interface{}) (bool, interface{}) {
554
+	collection := f.GetCollection(collectionName)
555
+	ctx, cancel := context.WithTimeout(context.Background(), f.config.Timeout)
556
+	defer cancel()
557
+
558
+	// 设置 upsert 选项
559
+	opts := options.Update().SetUpsert(true)
560
+
561
+	result, err := collection.UpdateOne(ctx, filter, update, opts)
562
+	if err != nil {
563
+		logger.Errorf("Upsert操作失败,集合:%s,过滤条件:%v,错误:%v", collectionName, filter, err)
564
+		return false, result
565
+	}
566
+
567
+	// 返回: 成功状态, 匹配数, 修改数, 插入数
568
+	return true, result
569
+}
570
+
571
+// UpdateOneByID 根据ID更新文档
572
+func (f *MongoDBFactory) UpdateOneByID(collectionName string, id interface{}, update interface{}) (bool, int64) {
573
+	return f.UpdateOne(collectionName, bson.M{"_id": id}, update)
574
+}
575
+
576
+// UpdateOneByIDWithMatch 根据ID更新文档,只有匹配到才返回成功
577
+func (f *MongoDBFactory) UpdateOneByIDWithMatch(collectionName string, id interface{}, update interface{}) bool {
578
+	success, modifiedCount := f.UpdateOneByID(collectionName, id, update)
579
+	return success && modifiedCount > 0
580
+}
581
+
582
+// DeleteOneByID 根据ID删除文档
583
+func (f *MongoDBFactory) DeleteOneByID(collectionName string, id interface{}) (bool, int64) {
584
+	return f.DeleteOne(collectionName, bson.M{"_id": id})
585
+}
586
+
587
+// DeleteOneByIDWithMatch 根据ID删除文档,只有删除了才返回成功
588
+func (f *MongoDBFactory) DeleteOneByIDWithMatch(collectionName string, id interface{}) bool {
589
+	success, deletedCount := f.DeleteOneByID(collectionName, id)
590
+	return success && deletedCount > 0
591
+}

+ 2
- 6
factory/rabbitmq/rabbitmq_factory.go 파일 보기

@@ -20,11 +20,7 @@ type RabbitMQFactory struct {
20 20
 
21 21
 // NewRabbitMQFactory 创建RabbitMQ工厂
22 22
 func NewRabbitMQFactory() (*RabbitMQFactory, error) {
23
-	cfg, err := config.GetConfig()
24
-
25
-	if err != nil {
26
-		return nil, fmt.Errorf("failed to load config: %v", err)
27
-	}
23
+	cfg := config.GetConfig()
28 24
 
29 25
 	rabbitConfig := cfg.GetRabbitMQConfig()
30 26
 	if rabbitConfig.Host == "" || rabbitConfig.Port == 0 {
@@ -42,7 +38,7 @@ func NewRabbitMQFactory() (*RabbitMQFactory, error) {
42 38
 	// 简单的连接配置
43 39
 	mqConfig := amqp.Config{
44 40
 		Properties: amqp.Table{
45
-			"connection_name": cfg.GetService().InstanceName,
41
+			"connection_name": cfg.GetServiceConfig().InstanceName,
46 42
 		}}
47 43
 
48 44
 	// 建立连接

+ 11
- 11
factory/redis/redis_factory.go 파일 보기

@@ -10,7 +10,7 @@ import (
10 10
 	"github.com/go-redis/redis/v8"
11 11
 )
12 12
 
13
-var ctx = context.Background()
13
+var ctxRedis = context.Background()
14 14
 
15 15
 // RedisFactory Redis客户端工厂
16 16
 type RedisFactory struct {
@@ -20,7 +20,7 @@ type RedisFactory struct {
20 20
 // NewRedisFactory 创建Redis客户端工厂
21 21
 func NewRedisFactory() (*RedisFactory, error) {
22 22
 
23
-	cfg := config.GetRedis()
23
+	cfg := config.GetRedisConfig()
24 24
 
25 25
 	// 可以添加配置验证
26 26
 	if cfg == nil || cfg.Host == "" {
@@ -53,47 +53,47 @@ type RedisClient struct {
53 53
 
54 54
 // Set 写入字符串值
55 55
 func (c *RedisClient) Set(key string, value interface{}, expiration time.Duration) error {
56
-	return c.client.Set(ctx, key, value, expiration).Err()
56
+	return c.client.Set(ctxRedis, key, value, expiration).Err()
57 57
 }
58 58
 
59 59
 // Get 读取字符串值
60 60
 func (c *RedisClient) Get(key string) (string, error) {
61
-	return c.client.Get(ctx, key).Result()
61
+	return c.client.Get(ctxRedis, key).Result()
62 62
 }
63 63
 
64 64
 // HSet 写入哈希字段
65 65
 func (c *RedisClient) HSet(key string, values ...interface{}) error {
66
-	return c.client.HSet(ctx, key, values...).Err()
66
+	return c.client.HSet(ctxRedis, key, values...).Err()
67 67
 }
68 68
 
69 69
 // HGet 读取哈希字段
70 70
 func (c *RedisClient) HGet(key, field string) (string, error) {
71
-	return c.client.HGet(ctx, key, field).Result()
71
+	return c.client.HGet(ctxRedis, key, field).Result()
72 72
 }
73 73
 
74 74
 // HGetAll 读取整个哈希
75 75
 func (c *RedisClient) HGetAll(key string) (map[string]string, error) {
76
-	return c.client.HGetAll(ctx, key).Result()
76
+	return c.client.HGetAll(ctxRedis, key).Result()
77 77
 }
78 78
 
79 79
 // LPush 列表左推入
80 80
 func (c *RedisClient) LPush(key string, values ...interface{}) error {
81
-	return c.client.LPush(ctx, key, values...).Err()
81
+	return c.client.LPush(ctxRedis, key, values...).Err()
82 82
 }
83 83
 
84 84
 // RPop 列表右弹出
85 85
 func (c *RedisClient) RPop(key string) (string, error) {
86
-	return c.client.RPop(ctx, key).Result()
86
+	return c.client.RPop(ctxRedis, key).Result()
87 87
 }
88 88
 
89 89
 // Del 删除键
90 90
 func (c *RedisClient) Del(keys ...string) error {
91
-	return c.client.Del(ctx, keys...).Err()
91
+	return c.client.Del(ctxRedis, keys...).Err()
92 92
 }
93 93
 
94 94
 // Exists 检查键是否存在
95 95
 func (c *RedisClient) Exists(keys ...string) (int64, error) {
96
-	return c.client.Exists(ctx, keys...).Result()
96
+	return c.client.Exists(ctxRedis, keys...).Result()
97 97
 }
98 98
 
99 99
 // Close 关闭连接

+ 9
- 0
go.mod 파일 보기

@@ -14,7 +14,15 @@ require (
14 14
 require (
15 15
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
16 16
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
17
+	github.com/golang/snappy v0.0.4 // indirect
18
+	github.com/klauspost/compress v1.16.7 // indirect
19
+	github.com/montanaflynn/stats v0.7.1 // indirect
20
+	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
21
+	github.com/xdg-go/scram v1.1.2 // indirect
22
+	github.com/xdg-go/stringprep v1.0.4 // indirect
23
+	github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
17 24
 	golang.org/x/net v0.47.0 // indirect
25
+	golang.org/x/sync v0.18.0 // indirect
18 26
 	gopkg.in/yaml.v2 v2.4.0 // indirect
19 27
 )
20 28
 
@@ -27,6 +35,7 @@ require (
27 35
 	github.com/google/uuid v1.6.0 // indirect
28 36
 	github.com/jmoiron/sqlx v1.4.0
29 37
 	github.com/streadway/amqp v1.1.0
38
+	go.mongodb.org/mongo-driver v1.17.6
30 39
 	golang.org/x/crypto v0.45.0 // indirect
31 40
 	golang.org/x/text v0.31.0 // indirect
32 41
 )

+ 43
- 0
go.sum 파일 보기

@@ -1,5 +1,6 @@
1 1
 filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
2 2
 filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
3
+git.x2erp.com/qdy/go-base v0.1.51/go.mod h1:IYkjIY0xiqPKIOBojsR9miER2ceyly6+iwv4Zd64OT0=
3 4
 git.x2erp.com/qdy/go-base v0.1.60 h1:eGexgp8fUNMBmecpR7pelNsvr8ujYFZf1phLNFlGjVE=
4 5
 git.x2erp.com/qdy/go-base v0.1.60/go.mod h1:IYkjIY0xiqPKIOBojsR9miER2ceyly6+iwv4Zd64OT0=
5 6
 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U=
@@ -35,10 +36,14 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt
35 36
 github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
36 37
 github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
37 38
 github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
39
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
40
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
38 41
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
39 42
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
40 43
 github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
41 44
 github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
45
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
46
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
42 47
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
43 48
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
44 49
 github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
@@ -47,6 +52,8 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o
47 52
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
48 53
 github.com/microsoft/go-mssqldb v1.9.4 h1:sHrj3GcdgkxytZ09aZ3+ys72pMeyEXJowT44j74pNgs=
49 54
 github.com/microsoft/go-mssqldb v1.9.4/go.mod h1:GBbW9ASTiDC+mpgWDGKdm3FnFLTUsLYN3iFL90lQ+PA=
55
+github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
56
+github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
50 57
 github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
51 58
 github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
52 59
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
@@ -63,16 +70,52 @@ github.com/streadway/amqp v1.1.0 h1:py12iX8XSyI7aN/3dUT8DFIDJazNJsVJdxNVEpnQTZM=
63 70
 github.com/streadway/amqp v1.1.0/go.mod h1:WYSrTEYHOXHd0nwFeUXAe2G2hRnQT+deZJJf88uS9Bg=
64 71
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
65 72
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
73
+github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
74
+github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
75
+github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
76
+github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
77
+github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
78
+github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
79
+github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
80
+github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
81
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
82
+go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
83
+go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
84
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
85
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
66 86
 golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
67 87
 golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
88
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
89
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
90
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
91
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
68 92
 golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
69 93
 golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
94
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
95
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
96
+golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
97
+golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
98
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
99
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
100
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
101
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
102
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
70 103
 golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
71 104
 golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
105
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
106
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
107
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
108
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
109
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
110
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
72 111
 golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
73 112
 golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
74 113
 golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
75 114
 golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
115
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
116
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
117
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
118
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
76 119
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
77 120
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
78 121
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=

+ 12
- 23
test.go 파일 보기

@@ -2,44 +2,33 @@ package main
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"log"
6 5
 
7 6
 	"git.x2erp.com/qdy/go-base/config"
7
+	"git.x2erp.com/qdy/go-base/container"
8 8
 	"git.x2erp.com/qdy/go-db/factory/database"
9 9
 )
10 10
 
11 11
 func main() {
12 12
 
13 13
 	// 显示当前使用的数据库配置
14
-	config, err := config.GetConfig()
15
-	if err != nil {
16
-		log.Fatalf("failed to load config: %v", err)
14
+	config := config.GetConfig()
17 15
 
18
-		return
19
-	}
16
+	ctr := container.NewContainer(config)
20 17
 
21
-	dbConfig := config.GetDatabase() // 通过接口方法获取数据库配置
22
-	fmt.Printf("Using database type: %s\n", dbConfig.Type)
23
-	fmt.Printf("Database host: %s:%d\n", dbConfig.Host, dbConfig.Port)
24
-	fmt.Printf("Database name: %s\n", dbConfig.Database)
18
+	dbFactory := container.Create(ctr, database.CreateDBFactory)
25 19
 
20
+	dbFactory.TestConnection()
26 21
 	// 创建数据库工厂
27 22
 	fmt.Printf("第1次.\n")
28
-	dbFactory, err := database.GetDefaultDBFactory()
29 23
 
30
-	if err != nil {
31
-		log.Fatalf("Failed to create DB factory: %v", err)
32
-	}
24
+	dbFactory1 := database.CreateDBFactory(config)
25
+
26
+	dbFactory1.TestConnection()
33 27
 
34
-	//测试单例是否生效
35 28
 	fmt.Printf("第2次.\n")
36
-	dbFactory1, err1 := database.GetDefaultDBFactory()
37
-
38
-	if err1 != nil {
39
-		log.Fatalf("Failed to create DB factory: %v", err1)
40
-	}
41
-	dbFactory1.TestConnection(dbConfig.Type)
42
-	defer dbFactory.Close()
43
-	defer dbFactory1.Close()
29
+	dbFactory2 := container.Create(ctr, database.CreateDBFactory)
30
+
31
+	dbFactory2.TestConnection()
32
+	defer ctr.CloseAll()
44 33
 
45 34
 }

Loading…
취소
저장