一、参数判断,如果有特殊字符,进行转义操作
func sqlAgencyListFindParam(agency AgencyList) string {
// 定义变量
sql := ""
// 参数判断,如果有特殊字符,进行转义操作
utils.MysqlSpecialCharHandle(&agency) //此处传入的是指针,若函数中的参数已经是指针,则无需再带&
if agency.Name != "" {
sql += " name LIKE '%" + agency.Name + "%' AND "
}
return sql
}
///
// @title MysqlSpecialCharHandle
// @description Mysql 数据库查询,字符串字段需要校验,避免出现特殊字符,如果有特殊字符,进行转义操作
// @param s interface{} 结构体变量
// @return
func MysqlSpecialCharHandle(s interface{}) {
log.Info("MysqlSpecialCharHandle")
prval := reflect.ValueOf(s)
num := prval.Elem().NumField()
// TODO 遍历结构体
for i := 0; i < num; i++ {
if prval.Elem().Field(i).Kind() == reflect.String {
srcfield := prval.Elem().Field(i).String()
realescapestring := mysqlRealEscapeString(srcfield)
prval.Elem().Field(i).SetString(realescapestring)
}
}
}
// @title mysqlRealEscapeString
// @description MySql字符转义
// https://www.cnblogs.com/end/archive/2011/04/01/2002516.html
// \0 ASCII 0(NUL)字符。
// \' 单引号(‘'’)。
// \" 双引号(‘"’)。
// \b 退格符。
// \n 换行符。
// \r 回车符。
// \t tab字符。
// \Z ASCII 26(控制(Ctrl)-Z)。该字符可以编码为‘\Z’,以允许你解决在Windows中ASCII 26代表文件结尾这一问题。(如果你试图使用mysql db_name < file_name,ASCII 26会带来问题)。
// \\ 反斜线(‘\’)字符。
// \% ‘%’字符: 包含零个或更多字符的任意字符串。
// \_ ‘_’字符: 任何单个字符。
// [ ] 指定范围(例如 [a-f])或集合(例如 [abcdef])内的任何单个字符。
// [^] 不在指定范围(例如 [^a - f])或集合(例如 [^abcdef])内的任何单个字符。
func mysqlRealEscapeString(field string) string {
log.Info("mysqlRealEscapeString field:" + field)
field = strings.Replace(field, "\\", "\\\\\\\\\\\\\\\\", -1) // -1 全部替换
//field = strings.Replace(field, "0", "\\0", -1) // -1 全部替换
field = strings.Replace(field, "'", "\\'", -1) // -1 全部替换
//field = strings.Replace(field, "\"", "\\\"", -1) // -1 全部替换
field = strings.Replace(field, "\b", "\\\\b", -1) // -1 全部替换
field = strings.Replace(field, "\n", "\\\\n", -1) // -1 全部替换
field = strings.Replace(field, "\r", "\\\\r", -1) // -1 全部替换
field = strings.Replace(field, "\t", "\\\\t", -1) // -1 全部替换
field = strings.Replace(field, "\\Z", "\\\\Z", -1) // -1 全部替换
field = strings.Replace(field, "%", "\\%", -1) // -1 全部替换
field = strings.Replace(field, "_", "\\_", -1) // -1 全部替换
reg, err := regexp.Compile("\\[(^)?[\\s\\S]{0,}\\]") // 校验 []
if err != nil {
log.Error("error(%v)", err)
return field
}
if reg.MatchString(field) {
field = strings.Replace(field, "[", "\\[", -1) // -1 全部替换
}
log.Info("mysqlRealEscapeString newField:" + field)
return field
}
二、联合列表模糊查询
第一种:组合sql语句
// 用户列表
func (r *userRepo) UserList(ctx context.Context, user *biz.UserList) ([]*biz.UserListRes, uint64, error) {
var (
ttl int64
userListRes []*biz.UserListRes
)
//
sqlParam := sqlUserListFindParam(user)
//res := r.data.db.Table("agency").
res := r.data.db.Model(&Agency{}).
Select("user.username, user.mobile, agency.name as agencyname, user.id as UserID").
Joins("join user on " +
"user.agency_id = agency.id").
Where(sqlParam + "user.deleted_at IS NULL" +
" AND " + "agency.deleted_at IS NULL").
Count(&ttl).Order("user.id desc").Limit(int(user.PageSize)).Offset(int((user.Page - 1) * user.PageSize)).
Find(&userListRes)
if res.Error != nil {
return nil, uint64(ttl), errors.New(utils.AGENCY_LIST, "", "查询失败")
}
return userListRes, uint64(ttl), nil
}
func sqlUserListFindParam(user *biz.UserList) string {
// 定义变量
sql := ""
// 参数判断,如果有特殊字符,进行转义操作
utils.MysqlSpecialCharHandle(user)
if user.Username != "" {
sql += " user.username LIKE '%" + user.Username + "%' AND "
}
if user.Mobile != "" {
sql += " user.mobile LIKE '%" + user.Mobile + "%' AND "
}
//todo
if user.Agencyname != "" {
sql += " agency.name LIKE '%" + user.Agencyname + "%' AND "
}
return sql
}
第二种:组合查询语句
