mysqlapi.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // 数据库底层操作接口
  2. // 秒寻科技
  3. // zt 2024-01-04
  4. package mysqlapi
  5. import (
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "ipsomc/core/dao/mysql/mysqlmodel"
  10. "ipsomc/util"
  11. "reflect"
  12. "strings"
  13. "time"
  14. "github.com/jinzhu/gorm"
  15. _ "github.com/jinzhu/gorm/dialects/mysql"
  16. )
  17. type MySqlApi struct {
  18. }
  19. // 全局数据库操作对象
  20. var (
  21. Db *gorm.DB
  22. )
  23. // 初始化数据库模块,创建一个数据连接对象
  24. func OpenSqlDb() error {
  25. var err error
  26. myViper := util.GetViper()
  27. dbHostAddress := myViper.GetString("dbDefault.dbHost") //主机地址
  28. dbHostPort := myViper.GetString("dbDefault.dbPort") //主机端口
  29. dbName := myViper.GetString("dbDefault.dbName") //数据库名
  30. dbUser := myViper.GetString("dbDefault.dbUser") //数据库用户名
  31. dbPassword := myViper.GetString("dbDefault.dbPassword") //数据库用户登录密码
  32. //组织dsn字符串
  33. dsn := dbUser + ":" + dbPassword + "@tcp(" + dbHostAddress + ":" + dbHostPort + ")/" + dbName + "?charset=utf8mb4&parseTime=True&loc=Local"
  34. //连接数据库
  35. for Db, err = gorm.Open("mysql", dsn); err != nil; {
  36. fmt.Println("连接数据库异常,之后自动重连")
  37. time.Sleep(5 * time.Second)
  38. Db, err = gorm.Open("mysql", dsn)
  39. }
  40. Db.LogMode(true) //打开日志开关
  41. Db.SingularTable(true) //禁用数据库表名复数
  42. TimerConnectSqlDb(Db) //5秒定时连接数据库,以免连接断开
  43. return nil
  44. }
  45. // CloseDb 关闭数据
  46. func CloseSqlDb() {
  47. Db.Close() //关闭数据
  48. }
  49. // GetDb 返回当前db对象
  50. func (obj *MySqlApi) GetDb() *gorm.DB {
  51. return Db
  52. }
  53. // 创建数据库表,不会删除和修改数据库中的数据,只增加新新的表字段
  54. func (obj *MySqlApi) GenerateDbTable(dataModel interface{}) {
  55. Db.AutoMigrate(dataModel)
  56. }
  57. // TimerConnectSqlDb 定时连接数据库
  58. func TimerConnectSqlDb(db *gorm.DB) {
  59. go func() {
  60. myTiker := time.NewTicker(30 * time.Second)
  61. for range myTiker.C {
  62. var dtTime time.Time
  63. if err := db.Raw("select now() as time").Scan(&dtTime).Error; err != nil {
  64. fmt.Println(err)
  65. }
  66. }
  67. }()
  68. }
  69. // AddItem 增加数据库记录
  70. func (obj *MySqlApi) AddItem(dataModel interface{}) error {
  71. if err := Db.Create(dataModel).Error; err != nil {
  72. return err
  73. }
  74. return nil
  75. }
  76. // UpdateItem 更新记录
  77. func (obj *MySqlApi) UpdateItem(dataModel interface{}, dataMap map[string]interface{}) error {
  78. val := reflect.ValueOf(dataModel)
  79. if val.Kind() != reflect.Ptr {
  80. return errors.New("更新失败,函数参数检查错误,应为指针类型")
  81. }
  82. val = val.Elem()
  83. if val.Kind() != reflect.Struct {
  84. return errors.New("更新失败,函数参数检查错误,应为结构体指针类型")
  85. }
  86. id := val.FieldByName("ID").Int()
  87. if id == 0 {
  88. return errors.New("更新失败,请设置要更新的数据的ID值")
  89. }
  90. //更新数据
  91. if err := Db.Model(dataModel).Updates(dataMap).Error; err != nil {
  92. return err
  93. }
  94. return nil
  95. }
  96. // DeleteItem 删除记录
  97. func (obj *MySqlApi) DeleteItem(dataModel interface{}) error {
  98. val := reflect.ValueOf(dataModel)
  99. if val.Kind() != reflect.Ptr {
  100. return errors.New("删除失败,函数参数检查错误,应为指针类型")
  101. }
  102. val = val.Elem()
  103. if val.Kind() != reflect.Struct {
  104. return errors.New("删除失败,函数参数检查错误,应为结构体指针类型")
  105. }
  106. id := val.FieldByName("ID").Int()
  107. if id == 0 {
  108. return errors.New("删除失败,请设置要删除的数据的ID值")
  109. }
  110. if err := Db.Where("owner_id <> 0").Delete(dataModel).Error; err != nil {
  111. return err
  112. }
  113. return nil
  114. }
  115. // GetItemByID 根据id获得记录数据
  116. func (obj *MySqlApi) GetItemByID(dataModel interface{}) error {
  117. val := reflect.ValueOf(dataModel)
  118. if val.Kind() != reflect.Ptr {
  119. return errors.New("查询数据失败,函数参数检查错误,应为指针类型")
  120. }
  121. val = val.Elem()
  122. if val.Kind() != reflect.Struct {
  123. return errors.New("查询数据失败,函数参数检查错误,应为结构体指针类型")
  124. }
  125. id := val.FieldByName("ID").Int()
  126. if id == 0 {
  127. return errors.New("查询数据失败,请设置要查询的数据的ID值")
  128. }
  129. if err := Db.First(dataModel).Error; err != nil {
  130. return err
  131. }
  132. return nil
  133. }
  134. // 组织公司参数(公司ID和项目ID)
  135. func (obj *MySqlApi) GenerateCompanyParam(db *gorm.DB, companyId int, projectId int) *gorm.DB {
  136. if companyId > 0 {
  137. db = db.Where("company_id=?", companyId)
  138. }
  139. if projectId > 0 {
  140. db = db.Where("project_id=?", projectId)
  141. }
  142. return db
  143. }
  144. // 组织search参数
  145. func (obj *MySqlApi) GenerateSearchParam(db *gorm.DB, searchParam map[string]interface{}, dataMap map[string]interface{}) *gorm.DB {
  146. //组织Search参数
  147. for queryKey, value := range searchParam {
  148. queryKey = strings.ToLower(queryKey)
  149. for mapKey := range dataMap {
  150. mapKey = strings.ToLower(mapKey)
  151. if mapKey == queryKey {
  152. db = db.Where(queryKey+"=?", value)
  153. }
  154. }
  155. }
  156. return db
  157. }
  158. // 组织Query参数
  159. func (obj *MySqlApi) GenerateQueryParam(db *gorm.DB, queryParam []mysqlmodel.QueryParam, dataMap map[string]interface{}) *gorm.DB {
  160. wLen := len(queryParam)
  161. for i := 0; i < wLen; i++ {
  162. obj := queryParam[i]
  163. for mapKey := range dataMap {
  164. mapKey = strings.ToLower(mapKey)
  165. queryKey := strings.ToLower(obj.Key)
  166. if mapKey == queryKey {
  167. if obj.Opt == "like" {
  168. db = db.Where(queryKey+" like ?", fmt.Sprintf("%v", obj.Data)) //%通配在前端处理
  169. } else if obj.Opt == "in" {
  170. db = db.Where(queryKey+" in (?)", obj.Data)
  171. } else {
  172. db = db.Where(queryKey+obj.Opt+"?", obj.Data)
  173. }
  174. }
  175. }
  176. }
  177. return db
  178. }
  179. // 组织Order参数
  180. func (obj *MySqlApi) GenerateOrderParam(db *gorm.DB, orderBy string) *gorm.DB {
  181. strOrderBy := orderBy
  182. if len(strOrderBy) > 0 {
  183. orderList := strings.Split(strOrderBy, ",")
  184. for _, item := range orderList {
  185. db = db.Order(item)
  186. }
  187. } else {
  188. db = db.Order("id") //默认按照ID排序
  189. }
  190. return db
  191. }
  192. // 组织查询条件where参数
  193. func (obj *MySqlApi) GenerateWhereParam(dataModel interface{}, companyId int, projectId int, searchParam map[string]interface{}, queryParam []mysqlmodel.QueryParam, orderParam string) *gorm.DB {
  194. //空接口转map,以便判断查询字段是否在模型
  195. dataMap := make(map[string]interface{})
  196. byteList, _ := json.Marshal(dataModel)
  197. json.Unmarshal(byteList, &dataMap)
  198. db := obj.GetDb()
  199. db = obj.GenerateCompanyParam(db, companyId, projectId) //组织公司ID参数
  200. db = obj.GenerateSearchParam(db, searchParam, dataMap) //组织Search参数
  201. db = obj.GenerateQueryParam(db, queryParam, dataMap) //组织query参数
  202. db = obj.GenerateOrderParam(db, orderParam) //组织排序参数
  203. return db
  204. }
  205. // 查询
  206. func (obj *MySqlApi) GetItemList(dataModel interface{}, listParam *mysqlmodel.ListParam, dataList interface{}) error {
  207. val := reflect.ValueOf(dataModel)
  208. if val.Kind() != reflect.Ptr {
  209. return errors.New("查询数据失败,函数参数检查错误,应为指针类型")
  210. }
  211. val = val.Elem()
  212. if val.Kind() != reflect.Struct {
  213. return errors.New("查询数据失败,函数参数检查错误,应为结构体指针类型")
  214. }
  215. //组织查询条件
  216. db := obj.GenerateWhereParam(dataModel, listParam.CompanyID, listParam.ProjectID, listParam.Search, listParam.Query, listParam.OrderBy)
  217. //查询数据
  218. if err := db.Find(dataList).Error; err != nil {
  219. return errors.New("查询数据失败")
  220. }
  221. return nil
  222. }
  223. // 分页查询
  224. func (obj *MySqlApi) GetPageItemList(dataModel interface{}, listParam *mysqlmodel.PageListParam, dataList interface{}) (mysqlmodel.PageListData, error) {
  225. pageListData := mysqlmodel.PageListData{}
  226. pageListData.PageNum = listParam.PageNum
  227. pageListData.PageSize = listParam.PageSize
  228. offset := (listParam.PageNum - 1) * listParam.PageSize
  229. pageSize := listParam.PageSize
  230. //组织查询条件
  231. db := obj.GenerateWhereParam(dataModel, listParam.CompanyID, listParam.ProjectID, listParam.Search, listParam.Query, listParam.OrderBy)
  232. //获得分页数据
  233. if err := db.Limit(pageSize).Offset(offset).Find(dataList).Error; err != nil {
  234. return pageListData, err
  235. }
  236. pageListData.Items = dataList
  237. //计算总记录数
  238. value := reflect.ValueOf(dataList).Elem()
  239. if listParam.PageNum == 1 && value.Len() < listParam.PageSize { //记录数不足一页
  240. pageListData.TotalCount = value.Len()
  241. } else {
  242. db.Model(dataModel).Count(&pageListData.TotalCount)
  243. }
  244. return pageListData, nil
  245. }