Yesql v1.1.5 发布了,从 SQL 文件自动生成 Go 结构体代码,实现查询语句与代码分离
Yesql 解析一个 SQL 文件,提取出查询语句,自动生成对应的 Go 结构体,实现查询语句与代码分离,方便编写数据库查询逻辑。
安装
go get github.com/alimy/yesql
使用
创建sql文件
-- sql file yesql.sql -- name: newest_tags@topic -- get newest tag information SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin FROM @tag t JOIN @user u ON t.user_id = u.id WHERE t.is_del = 0 AND t.quote_num > 0 ORDER BY t.id DESC LIMIT ? OFFSET ?; -- name: hot_tags@topic -- get get host tag information SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin FROM @tag t JOIN @user u ON t.user_id = u.id WHERE t.is_del = 0 AND t.quote_num > 0 ORDER BY t.quote_num DESC LIMIT ? OFFSET ?; -- name: tags_by_keyword_a@topic -- get tags by keyword SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 ORDER BY quote_num DESC LIMIT 6; -- name: tags_by_keyword_b@topic SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 AND tag LIKE ? ORDER BY quote_num DESC LIMIT 6; -- name: insert_tag@topic INSERT INTO @tag (user_id, tag, created_on, modified_on, quote_num) VALUES (?, ?, ?, ?, 1); -- name: tags_by_id_a@topic -- clause: in SELECT id FROM @tag WHERE id IN (?) AND is_del = 0 AND quote_num > 0; -- name: tags_by_id_b@topic -- clause: in SELECT id, user_id, tag, quote_num FROM @tag WHERE id IN (?); -- name: decr_tags_by_id@topic -- clause: in UPDATE @tag SET quote_num=quote_num-1, modified_on=? WHERE id IN (?); -- name: tags_for_incr@topic -- clause: in SELECT id, user_id, tag, quote_num FROM @tag WHERE tag IN (?); -- name: incr_tags_by_id@topic -- clause: in UPDATE @tag SET quote_num=quote_num+1, is_del=0, modified_on=? WHERE id IN (?);
使用Scan模式(方式一)
// file: topics.go package topics import ( "context" _ "embed" "github.com/alimy/yesql" "github.com/jmoiron/sqlx" ) //go:embed yesql.sql var yesqlBytes []byte type Topic struct { yesql.Namespace `yesql:"topic"` DecrTagsById string `yesql:"decr_tags_by_id"` IncrTagsById string `yesql:"incr_tags_by_id"` TagsByIdA string `yesql:"tags_by_id_a"` TagsByIdB string `yesql:"tags_by_id_b"` TagsForIncr string `yesql:"tags_for_incr"` HotTags *sqlx.Stmt `yesql:"hot_tags"` InsertTag *sqlx.Stmt `yesql:"insert_tag"` NewestTags *sqlx.Stmt `yesql:"newest_tags"` TagsByKeywordA *sqlx.Stmt `yesql:"tags_by_keyword_a"` TagsByKeywordB *sqlx.Stmt `yesql:"tags_by_keyword_b"` } func NewTopic(db *sqlx.DB) (*Topic, error) { // use *sqlx.DB as prepare context yesql.UseSqlx(db) // get sql query query := yesql.MustParseBytes(yesqlBytes) // scan object from sql query obj := &Topic{} if err := yesql.Scan(obj, query); err != nil { return nil, err } return obj, nil }
使用代码生成模式(方式二)
- 编写代码生成逻辑
/ file: gen.go package main import ( "log" "github.com/alimy/yesql" ) //go:generate go run $GOFILE func main() { log.Println("[Yesql] generate code start") if err := yesql.Generate("yesql.sql", "auto", "yesql"); err != nil { log.Fatalf("generate code occurs error: %s", err) } log.Println("[Yesql] generate code finish") }
- 自动生成Go代码
% go generate gen.go 2023/03/31 19:34:44 [Yesql] generate code start 2023/03/31 19:34:44 [Yesql] generate code finish
- 生成代码如下(生成文件路径:auto/yesql.go)
// Code generated by Yesql. DO NOT EDIT. // versions: // - Yesql v1.1.2 package yesql import ( "context" "github.com/alimy/yesql" "github.com/jmoiron/sqlx" ) const ( _TagsByKeywordB_Topic = `SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 AND tag LIKE ? ORDER BY quote_num DESC LIMIT 6` _InsertTag_Topic = `INSERT INTO @tag (user_id, tag, created_on, modified_on, quote_num) VALUES (?, ?, ?, ?, 1)` _TagsByIdA_Topic = `SELECT id FROM @tag WHERE id IN (?) AND is_del = 0 AND quote_num > 0` _TagsByIdB_Topic = `SELECT id, user_id, tag, quote_num FROM @tag WHERE id IN (?)` _TagsForIncr_Topic = `SELECT id, user_id, tag, quote_num FROM @tag WHERE tag IN (?)` _IncrTagsById_Topic = `UPDATE @tag SET quote_num=quote_num+1, is_del=0, modified_on=? WHERE id IN (?)` _NewestTags_Topic = `SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin FROM @tag t JOIN @user u ON t.user_id = u.id WHERE t.is_del = 0 AND t.quote_num > 0 ORDER BY t.id DESC LIMIT ? OFFSET ?` _TagsByKeywordA_Topic = `SELECT id, user_id, tag, quote_num FROM @tag WHERE is_del = 0 ORDER BY quote_num DESC LIMIT 6` _DecrTagsById_Topic = `UPDATE @tag SET quote_num=quote_num-1, modified_on=? WHERE id IN (?)` _HotTags_Topic = `SELECT t.id id, t.user_id user_id, t.tag tag, t.quote_num quote_num, u.id, u.nickname, u.username, u.status, u.avatar, u.is_admin FROM @tag t JOIN @user u ON t.user_id = u.id WHERE t.is_del = 0 AND t.quote_num > 0 ORDER BY t.quote_num DESC LIMIT ? OFFSET ?` ) type Topic struct { yesql.Namespace `yesql:"topic"` DecrTagsById string `yesql:"decr_tags_by_id"` IncrTagsById string `yesql:"incr_tags_by_id"` TagsByIdA string `yesql:"tags_by_id_a"` TagsByIdB string `yesql:"tags_by_id_b"` TagsForIncr string `yesql:"tags_for_incr"` HotTags *sqlx.Stmt `yesql:"hot_tags"` InsertTag *sqlx.Stmt `yesql:"insert_tag"` NewestTags *sqlx.Stmt `yesql:"newest_tags"` TagsByKeywordA *sqlx.Stmt `yesql:"tags_by_keyword_a"` TagsByKeywordB *sqlx.Stmt `yesql:"tags_by_keyword_b"` } func BuildTopic(p yesql.PreparexBuilder, ctx ...context.Context) (obj *Topic, err error) { var c context.Context if len(ctx) > 0 && ctx[0] != nil { c = ctx[0] } else { c = context.Background() } obj = &Topic{ DecrTagsById: p.QueryHook(_DecrTagsById_Topic), IncrTagsById: p.QueryHook(_IncrTagsById_Topic), TagsByIdA: p.QueryHook(_TagsByIdA_Topic), TagsByIdB: p.QueryHook(_TagsByIdB_Topic), TagsForIncr: p.QueryHook(_TagsForIncr_Topic), } if obj.HotTags, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_HotTags_Topic))); err != nil { return } if obj.InsertTag, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_InsertTag_Topic))); err != nil { return } if obj.NewestTags, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_NewestTags_Topic))); err != nil { return } if obj.TagsByKeywordA, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TagsByKeywordA_Topic))); err != nil { return } if obj.TagsByKeywordB, err = p.PreparexContext(c, p.Rebind(p.QueryHook(_TagsByKeywordB_Topic))); err != nil { return } return }
使用 Yesql 的项目

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
兑现承诺,马斯克宣布 Twitter 算法正式开源
当地时间 3 月 31 日,马斯克终于履行诺言正式宣布了 Twitter(推特)算法的开源。该公司在 GitHub 上发布了两个存储库 (main repo、ml repo),其中涵盖了推荐算法在内的许多推特源代码,包括用来控制用户在 For You 时间线上看到的推文的机制。并发布了一篇博客分享了有关推特算法的更多详细信息。 “今天标志着 Twitter 进入了一个透明的新时代。我们正在与全世界共享为我们的平台提供动力的大部分源代码。” 马斯克表示,此次发布的是大部分推荐算法,其余的算法也将陆续开放;希望“独立的第三方能够以合理的准确性确定 Twitter 可能向用户展示的内容”。不过他也警告称,随着开源发布可能会暴露出一些令人尴尬的问题,“但我们会迅速解决”。此外他还补充称,推特将根据用户的建议,每 24 至 48 小时更新其推荐算法。 此次发布不包括驱动推特广告推荐的代码。推特方面表示,其目标是尽可能提高透明度,它排除了会损害用户安全或隐私的代码,以及会破坏在该平台上防止儿童性侵内容努力的细节。 在有关算法开源发布的Space 讨论中,马斯克称此次的开源是想让推特向著名的开源项目...
- 下一篇
openGauss 5.0.0 版本正式发布
openGauss 5.0.0 版本现已正式发布。这是openGauss发布的第三个LTS版本,版本生命周期为3年。公告称,openGauss 5.0.0版本与之前的版本功能特性保持兼容,在内核能力、工具链、兼容性方面全面增强。 具体更新内容包括: 一、内核能力增强 1 企业级特性 SQL PATCH 当业务语句出现由于数据等因素变化引起执行计划跳变,且出现严重的性能劣化,用户可通过SQL PATCH机制在线实施修复,业务无需版本升级,无感知解决计划跳变等疑难问题。 SQL Patch功能通过在优化器阶段计划生成之前对查询解析树的HintState成员进行替换,达成在计划生成阶段产生最佳执行计划的效果。在接口层面,用户可以使用SQL PATCH的创建、激活、禁用、删除、显示等接口,实现SQL PATCH全生命周期管理。 分区表能力持续增强 List分区键最大数由1扩展为16列; Range分区键最大数由4扩展为16列; 分区键底层重构LRHS为统一分区键内存结构 兼容创建分区表COLUMNS、VALUES IN、PARTITIONS num、SUBPARTITIONS num、MAXV...
相关文章
文章评论
共有0条评论来说两句吧...