• go gorm select * 优化


    很多时候sql查询都不允许select * 出现要求指定列名,如果你是用gormv2 ,恭喜你可以使用QueryFields属性,如果是gormv1版本怎么样,难道要升级gormV2吗,这里提供种反射的实现,可能不是最优解,但只是一个方案。

    首先mysq建一个表

    1. CREATE TABLE `test` (
    2. `id` BIGINT(20) NOT NULL,
    3. `name` VARCHAR(5) DEFAULT NULL,
    4. `age` INT(11) DEFAULT NULL,
    5. PRIMARY KEY (`id`)
    6. ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4

    go的代码如下:

    1. package main
    2. import (
    3. "fmt"
    4. "gorm.io/driver/mysql"
    5. "gorm.io/gorm/logger"
    6. "gorm.io/gorm/schema"
    7. "reflect"
    8. "strings"
    9. _ "github.com/go-sql-driver/mysql"
    10. "gorm.io/gorm"
    11. )
    12. func main() {
    13. dns := "root:root@tcp(192.168.100.30:3306)/demo?charset=utf8&parseTime=True&loc=Local"
    14. config := &gorm.Config{
    15. NamingStrategy: schema.NamingStrategy{
    16. SingularTable: true,
    17. },
    18. //QueryFields: true,
    19. Logger: logger.Default.LogMode(logger.Info),
    20. }
    21. db, err := gorm.Open(mysql.Open(dns), config)
    22. if err != nil {
    23. fmt.Println(fmt.Sprintf("Open err:%v", err))
    24. }
    25. var ret []*Test
    26. //一般查询
    27. fmt.Println("一般查询")
    28. err = db.Table("test").Where("id>1").Find(&ret).Debug().Error
    29. if err != nil {
    30. fmt.Println(fmt.Sprintf("select err:%v", err))
    31. }
    32. //通过反射指定列
    33. fmt.Println("通过反射指定列")
    34. err = db.Table("test").Where("id>1").Select(GetAllFields(new(Test))).Find(&ret).Debug().Error
    35. if err != nil {
    36. fmt.Println(fmt.Sprintf("select err:%v", err))
    37. }
    38. //通过QueryFields 指定列
    39. fmt.Println("通过QueryFields 指定列")
    40. tx := db.Table("test")
    41. tx.QueryFields = true
    42. err = tx.Where("id>1").Find(&ret).Debug().Error
    43. if err != nil {
    44. fmt.Println(fmt.Sprintf("select err:%v", err))
    45. }
    46. }
    47. type Test struct {
    48. ID int64 `gorm:"type:bigint(20);column:id;primary_key"`
    49. Name string `gorm:"type:varchar(5);column:name"`
    50. Age int `gorm:"type:int(11);column:age"`
    51. }
    52. func GetAllFields(info interface{}) string {
    53. tagName := strings.ToUpper("column")
    54. var arr []string
    55. el := reflect.TypeOf(info).Elem()
    56. for i := 0; i < el.NumField(); i++ {
    57. structTag := el.Field(i).Tag
    58. tags := parseTagSetting(structTag)
    59. if columnName, ok := tags[tagName]; ok && columnName != "-" {
    60. arr = append(arr, columnName)
    61. }
    62. }
    63. sqlFields := "`" + strings.Join(arr, "`,`") + "`"
    64. return sqlFields
    65. }
    66. func parseTagSetting(tags reflect.StructTag) map[string]string {
    67. setting := map[string]string{}
    68. for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} {
    69. if str == "" {
    70. continue
    71. }
    72. tags := strings.Split(str, ";")
    73. for _, value := range tags {
    74. v := strings.Split(value, ":")
    75. k := strings.TrimSpace(strings.ToUpper(v[0]))
    76. if len(v) >= 2 {
    77. setting[k] = strings.Join(v[1:], ":")
    78. } else {
    79. setting[k] = k
    80. }
    81. }
    82. }
    83. return setting
    84. }

    运行结果:

     

  • 相关阅读:
    Socket 编程
    MySQL-内置函数
    动力电池UL2580测试项目包括哪些
    第十三届蓝桥杯(C/C++ 大学B组)
    收集 VSCode 常用快捷键
    python 多项式回归以及可视化
    重要的 SQL Server 函数 - 日期函数
    闲人闲谈PS之三十四——项目成本费用控制阈值
    [附源码]计算机毕业设计JAVA“拥抱爱心”公益网站管理系统
    JavaWeb项目(三)
  • 原文地址:https://blog.csdn.net/dz45693/article/details/126904653