mysqlapi.go 8.4 KB

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