gendry icon indicating copy to clipboard operation
gendry copied to clipboard

buildInsert 对于mysql 5.7升级mysql 8.0 , 用到mysql 8.0关键词的人不友好,

Open xiangshang190823 opened this issue 1 year ago • 15 comments

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,处理不了

xiangshang190823 avatar Jun 13 '24 04:06 xiangshang190823

给个你实际使用的code example?

caibirdme avatar Jun 14 '24 07:06 caibirdme

实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 查询rank字段,会报错。

xiangshang190823 avatar Jun 14 '24 09:06 xiangshang190823

实际case: 我们用的线下是mysql 8.0 线上mysql 5.7版本,目前去用该库的sqlbuilder 去组装sql语句,查询rank字段,会报错。 select rank from testA; 5.7版本,可以正常查询出数值; 8.0版本。会报错, Uploading 0d656abbf4b5266b2b4d5caa5.png…

xiangshang190823 avatar Jun 14 '24 09:06 xiangshang190823

/**

  • @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" // 更新时间 }

banner

这个数据库有但是查询获取不到值 code_banner

xiangshang190823 avatar Jun 14 '24 10:06 xiangshang190823

以下两个语句就是反引号的差异,但是在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 = ?

xiangshang190823 avatar Jun 14 '24 16:06 xiangshang190823

以下两个语句就是反引号的差异,但是在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 = ?

xiangshang190823 avatar Jun 14 '24 16:06 xiangshang190823

tb_mall_banner 和rank中间的反引号被消除了,展示不出来 Uploading sql.png…

xiangshang190823 avatar Jun 14 '24 16:06 xiangshang190823

sql

xiangshang190823 avatar Jun 14 '24 16:06 xiangshang190823

你是说构建出来的sql语句遇到数据库关键字有问题对吧…我看你一开始的描述还以为是无法Scan

你们是基于gendry之上封装了一层吗?gendry的struct tag只用于Scan,没有用于生成sql语句。 你可以如下

where["`rank`"]=xxx

去规避这个问题。

没有默认加"`"符号,是因为有的用户希望 where["函数名(col)"]=xx,如果要默认加"`",则需要对map key做一定的语法解析才行,那样太复杂了没必要

caibirdme avatar Jun 15 '24 03:06 caibirdme

我们是基于gendry之上封装了一层,where["rank"]=xxx可以规避查询问题,但是insert 插入语句遇到关键词也有问题

xiangshang190823 avatar Jun 15 '24 04:06 xiangshang190823

例如,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是能解决这个问题,但是第一不方便,第二批量插入操作,用手写拼装的方式也不是很优雅

xiangshang190823 avatar Jun 15 '24 04:06 xiangshang190823

如果where 不加反引号也能行,但是insert 也没有的话,这个就很囧,不太好实现 我当前的case,或者用当前框架还有没有别的方式去实现

xiangshang190823 avatar Jun 17 '24 02:06 xiangshang190823

Got it,如果要解决可能需要拓展一下API,比如提供一个自定义hook,你可以自己对字段名按需做二次修改

caibirdme avatar Jun 17 '24 02:06 caibirdme

目前形态是没法做到是吗?没有比较好的实现思路,除了用原生的sql语句去执行

xiangshang190823 avatar Jun 17 '24 02:06 xiangshang190823

给Build方法增加Option参数,比如: BuildInsert(...., WithColModify(your_func))

func your_func(col string) string {
  if col == "rank" {
    return "`rank`"
  }
}

caibirdme avatar Jun 17 '24 03:06 caibirdme