<p>I'm trying to figure out the best way to write complex conditional SQL queries based on different filtering parameters. I'm currently using <a href="https://github.com/jmoiron/sqlx" rel="nofollow">sqlx</a> to do my struct scanning, but I need a way to build queries at runtime without having a bunch of very long and raw SQL strings with complex concatenation and ordinal incrementing littering my go code.</p>
<p>Right now I'm leaning towards using the standard template package and creating custom template functions, <a href="https://clypd.com/simple-database-interaction-in-go/" rel="nofollow">just like how this company does it</a>. It allows me to write the raw queries in a separate file that I can compile into go code before I ship the binary by using <a href="https://github.com/gobuffalo/packr" rel="nofollow">packr</a>. The main benefit from this is that I can visually see what query is going to run, which allows me to fine tune it when I need a performance boost. It also allows me to store other really long and complex sql queries in the same directory that don't require conditional logic so it doesn't clutter my go code. The only problem is I don't know how maintainable this way is. It looks like it can get quite complex really fast and I wouldn't know until 3 months down the line after it's baked into the codebase.</p>
<p>I've found the following solutions as well:</p>
<ul>
<li><a href="https://github.com/Masterminds/squirrel" rel="nofollow">squirrel</a>: SQL builder tool.</li>
<li><a href="https://github.com/go-pg/pg" rel="nofollow">go-pg/pg</a>: Postgres based ORM with query builder capabilities.</li>
<li><a href="https://github.com/jinzhu/gorm" rel="nofollow">gorm</a>: Fully featured ORM.</li>
</ul>
<p>I've stayed away from ORM's thus far because I wanted to really fine tune my SQL queries for pretty high throughput in certain situations, but I'm not against the idea. I'm just trying to KISS right now by keeping the number of dependencies low.</p>
<p>Let me know what your experiences are with solving this particular problem!</p>
<hr/>**评论:**<br/><br/>Ploobers: <pre><p>I really dislike <code>text/template</code>, and I don't find that using it like the example you linked to ends up more readable than string concatenation. We've done a combination of <code>fmt.Sprintf</code>, <code>bytes.Buffer</code> and a custom sql builder similar to squirrel, depending on the complexity of the query. This is an example of our sql builder that uses functional options:</p>
<pre><code>b := mysql.NewBatchSelector(c,
"db.Tags",
[]string{"WorkspaceID", "ID", "Name", "Description", "Config", "Created", "Modified", "Deleted"}, // field names
[]string{"WorkspaceID", "ID"}, // where fields
mysql.BatchSelectorRequireOneRowAffectedPerAdd(),
)
for _, tag := range tags {
b.Add(tag.WorkspaceID, tag.ID) // params that have to match the where fields
}
</code></pre></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传