草庐IT

json - 将一对多关系检索到 JSON sql pure、Golang、Performance

coder 2023-06-27 原文

假设我有以下结构,它是映射表。

type Publisher struct{
   ID int       `db:"id"`
   Name  string `db:"name"`
   Books []*Book  
}

type Book struct {
   ID int       `db:"id"`
   Name string  `db:"name"`
   PublisherID   `db:"publisher_id"` 
}

所以,如果我想检索所有 Publisher 和所有相关的 Books 我想得到一个像这样的 JSON 怎么办:

[ //Publisher 1 
  {
    "id" : "10001", 
    "name":"Publisher1",
    "books" : [
       { "id":321,"name": "Book1"}, 
       { "id":333,"name": "Book2"}
    ]
  },
  //Publisher 2
  {
    "id" : "10002", 
    "name":"Slytherin Publisher",
    "books" : [
       { "id":4021,"name": "Harry Potter and the Chamber of Secrets"}, 
       { "id":433,"name": "Harry Potter and the Order of the Phoenix"}
    ]
  },
]

所以我使用以下结构来检索与 Publisher

相关的所有类型的查询
type PublisherRepository struct{
   Connection *sql.DB
}
// GetEbooks return all the books related with a publisher
func (r *PublisherRepository) GetBooks(idPublisher int) []*Book {
    bs := make([]Book,0)
    sql := "SELECT * FROM books b WHERE b.publisher_id =$1 "
    row, err := r.Connection.Query(sql,idPublisher)
    if err != nil {
      //log
    }
    for rows.Next() {
      b := &Book{}
      rows.Scan(&b.ID, &b.Name, &b.PublisherID)
      bs := append(bs,b)
    }
    return bs
}
func (r *PublisherRepository) GetAllPublishers() []*Publisher {
    sql := "SELECT * FROM publishers"
    ps := make([]Publisher,0)
    rows, err := r.Connection.Query(sql)
    if err != nil { 
       // log 
    }
    for rows.Next() {
       p := &Publisher{}
       rows.Scan(&p.ID,&p.Name)
       // Is this the best way? 
       books := r.GetBooks(p.ID)
       p.Books  = books
    }
    return ps

}

所以,这是我的问题

  1. 以最佳性能检索所有 publisher 的最佳方法是什么,因为 for 中的 for 不是最佳解决方案,如果我有 200 个出版商,平均每个出版商有 100 本书。

  2. 是 GoLang 惯用的 PublisherRepository 还是有另一种方法来创建一些东西来使用纯 sql 管理实体的事务?

最佳答案

1) 不好的是每次迭代的 sql 请求。所以这里有一个解决方案,不会对每个发布者发出额外请求:

func (r *PublisherRepository) GetAllPublishers() []*Publisher {
    sql := "SELECT * FROM publishers"
    ps := make(map[int]*Publisher)
    rows, err := connection.Query(sql)
    if err != nil { 
       // log 
    }
    for rows.Next() {
       p := &Publisher{}
       rows.Scan(&p.ID,&p.Name)
       ps[p.ID] = p
    }

    sql = "SELECT * FROM books"
    rows, err := connection.Query(sql)
    if err != nil {
      //log
    }
    for rows.Next() {
      b := &Book{}
      rows.Scan(&b.ID, &b.Name, &b.PublisherID)

      ps[b.PublisherID].Books = append(ps[b.PublisherID].Books, b)
    }

    // you might choose to keep the map as a return value, but otherwise:

    // preallocate memory for the slice
    publishers := make([]*Publisher, 0, len(ps))
    for _, p := range ps {
        publishers = append(publishers, p)
    }

    return publishers
}

2) 除非您只创建 PublisherRepository 一次,否则创建和关闭大量连接可能不是一个好主意。还取决于您的 sql 客户端实现,我建议(并且也已经看到许多其他 go 数据库客户端)为整个服务器建立一个连接。池是由许多 sql 客户端在内部完成的,这就是为什么你应该检查你的 sql 客户端。 如果您的 sql 客户端库在内部进行池化,则为“连接”使用一个全局变量(如果在内部进行池化,则它不是真正的一个连接):

connection *sql.DB

func New () *PublisherRepository {
    repo := &PublisherRepository{}
    return repo.connect()
}

type PublisherRepository struct{
}

func (r *PublisherRepository) connect() *PublisherRepository {
    // open new connection if connection is nil 
    // or not open (if there is such a state)
    // you can also check "once.Do" if that suits your needs better
    if connection == nil {
        // ...
    }
    return r
}

所以每次你创建一个新的 PublisherRepository 时,它只会检查连接是否已经存在。如果你使用 once.Do,go 只会创建一次“连接”,你就完成了它。

如果您有其他结构也将使用该连接,您需要一个全局位置来存放您的连接变量,或者(甚至更好)您为您的 sql 客户端编写一个小的包装程序包,然后在您的所有结构中使用.

关于json - 将一对多关系检索到 JSON sql pure、Golang、Performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38340859/

有关json - 将一对多关系检索到 JSON sql pure、Golang、Performance的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. ruby - Rails 关联 - 同一个类的多个 has_one 关系 - 2

    我的问题的一个例子是体育游戏。一场体育比赛有两支球队,一支主队和一支客队。我的事件记录模型如下:classTeam"Team"has_one:away_team,:class_name=>"Team"end我希望能够通过游戏访问一个团队,例如:Game.find(1).home_team但我收到一个单元化常量错误:Game::team。谁能告诉我我做错了什么?谢谢, 最佳答案 如果Gamehas_one:team那么Rails假设您的teams表有一个game_id列。不过,您想要的是games表有一个team_id列,在这种情况下

  3. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  4. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  5. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  6. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  7. ruby - Rails 组合多个 activerecord 关系 - 2

    我想合并多个事件记录关系例如,apple_companies=Company.where("namelike?","%apple%")banana_companies=Company.where("namelike?","%banana%")我想结合这两个关系。不是合并,合并是apple_companies.merge(banana_companies)=>Company.where("namelike?andnamelike?","%apple%","%banana%")我要Company.where("名字像?还是名字像?","%apple%","%banana%")之后,我会写代

  8. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  9. ruby - 使用 JSON gem 将自定义对象转换为 JSON - 2

    我正在学习如何使用JSONgem解析和生成JSON。我可以轻松地创建数据哈希并将其生成为JSON;但是,在获取一个类的实例(例如Person实例)并将其所有实例变量放入哈希中以转换为JSON时,我脑袋放屁。这是我遇到问题的例子:require"json"classPersondefinitialize(name,age,address)@name=name@age=age@address=addressenddefto_jsonendendp=Person.new('JohnDoe',46,"123ElmStreet")p.to_json我想创建一个.to_json方法,这样我就可以获

  10. ruby-on-rails - 如何使用驼峰键名称从 Rails 返回 JSON - 2

    我正在构建一个带有Rails后端的JS应用程序,为了不混淆snake和camelcases,我想通过从服务器返回camelcase键名来规范化这一切。因此,当从API返回时,user.last_name将返回user.lastName。我如何实现这一点?谢谢!编辑:添加Controller代码classApi::V1::UsersController 最佳答案 我的方法是使用ActiveModelSerializer和json_api适配器:在你的Gemfile中,添加:gem'active_model_serializers'创建

随机推荐