Would you recommend a database layer like this one?

xuanbao · · 519 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p><a href="https://gist.github.com/shaunlee/7443514" rel="nofollow">https://gist.github.com/shaunlee/7443514</a></p> <p>I&#39;m still trying to figure out the best way to interact with pgsql and Golang.</p> <hr/>**评论:**<br/><br/>iends: <pre><p>The one thing that these tools all suck at is joins...relationships are the whole point in using relational databases!</p> <p>Do people really just create a bunch of structs for each join?</p></pre>TruncatedTrebuchet: <pre><p>If you want to do joins you can do it on the db side when you fire your query. Are you suggesting doing joins on the go side? </p></pre>iends: <pre><p>No, a join would be in the SQL database, but the results returned are usually marshaled into a struct (see upper or sqlx for example). So do people create these big structs with both fields from table a and table b when they are joined? </p></pre>TruncatedTrebuchet: <pre><p>Ahhh I see what you mean now. It seems that is the only way to handle marshalling sql results. You can dynamically fill a map with field:arrayOfValues using sqlx but you&#39;d still need to know what was in each table to be able to use them in your code. </p></pre>HugoWeb: <pre><p>I guess one creates a struct inside the function that has all the resulting columns..</p></pre>skidooer: <pre><p>The repository pattern is your best bet, in my opinion. Here&#39;s a simple example of how you might implement one around a person model.</p> <pre><code>type Person struct { ID int Name string } type PeopleRespository struct { db *sql.DB } func (p *PeopleRespository) Find(id int) (*Person, error) { person := Person{} err = p.db.QueryRow(&#34;select id, name from people where id = ? limit 1&#34;, id).Scan(&amp;person.ID, &amp;person.Name) return &amp;person, err } func (p *PeopleRespository) Create(person *Person) error { return p.db.QueryRow(&#34;insert into people (name) values (?) returning id&#34;, person.Name).Scan(&amp;person.ID) } func (p *PeopleRespository) Update(person *Person) error { _, err := p.db.Exec(&#34;update people set name = ? where id = ?&#34;, person.Name, person.ID) return err } </code></pre> <p><strong>Bonus points</strong>: Use a repository interface and then you don&#39;t have to be bound to only a pgsql implementation. You, for instance, may want to sub in an in-memory repository during testing to not rely on any external services.</p></pre>iends: <pre><p>What does the repository pattern look like for when you want to do a join between Person and another table, say Jobs? You create a new struct called PersonJobs and Scan() into the joined table?</p></pre>skidooer: <pre><p>I would say that first and foremost you should model your models for the needs of your application. The relational database, and the joins it provides, is largely just an implementation detail. One that, like I mentioned in my bonus points section, may not even be a relational database in the future.</p> <p>But, let&#39;s say we decided on this model:</p> <pre><code>type Person struct { ID int Name string Job Job } type Job struct { ID int Name string } </code></pre> <p>If you want to optionally load the <code>Job</code> data along with the <code>Person</code>, you could do something like:</p> <pre><code>func (p *PeopleRespository) FindWithJob(id int) (*Person, error) { person := Person{} err = p.db.QueryRow(&#34;select with join...&#34;, id).Scan( &amp;person.ID, &amp;person.Name, &amp;person.Job.ID, &amp;person.Job.Name, ) return &amp;person, err } </code></pre></pre>vpol: <pre><p><a href="https://github.com/go-pg/pg" rel="nofollow">https://github.com/go-pg/pg</a></p> <p>even if you don&#39;t use it as orm, at least it properly handles reconnections, context, listen/notify.</p></pre>HugoWeb: <pre><p>Wow, another one, will take a look. There is also <a href="https://upper.io" rel="nofollow">https://upper.io</a></p></pre>e1ch1: <pre><p>go-pg appears to be much more flexible and powerful. I use it extensively and found it most balanced between being too much abstraction and too much raw SQL.</p></pre>kardianos: <pre><p>Do you want CRUD, or so you actually want to use the SQL Database Query engine?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

519 次点击  
加入收藏 微博
1 回复  |  直到
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传