最近在使用xorm,并使用了sql builder来构建sql查询没想到升级后原来可以使用的代码居然报错了。

0x00 代码

sql, args, _ := builder.Select("*").
From("user").
Where(builder.Eq{"uid": 1}).
ToSQL()
res, err := orm.QueryString(sql, args...)

0x01 对比

发现xorm在0.6.3 和 0.6.4间做了改动,如图

0.6.3

0.6.4

原来如此,去掉了第一个参数,改为全部可变参数了,于是机智的把args...,改为了args

关于可变参数的问题,可以参考我的这篇文章

0x02 新错误

没想到编译没错,运行时报错了,提示

sql: converting argument $1 type: unsupported type []interface {}, a slice of interface

即类型错误。继续追踪代码,发现session_query.go里有生成sql的函数,代码如下:

func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
if len(sqlorArgs) > 0 {
return sqlorArgs[0].(string), sqlorArgs[1:], nil
}
//省略
}

由于sqlorArgs是slice,而且builder.ToSql的args也是slice,那么sqlorArgs[1:]又创建了一个新的slice,就让最后返回的slice变成了二元slice了,所以出现了上面的类型错误。

0x03 解决办法

想了一下,其实我觉得上一个版本的函数签名更好,两个参数,一个负责接受sql语句,一个负责接收sql变量。给作者提了issue,或许作者有更好的解决方案。

下面是我的临时解决方法:

func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
if len(sqlorArgs) > 0 {
if len(sqlorArgs) == 2 && reflect.TypeOf(sqlorArgs[1]).Kind() == reflect.Slice {
return sqlorArgs[0].(string), sqlorArgs[1].([]interface{}), nil
}
return sqlorArgs[0].(string), sqlorArgs[1:], nil
}
//省略
}

作者已经更新,方法更加巧妙,增加了builder类型

用法,直接传builder即可

xorm的sql builder的更多相关文章

  1. SQL Builder 1.04

    解析效果: select id,code,name,utime,src,ctime from stock where id<20 and code like '%6%' order by id, ...

  2. MyBatis(3.2.3) - Dynamic SQL

    Sometimes, static SQL queries may not be sufficient for application requirements. We may have to bui ...

  3. 【开源.NET】轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)

    该篇是 Grissom.CMS 框架系列文章的第三篇, 主要介绍框架用到的核心库 EasyJsonToSql, 把标准的配置文件和数据结构解析成可执行的 sql. 该框架能实现自动化增删改查得益于 E ...

  4. PetaPoco源代码学习--3.Sql类

    PetaPoco对数据库的操作直接使用SQL语句,在代码中进行调用既可以直接传递SQL语句,也可以使用提供的SQL类来获取到SQL语句进行操作,直接传递SQL语句在内部实现中也是封装成Sql类传递到底 ...

  5. using the library to generate a dynamic SELECT or DELETE statement mysqlbaits xml配置文件 与 sql构造器 对比

    https://github.com/mybatis/mybatis-dynamic-sql MyBatis Dynamic SQL     What Is This? This library is ...

  6. SpringBoot + MyBatis(注解版),常用的SQL方法

    一.新建项目及配置 1.1 新建一个SpringBoot项目,并在pom.xml下加入以下代码 <dependency> <groupId>org.mybatis.spring ...

  7. DIY:从零开始写一个 SQL 构建器

    最近在项目中遇到了一个棘手的问题,因为 EF Core 不支持直接生成 Update 语句,所以这个项目就用到了 EFCore.Plus 来实现这个功能,但是 EFCore.Plus 对 SQLite ...

  8. Awesome Go

    A curated list of awesome Go frameworks, libraries and software. Inspired by awesome-python. Contrib ...

  9. Go 语言相关的优秀框架,库及软件列表

    If you see a package or project here that is no longer maintained or is not a good fit, please submi ...

随机推荐

  1. TensorFlow实战

    TensorFlow实战:Chapter-1(TensorFlow介绍) TensorFlow实战:Chapter-2(TensorFlow入门) TensorFlow实战:Chapter-3(CNN ...

  2. python练习笔记——组合恒等式

    排列组合结合恒等式 已知从n个物品中取出m个,则存在一个组合恒等式. C(n, m)=C(n, n-m)=C(n-1, m-1)+C(n-1,m) 其中C(n,0) = 1 求:从5取3 和 10 取 ...

  3. php mysql procedure获取多个结果集

    protected function getRs($id) { $db = new mysqli(C("DB_HOST"), C("DB_USER"), C(& ...

  4. Java中类的设计技巧

    1)  一定要将数据设计为私有: 不要破坏封装性.有时需要编写一个访问器或更改器方法,但是最好还是保持实例域的私有性.数据的表示形式可能会改变,但他们的使用方式却不会经常发生变化.当数据保持私有时,他 ...

  5. Oracle 12C -- Unified Auditing Policy

    1.审计策略是一组审计选项,用来审计数据库用户 2.创建审计策略需要被授予audit_admin角色(create audit policy ...) 3.可以在CDB.PDB级别创建创建审计策略 4 ...

  6. Android MediaScannerJNI源代码具体解释

    1.简单介绍 MediaScannerJNI的在MediaScanner中的地位可參考 Android MediaScanner 总纲 MediaScanner JNI文件名称: android_me ...

  7. proguard的简单配置说明

    #需要转换的jar文件路径-injars 'D:\fs-np.jar'#转换后的jar文件名称-outjars 'D:\fs-np-sec.jar' #关联的第三方jar-libraryjars 'C ...

  8. 【转载】Oracle死锁概念,阻塞产生的原因以及解决方案

    参考原文:http://blog.sina.com.cn/s/blog_9d12d07f0102vu72.html 锁是一种机制,一直存在:死锁是一种错误,尽量避免.​ 首先,要理解锁和死锁的概念:​ ...

  9. Java 8 – Convert Map to LIST

    Java 8 – Convert Map to LIST Few Java examples to convert a Map to a List Map<String, String> ...

  10. 如何在Android Studio中添加注释模板信息?

    如何在Android Studio中添加注释模板信息? 在开发程序的时候,我们一般都会给文件自动添加上一些关于文件的注释信息,比如开发者的名字,开发的时间,开发者的联系方式等等.那么在android ...