xormplus / xorm

xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简便。本库是基于原版xorm的定制增强版本,为xorm提供类似ibatis的配置文件及动态SQL支持,支持AcitveRecord操作
BSD 3-Clause "New" or "Revised" License
1.55k stars 222 forks source link

如何给Sqltemplate添加自定义函数 #42

Closed lx32056127 closed 5 years ago

lx32056127 commented 5 years ago

如何给Sqltemplate添加自定义函数,使用html/template模板进行解析.想添加个自定义函数.总是提示未定义.一步一步debug发现只使用了官方库的默认函数查找对比

xormplus commented 5 years ago

你是使用的标准库的模板引擎么?

lx32056127 commented 5 years ago

你是使用的标准库的模板引擎么?

是的.示例代码如下 main.go `package main

import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/xormplus/xorm" "html/template" "time" )

var ( engine *xorm.Engine )

func main() { engine, err := xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local", "root", "", "127.0.0.1", "3306", "mysql")) if err != nil { panic(err) } engine.ShowExecTime(true) engine.ShowSQL(true) tpl := xorm.Default("./templates", ".tpl") t := template.New("ShowTimestamp").Funcs(template.FuncMap{"ShowTimestamp": ShowTimestamp}) tpl.Template["ShowTimestamp"] = t fmt.Println(t.DefinedTemplates()) err = engine.RegisterSqlTemplate(tpl) if err != nil { panic(err) } }

// 显示时间戳 func ShowTimestamp(val string) string { fmt.Println(val) return fmt.Sprintf("%d", time.Now().Unix()) } `

tpl文件内容如下 select * from user {{. | ShowTimestamp}}

报错提示 panic: template: query.tpl:2: function "ShowTimestamp" not defined

xormplus commented 5 years ago

暂不支持这种用法

xormplus commented 5 years ago

对Default模板引擎新增这个功能,你可以试下看看

lx32056127 commented 5 years ago

对Default模板引擎新增这个功能,你可以试下看看

测试了正常. 还有一个问题 在使用?变量名进行占位时,变量内容中如果带有点(.),只会判断前面的内容为map的key Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?.hardkey ORDER BY create_at desc LIMIT 20' at line 1 实际上我使用的是 device.hardkey = ?device.hardkey 这样的方式进行占位,除了where部分 orderby部分好像不能进行这样占位.

xormplus commented 5 years ago

请贴一下你的详细代码,我看下你的具体使用方式

lx32056127 commented 5 years ago

请贴一下你的详细代码,我看下你的具体使用方式

`package main

import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/xormplus/xorm" )

var ( engine *xorm.Engine )

func main() { engine, err := xorm.NewEngine("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8&parseTime=True&loc=Local", "root", "", "127.0.0.1", "3306", "mysql")) if err != nil { panic(err) } engine.ShowExecTime(true) engine.ShowSQL(true) m := make(map[string]interface{}) m["mgr_role.role_id"] = 1 sql := SELECT 'mgr_user', mgr_user.*, 'mgr_user_role', mgr_user_role.*, 'mgr_role', mgr_role.* FROM mgr_user LEFT JOIN mgr_user_role ON mgr_user.user_id = mgr_user_role.user_id LEFT JOIN mgr_role ON mgr_user_role.role_id = mgr_role.role_id WHERE mgr_role.role_id = ?mgr_role.role_id result := engine.SQL(sql, &m).Query() if result.Error != nil { panic(result.Error) } }`

mgr_role.role_id 为1时正常查询的结果集如下: `Name Value
mgr_user mgr_user
user_id 1
account admin
password admin
status 1
qq 123456
mail 123456@qq.com
phone 10010
desc 管理员
login_count 382
version 8
create_time 2019-04-08 17:37:43
login_time 2019-08-19 10:57:33
mgr_user_role mgr_user_role
id 1
user_id 1
role_id 1
mgr_role mgr_role
role_id 1
role_name admin
role_desc 系统管理员
status 1
version 31
create_time 2019-04-11 17:23:22
update_time 2019-08-13 15:23:56 `

map中的key如果包含(.),这样在使用名称占位时就会出现问题.

xormplus commented 5 years ago

占位符中不要出现"."之类的符号,因为在多种复杂场景中会导致分析词法错误

xormplus commented 5 years ago

不同数据库和数据库驱动对占位符的实现和支持也是不一样的。另外这里的占位符和实际提交到数据库中的占位符不是一个事情。中间是经过转换的,这也必须按不同数据库和数据库驱动的要求来

lx32056127 commented 5 years ago

不同数据库和数据库驱动对占位符的实现和支持也是不一样的。另外这里的占位符和实际提交到数据库中的占位符不是一个事情。中间是经过转换的,这也必须按不同数据库和数据库驱动的要求来

ok,现在已有办法是将占位符中的.转换为_放入sql中进行查询.