Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
xiangshang190823 opened this issue Jun 13, 2024 · 15 comments

Comments

@xiangshang190823
Copy link

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

@caibirdme
Copy link
Contributor

给个你实际使用的code example?

@xiangshang190823
Copy link
Author

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

@xiangshang190823
Copy link
Author

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

@xiangshang190823
Copy link
Author

/**

  • @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
Copy link
Author

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

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

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

@xiangshang190823
Copy link
Author

sql

@caibirdme
Copy link
Contributor

caibirdme commented Jun 15, 2024

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

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

where["`rank`"]=xxx

去规避这个问题。

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

@xiangshang190823
Copy link
Author

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

@xiangshang190823
Copy link
Author

例如,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
Copy link
Author

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

@caibirdme
Copy link
Contributor

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

@xiangshang190823
Copy link
Author

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

@caibirdme
Copy link
Contributor

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants