ZBLOG

golang 根据Postgers 数据库表生成动态结构体

可以使用反射来实现根据PostgreSQL数据库表动态生成结构体。

首先需要连接到PostgreSQL数据库并查询表结构信息,可以使用”information_schema.columns”表来获取表名、列名、数据类型等信息:

  1. db, err := sql.Open("postgres", "user=postgres password=123456 dbname=mydb sslmode=disable")
  2. if err != nil {
  3. log.Fatal(err)
  4. }
  5. defer db.Close()
  6. rows, err := db.Query("SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_name = 'mytable'")
  7. if err != nil {
  8. log.Fatal(err)
  9. }
  10. defer rows.Close()

接下来,可以通过遍历查询结果的方式动态生成结构体,并设置结构体的字段名和类型:

  1. // 定义结构体类型
  2. type MyTable struct {
  3. Column1 string
  4. Column2 int
  5. Column3 float64
  6. }
  7. // 动态生成结构体
  8. columns := make(map[string]string)
  9. for rows.Next() {
  10. var tableName, columnName, dataType string
  11. if err := rows.Scan(&tableName, &columnName, &dataType); err != nil {
  12. log.Fatal(err)
  13. }
  14. columns[columnName] = dataType
  15. }
  16. fields := make([]reflect.StructField, len(columns))
  17. i := 0
  18. for columnName, dataType := range columns {
  19. // 根据数据类型设置结构体字段类型
  20. var fieldType reflect.Type
  21. switch dataType {
  22. case "text":
  23. fieldType = reflect.TypeOf("")
  24. case "integer":
  25. fieldType = reflect.TypeOf(0)
  26. case "numeric":
  27. fieldType = reflect.TypeOf(float64(0))
  28. default:
  29. log.Fatalf("unknown data type: %s", dataType)
  30. }
  31. fields[i] = reflect.StructField{
  32. Name: strings.Title(columnName),
  33. Type: fieldType,
  34. }
  35. i++
  36. }
  37. myTableType := reflect.StructOf(fields)

最后,可以使用反射创建一个新的结构体实例:

  1. myTable := reflect.New(myTableType).Elem().Interface()

完整代码示例:

  1. package main
  2. import (
  3. "database/sql"
  4. "log"
  5. "reflect"
  6. "strings"
  7. _ "github.com/lib/pq"
  8. )
  9. func main() {
  10. db, err := sql.Open("postgres", "user=postgres password=123456 dbname=mydb sslmode=disable")
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. defer db.Close()
  15. rows, err := db.Query("SELECT table_name, column_name, data_type FROM information_schema.columns WHERE table_name = 'mytable'")
  16. if err != nil {
  17. log.Fatal(err)
  18. }
  19. defer rows.Close()
  20. columns := make(map[string]string)
  21. for rows.Next() {
  22. var tableName, columnName, dataType string
  23. if err := rows.Scan(&tableName, &columnName, &dataType); err != nil {
  24. log.Fatal(err)
  25. }
  26. columns[columnName] = dataType
  27. }
  28. fields := make([]reflect.StructField, len(columns))
  29. i := 0
  30. for columnName, dataType := range columns {
  31. var fieldType reflect.Type
  32. switch dataType {
  33. case "text":
  34. fieldType = reflect.TypeOf("")
  35. case "integer":
  36. fieldType = reflect.TypeOf(0)
  37. case "numeric":
  38. fieldType = reflect.TypeOf(float64(0))
  39. default:
  40. log.Fatalf("unknown data type: %s", dataType)
  41. }
  42. fields[i] = reflect.StructField{
  43. Name: strings.Title(columnName),
  44. Type: fieldType,
  45. }
  46. i++
  47. }
  48. myTableType := reflect.StructOf(fields)
  49. myTable := reflect.New(myTableType).Elem().Interface()
  50. log.Printf("%#v", myTable)
  51. }

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=1190

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?