buildInsert 对于mysql 5.7升级mysql 8.0 , 用到mysql 8.0关键词的人不友好,
mysql 5.7升级到8.0,某些表加了8.0的关键词作为字段,该框架框架 tag不支持增加反括号这个处理, 这个表的model中的rank字段如何加反引号处理
type TBBestFriendRank struct {
ID int64 `ddb:"id" json:"id" form:"id"` // 自增主键
UserID int64 `ddb:"user_id" json:"user_id" form:"user_id"` // 用户id
FriendUserID int64 `ddb:"friend_user_id" json:"friend_user_id" form:"friend_user_id"` // 挚友id
SouvenirID int64 `ddb:"souvenir_id" json:"souvenir_id" form:"souvenir_id"` // 信物id
Rank int64 `ddb:"rank" json:"rank" form:"rank"` // 排名,从1开始
Score int64 `ddb:"score" json:"score" form:"score"` // 周期内分数
RankStartDate string `ddb:"rank_start_date" json:"rank_start_date" form:"rank_start_date"` // 榜单开始时间
RankType int64 `ddb:"rank_type" json:"rank_type" form:"rank_type"` // 榜单类型:0周榜,1月榜
CreateTime int64 `ddb:"create_time" json:"create_time" form:"create_time"` // 创建时间
} 建议可以在 buildInsert 等函数中,可以给字段加上反引号,去做插入,或者查询,这样更为通用一些,否则一些特殊case,处理不了
给个你实际使用的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版本。会报错,
/**
-
@description: base 查询商城 banner 方法
-
@param {context.Context} ctx
-
@param {map[string]interface{}} where 查询条件
-
@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中间的反引号被消除了,展示不出来
你是说构建出来的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`"
}
}