• xorm的sql builder


    最近在使用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即可

  • 相关阅读:
    1292
    explicit_defaults_for_timestamp
    比较好的平台工具
    git回退到指定版本的代码
    解决catalina.out文件过大的方法
    json字符串转化成对象列表数据
    Java LIST做批量分组切割
    Activiti数据库表结构
    MySQL修改数据库时区
    集合工具类的使用
  • 原文地址:https://www.cnblogs.com/xdao/p/go_xorm_builder.html
Copyright © 2020-2023  润新知