Open xiangshang190823 opened 4 weeks ago
给个你实际使用的code example?
实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 查询rank字段,会报错。
实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 去组装sql语句,查询rank字段,会报错。 select rank from testA; 5.7版本,可以正常查询出数值; 8.0版本。会报错, ![Uploading 0d656abbf4b5266b2b4d5caa5.png…]()
/**
@return {[]h5MallModel.BannerInfoDB, error} 返回结果 */ func baseGetMallBanner(ctx context.Context, where map[string]interface{}) ([]dressupmallModel.MallBannerDB, error) { if len(where) == 0 { return nil, fmt.Errorf("baseGetMallBanner empty query where") }
var ( list []dressupmallModel.MallBannerDB err error ) columns := []string{"*"}
mysqlClient := baseDao.NewMysqlObject(). SetServiceName(constant.SERVICE_CONF_DB_GRAVITY_UTF8MB4_READ). SetTableName(TbMallBanner). SetWhere(where). SetColumns(columns) err = mysqlClient.Query(ctx, &list) if err != nil { logs.Error(ctx, "baseGetMallBanner mysqlClient.Query failed with err: "+err.Error()) return nil, err }
return list, err }
type MallBannerDB struct {
ID int64 json:"id" ddb:"id"
// 自增 id
Photo string json:"photo" ddb:"photo"
// 图片
Rank int64 json:"rank" ddb:"rank"
// 排序
AndroidURL string json:"android_url" ddb:"android_url"
// 安卓跳转地址
IOSURL string json:"ios_url" ddb:"ios_url"
// ios跳转地址
Status int64 json:"status" ddb:"status"
// 状态 状态:0-未上线,1-已上线
Device string json:"device" ddb:"device"
// 设备类型:all-全部, android-安卓, ios-苹果
StartTime int64 json:"start_time" ddb:"start_time"
// 开始时间
EndTime int64 json:"end_time" ddb:"end_time"
// 结束时间
MinAppVersion string json:"min_app_version" ddb:"min_app_version"
// 最低版本
MaxAppVersion string json:"max_app_version" ddb:"max_app_version"
// 最高版本
CreateTime int64 json:"create_time" ddb:"create_time"
// 创建时间
UpdateTime int64 json:"update_time" ddb:"update_time"
// 更新时间
}
这个数据库有但是查询获取不到值
以下两个语句就是反引号的差异,但是在mysql 5.7旧版本引用了8.0定义的关键字作为字段的话,gendry构建出的sql语句,则会报错。
当前框架构建的sql语句
SELECT FROM tb_mall_banner WHERE rank = ?
目前看gorm构建的语句其实用反引号避免了这个case,故建议加上这个反引号的处理更优雅&& 能兼容更多样的情况
gorm构建的语句
SELECT FROM tb_mall_banner
WHERE tb_mall_banner
.rank
= ?
以下两个语句就是反引号的差异,但是在mysql 5.7旧版本引用了8.0定义的关键字作为字段的话,gendry构建出的sql语句,则会报错。
当前框架构建的sql语句
SELECT FROM tb_mall_banner WHERE rank = ?
目前看gorm构建的语句其实用反引号避免了这个case,故建议加上这个反引号的处理更优雅&& 能兼容更多样的情况
gorm构建的语句
SELECT FROM tb_mall_banner WHEREtb_mall_banner
.rank
= ?
tb_mall_banner 和rank中间的反引号被消除了,展示不出来 ![Uploading sql.png…]()
你是说构建出来的sql语句遇到数据库关键字有问题对吧…我看你一开始的描述还以为是无法Scan
你们是基于gendry之上封装了一层吗?gendry的struct tag只用于Scan,没有用于生成sql语句。 你可以如下
where["`rank`"]=xxx
去规避这个问题。
没有默认加"`"符号,是因为有的用户希望 where["函数名(col)"]=xx
,如果要默认加"`",则需要对map key做一定的语法解析才行,那样太复杂了没必要
我们是基于gendry之上封装了一层,where["rank"]=xxx可以规避查询问题,但是insert 插入语句遇到关键词也有问题
例如,INSERT INTO tb_mall_banner ( photo, rank, android_url, ios_url, status, start_time, end_time, op_user, min_app_version, max_app_version, create_time, update_time, device) VALUES (296, 'voiceroom/banner/2024-02-23/146591d6-96ae-427f-a0bd-e493f85daa7a.png', 4, ‘a’, ‘b’, 1, 1708617600, 1712851200, ‘a’, '', '', 0, 1708675457, 'all'); 8.0版本由于有rank关键词的字段的存在,会发生报错,手写sql是能解决这个问题,但是第一不方便,第二批量插入操作,用手写拼装的方式也不是很优雅
如果where 不加反引号也能行,但是insert 也没有的话,这个就很囧,不太好实现 我当前的case,或者用当前框架还有没有别的方式去实现
Got it,如果要解决可能需要拓展一下API,比如提供一个自定义hook,你可以自己对字段名按需做二次修改
目前形态是没法做到是吗?没有比较好的实现思路,除了用原生的sql语句去执行
给Build方法增加Option参数,比如:
BuildInsert(...., WithColModify(your_func))
func your_func(col string) string {
if col == "rank" {
return "`rank`"
}
}
mysql 5.7升级到8.0,某些表加了8.0的关键词作为字段,该框架框架 tag不支持增加反括号这个处理, 这个表的model中的rank字段如何加反引号处理
type TBBestFriendRank struct {
} 建议可以在 buildInsert 等函数中,可以给字段加上反引号,去做插入,或者查询,这样更为通用一些,否则一些特殊case,处理不了