db_base.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package base
  2. import (
  3. "fmt"
  4. "gorm.io/gorm"
  5. "math"
  6. )
  7. type Pagination struct {
  8. Current int `json:"current" query:"current" form:"current" ` //当前页
  9. PageSize int `json:"pageSize" query:"pageSize" form:"pageSize" ` //每页条数
  10. Total int64 `json:"total" query:"total" form:"total" ` //总条数
  11. Count int `json:"count" query:"count" form:"count" ` //总页数
  12. StartNums int `json:"startNums" query:"startNums" form:"startNums" ` //起始条数
  13. }
  14. func NewPagination() *Pagination {
  15. return &Pagination{}
  16. }
  17. func InitPaging(p, s int) *Pagination {
  18. return &Pagination{Current: p, PageSize: s}
  19. }
  20. func (p *Pagination) Computer() {
  21. if p.Current < 1 {
  22. p.Current = 1
  23. }
  24. if p.PageSize < 1 {
  25. p.PageSize = 10
  26. }
  27. p.StartNums = p.PageSize * (p.Current - 1)
  28. count := math.Ceil(float64(p.Total) / float64(p.PageSize))
  29. p.Count = int(count)
  30. }
  31. // 获取单条记录
  32. func GetOne[T any](db *gorm.DB, args ...interface{}) (*T, bool) {
  33. db = buildEqualDB(db, args...)
  34. r := new(T)
  35. if err := db.First(&r).Error; err != nil {
  36. return r, false
  37. }
  38. return r, true
  39. }
  40. func GetLast[T any](db *gorm.DB, args ...interface{}) (*T, bool) {
  41. db = buildEqualDB(db, args...)
  42. r := new(T)
  43. if err := db.Last(&r).Error; err != nil {
  44. return r, false
  45. }
  46. return r, true
  47. }
  48. // 统计条数
  49. func CountRow[T any](db *gorm.DB, args ...interface{}) int64 {
  50. db = buildEqualDB(db, args...)
  51. r := new(T)
  52. var total int64 = 0
  53. db.Model(&r).Count(&total)
  54. return total
  55. }
  56. // 获取所有数据 -- 一次性获取所有 -- 对于已知数量不多的情况下使用
  57. func GetMore[T any](db *gorm.DB, args ...interface{}) ([]*T, error) {
  58. db = buildEqualDB(db, args...)
  59. res := make([]*T, 0)
  60. var total int64
  61. err := db.Model(&res).Count(&total).Error
  62. if err != nil {
  63. return res, err
  64. }
  65. if total == 0 {
  66. return res, nil
  67. }
  68. if err := db.Find(&res).Error; err != nil {
  69. return res, err
  70. }
  71. return res, nil
  72. }
  73. // 分页查询 -- 分页查询
  74. func GetMoreWithPage[T any](db *gorm.DB, paging *Pagination, args ...interface{}) ([]*T, *Pagination, error) {
  75. if paging == nil {
  76. paging = InitPaging(1, 10)
  77. }
  78. db = buildEqualDB(db, args...)
  79. res := make([]*T, 0)
  80. err := db.Model(&res).Count(&paging.Total).Error
  81. if err != nil {
  82. return res, paging, err
  83. }
  84. paging.Computer()
  85. if paging.Total == 0 {
  86. return res, paging, nil
  87. }
  88. err = db.Model(&res).Limit(paging.PageSize).Offset(paging.StartNums).Find(&res).Error
  89. return res, paging, err
  90. }
  91. // 批量分页查询
  92. func getRowsWithPage[T any](db *gorm.DB, paging *Pagination) ([]*T, error) {
  93. paging.Computer()
  94. res := make([]*T, 0)
  95. err := db.Model(&res).Limit(paging.PageSize).Offset(paging.StartNums).Find(&res).Error
  96. return res, err
  97. }
  98. const BatchPageSize = 5000
  99. func ObtainAllRowsInBatches[T any](db *gorm.DB) ([]*T, error) {
  100. count := CountRow[T](db)
  101. // 分页循环读取用户数据
  102. list := make([]*T, 0, count)
  103. paging := &Pagination{
  104. PageSize: BatchPageSize,
  105. Total: count,
  106. }
  107. paging.Computer()
  108. if count > 0 {
  109. for i := 0; i < paging.Count; i++ {
  110. items, err := getRowsWithPage[T](db, &Pagination{
  111. PageSize: BatchPageSize,
  112. Current: i + 1,
  113. Total: count,
  114. })
  115. if err != nil {
  116. return nil, err
  117. }
  118. list = append(list, items...) // 直接追加整个切片
  119. }
  120. }
  121. return list, nil
  122. }
  123. // 构建查询
  124. func buildEqualDB(db *gorm.DB, args ...interface{}) *gorm.DB {
  125. tms := len(args) / 2
  126. if tms > 0 {
  127. for i := 0; i < tms; i++ {
  128. db = db.Where(fmt.Sprintf("%s = ?", args[i*2]), args[i*2+1])
  129. }
  130. }
  131. return db
  132. }
  133. const QueryPageSize int64 = 100000 // 批量查询数据最大条数