Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

SqlT golang实现的类似MyBaits的Sql 工具

License

NotificationsYou must be signed in to change notification settings

twiglab/sqlt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

java的数据库访问工具MyBatis给大家留下了深刻的印象,早在几年前,我刚刚接触golang的时候,也希望golang也有类似的工具,对golang稍微熟悉后,发现golang自带模板功能(text/template),于是在另外一个开源库sqlx的基础上,增加模板拼接sql的功能,所以 sqlt 就诞生了。

最早sqlt是托管在oschina,后续迁移到github.com/it512/sqlt,之后加入twiglab

安装

go get github.com/twiglab/sqlt

sqlt 也支持 go mod

sqlt 架构简要说明

sqlt 深度依赖sqlx, 是在sqlx的基础上增加了模板功能,底层的数据库方法全部通过sqlx的NamedStmt和PrepareName完成对数据库的访问。

sqlt 对外提供的所有操作全部通过Dbop struct 提供,Dbop struct 组合了sqlx.DB和模板(由Maker接口定义)

typeDbopstruct {Maker*sqlx.DB}
  • sqlt 没有隐藏任何使用sqlx的细节,Dbop对外直接暴露sqlx.DB,任何sqlt.DB的方法均可以直接使用,请参考sqlx的文档
  • sqlt 全部采用Parper和NamedStmt 完成对数据库的访问,所以也受到数据库驱动的限制,请详细参考数据库驱动的文档

目前sqlt自带的模板为text/template,任何Maker接口的实现都可以作为sqlt的模板使用。

typeMakerinterface {MakeSql(string,interface{}) (string,error)}

golang 自带的模板未必最好,欢迎pr更好模板实现

使用说明

Dbop的创建

最简单的创建方式为:

dbop:=sqlt.Default("postgres","dbname=testdb sslmode=disable","tpl/*.tpl")

注意:不要忘记引入数据库驱动

如果你有现成的数据库链接,或者对模板有特殊的要求,有可以用使用sqlt.New方法创建

dbx:=sqlt.MustConnect("postgres","dbname=testdb sslmode=disable")tpl:=sqlt.NewSqlTemplate("tpl/*.tpl")tpl.SetDebug(true)dbop:=sqlt.New(dbx,tpl)

如果你的模板方法中用到了自定义的函数,sqlt也提供了一个NewSqlTemplateWithFuncs 的方法用于创建带有自定义函数的模板 (位于tpl.go中)

模板

再次说明sqlt默认自带的模板是text/template的封装实现,详细的用法请参考text/template

(example目录中有完整的例子)

sqlt的方法

最新版本中,所有的sqlt的方法都可以直接调用,分别为:

  • func Query(execer TExecer, ctx context.Context, id string, param interface{}, h RowsExtractor) (err error)
  • func Exec(execer TExecer, ctx context.Context, id string, param interface{}) (r sql.Result, err error)

以及对应的Must版本

Texcer 为*Dbop,所有的方法都支持context.Context,id 为模板的id,param为传递给模板和用于Prepare的参数(用于构建条件,和sql拼接)

Exec方法对应执行无返回的sql语句,如:insert, update, delete和存储过程。

Query方法用于执行带有返回结果的sql语句,如:select,和带有returnning子句的insert, update (returnning子句需要数据库和驱动的支持

Query 的结果集处理

sqlt 提供了RowsExtractor 接口处理结果集,Query的最后一个参数中传入RowsExtractor的实现。

例子:

typeStaffstruct {StaffIdint`db:"staff_id"`//StaffNamestring`db:"staff_name"`//CreatedAt time.Time`db:"created_at"`//UpdatedAt time.Time`db:"updated_at"`//Ageint`db:"age"`//}typeStaffHandlerstruct {Staffs []*Staff}func (sh*StaffHandler)Extract(rs sqlt.Rows) (errerror) {forrs.Next() {staff:=new(Staff)iferr=rs.StructScan(staff);err!=nil {return}sh.Staffs=append(sh.Staffs,staff)}returnrs.Err()}staff:=new(Staff)staff.StaffId=67890h:=new(StaffHandler)sqlt.MustQuery(dbop,context.Background(),"Staff.select",staff,h)

sqlt不要求返回字段和struct字段一一对应,struct映射是按照row和struct公共部分映射的

staff 最为查询条件传入模板,模板会根据staff字段构建查询条件,然后通过sqlx执行查询,返回结果由RowsExtractor的实现StaffHandler处理模板:

{{ define "Staff.select"}}selectstaff_id,staff_name,created_atfromStaffwhere{{if .StaffId}} staff_id = :staff_id {{end}}{{if .StaffName}}and  staff_name = :staff_name {{end}}{{end}}

Gen (代码生成器)

cmd目录下的pggen是postgresql数据库的代码生成器,目前sqlt只提供了pg代码生成

首先需要说明的是:

  • 生成器以表为单位生成对应的struct,常量,和增删改查通用的模板
  • 生成器生成的内容直接输出到屏幕上(stdout),需要重定向到文件
  • 生成器生成的代码片段,并不是可以直接使用的结果

生成器生成的是代码片段,并不是可以直接使用的结果

开发人员需要从生成结果中复制有用的片段到程序中

一些规则

这些规则不是强制的,但是如果不遵循这些规则,使用sqlt的工作量会增大,从而失去价值

  • 数据库对象(表,字段)的命名,采用下划线格式(_) 如: staff_name, staff_id
  • struct 中的命名采用golang推荐的snake风格,如:StaffName, StaffId
  • 每个表里面最好都加上 created_at和updated_at这2个字段,用于记录创建时间和修改时间(后面生成模板的时候会简单一些)
  • 模板里面,逗号,and 都放在字段前面
  • 模板的名称要能顾名思义
  • sqlt底层用为sqlx,所以struct的处理也必须符合sqlx的要求(增加db tag)

第一条和第二天规则方便生成和struct和row直接的映射第三条和第四条方便模板的编写,确保不会生成没有字段的错误sql

sqlt已知的一些问题和避免方法

较之 Mybatis,由于golang和模板的限制,sqlt存在下列问题

  • text/template是没有上下文的, 所以无法帮助你处理结尾逗号(,)问题,避免的方法参见规则3,4
  • 0值问题,golang默认0值,对于0值模板会排除,需要用自定义函数去处理

特别提醒

模板只是帮您拼接了sql, sql是否正确,以及效率需要开发人员保证。

版权

MIT


[8]ページ先頭

©2009-2025 Movatter.jp