封裝原因:
- 查看了很多網上提供的ORM類型的數據庫操作,覺得比較麻煩,需要提前配置很多的表結構體,然後才能使用,對於數據表很多的項目就配置起來就比較麻煩,所以對golang的mysql包進行了外層包裝,簡化在開發中的使用.
實現思路:
- 通過配置數據庫鏈接,初始化連接(實現連接池),設置連接池參數,並存入map[string]*sql.DB中,在需要時調用.
- 使用Struct方法,對SQL進行預處理,然後執行相應的SQL,獲取數據
配置數據庫鏈接
- 例如我配置了三個數據庫的鏈接,分別是cms庫, base庫和sms庫,配置代碼如下
package config
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
)
var (
WorkDir string // 項目的根目錄
DBConfig map[string]string // 數據庫參數配置
)
// 初始化解析Env配置文件
func init() {
// 需要編譯後才能生效
WorkDir = filepath.Dir(os.Args[0])
err := os.Setenv("GOPATH", WorkDir)
data, err := ioutil.ReadFile(path.Join(WorkDir, ".env"))
if err != nil {
log.Fatal(err)
}
result := make(map[string]string)
// 把uint8形式轉換爲map類型數據
// []byte(data) 對字節數組轉換成byte類型數據
err = json.Unmarshal([]byte(data), &result)
if err != nil {
log.Fatal(err)
}
// 數據庫配置map
dBMap := make(map[string]string)
// 格式化數據庫鏈接
CmsConnect := fmt.Sprintf("%s:%s@tcp(%s:%s)/cms?charset=utf8mb4", result["DB_CMS_USER"],
result["DB_CMS_PASS"], result["DB_CMS_HOST"], result["DB_CMS_PORT"])
BaseConnect := fmt.Sprintf("%s:%s@tcp(%s:%s)/base?charset=utf8mb4", result["DB_BASE_USER"],
result["DB_BASE_PASS"], result["DB_BASE_HOST"], result["DB_BASE_PORT"])
SmsConnect := fmt.Sprintf("%s:%s@tcp(%s:%s)/sms?charset=utf8mb4", result["DB_SMS_USER"],
result["DB_SMS_PASS"], result["DB_SMS_HOST"], result["DB_SMS_PORT"])
dBMap["cms"], dBMap["base"], dBMap["sms"] = CmsConnect, BaseConnect, SmsConnect
DBConfig = dBMap
}
使用方法
- 創建-Create方法, 接收參數類型爲map[string]interface{}
(1).map中key即爲數據表的對應的字段名稱,value即爲對應要創建的數據字段值
(2).返回結果爲新增數據在表中的ID和error信息,新增成功error爲nil
import . "mysqldb"
# 例如我想base庫的auth_user表添加一條記錄,創建的三個字段爲手機號phone,姓名real_name,性別sex
createMap := make(map[string]interface{})
createMap["phone"], createMap["name"], createMap["sex"] = "18300000000", "張三", 1
insertId, err := DB("base").Table("auth_user").Create(createMap)
- 批量創建-BulkCreate方法,接收參數類型爲[]map[string]interface{}
(1).返回結果爲影響的行數和error信息,新增成功error爲nil
# 例如我想base庫的auth_user表添加兩條記錄,創建的三個字段爲手機號phone,姓名real_name,性別sex
var createMap []map[string]interface{}
cMap := make(map[string]interface{})
cMap["phone"], cMap["name"], cMap["sex"] = "18300000000", "張三", 1
createMap = append(createMap, cMap)
cMap["phone"], cMap["name"], cMap["sex"] = "18300000001", "李梅", 2
createMap = append(createMap, cMap)
insertId, err := DB("base").Table("auth_user").BulkCreate(createMap)
- 刪除-Delete方法
(1). 通過Filter設置篩選條件
(2).返回結果爲影響的行數和error信息,刪除成功error爲nil
# 例如我想刪除base庫的auth_user表中phone爲1830000000的記錄
affectRows, err :=DB("base").Table("auth_user").Filter("phone=?", "18300000000").Delete()
- 更新-Update方法,接收參數類型爲map[string]interface{}
(1). 通過Filter設置篩選條件
(2).返回結果爲影響的行數和error信息,更新成功error爲nil
# 例如我要更新base庫的auth_user表中phone爲18300000000數據的姓名爲李四
createMap := make(map[string]interface{})
createMap["phone"], createMap["name"], createMap["sex"] = "18300000000", "李四", 1
affectRows, err := DB("base").Table("auth_user").Filter("phone=?", "18300000000").Update(createMap)
- 查詢
(1). 單條數據獲取爲Get,獲取查詢到的第一條數據,返回結果類型爲map[string]interface{}
(2). 獲取所有數據爲All, 返回結果類型爲[]map[string]interface{}
# 例如我要獲取base庫auth_user表中phone爲18300000000的一條記錄
userData := DB("base").Table("auth_user").Filter("phone=?", "18300000000").Get()
# 例如我要獲取base庫auth_user表中phone爲18300000000的所有記錄
userData := DB("base").Table("auth_user").Filter("phone=?", "18300000000").All()
# 例如我要獲取base庫auth_user表中phone爲18300000000按照ID降序一條記錄
userData := DB("base").Table("auth_user").Filter("phone=?", "18300000000").OrderBy("-id").Get()
# 例如我要獲取base庫auth_user表中phone爲18300000000,sex爲1的一條記錄
userData := DB("base").Table("auth_user").Filter("phone=? AND sex=?", "18300000000", 1).Get()
# 例如我要獲取base庫auth_user表中每個手機號爲的統計數據
userData := DB("base").Table("auth_user").Select("phone", "COUNT(1) AS num").Filter("sex=?", 1).GroupBy("phone").All()
其他方法說明
- Execute, 執行一條SQL,返回影響的行數和error信息.error爲nil,表示執行成功
- FetchOne, 執行一條SQL返回一條數據結果,返回結果類型爲: map[string]interface{}
- FetchAll, 執行一條SQL,返回多條數據結果,返回結果類型爲: []map[string]interface{}
未實現方法
- 多表關聯查詢,建議通過書寫原生SQL,然後使用FetchOne或FetchAll方法執行獲取數據
源代碼地址