您的位置:首页 > 数据库

动态生成SQL语句, 通用查询接口

2019-06-24 00:08 337 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/huangruifeng/article/details/93420808

很多时候,由于业务变化,使得同一数据表在不同业务模块中查询条件不同;例如:用户表在其模块管理页面中,需要根据用户名,真实姓名查询;而在课程报名时,则需要根据用户所在专业进修过滤。这种情况在后端查询接口中全部兼容,另外实现动态SQL语句生成,满足条件由前端进行根据需要进行配置。
1、查询条件配置如下:

{"groupOp":"AND", "rules":[{"field":"name","op":"cn","data":"1"},{"field":"major","op":"eq","data":"110"}], "groups":null}
// 表示 name like '%1%' and major = 110

同样也可以表示更复杂的条件,如下

{
"groupOp":"AND",
"rules":[{"field":"major","op":"eq","data":"110"}],
"groups":[
{
"groupOp":"OR",
"rules":[{"field":"name","op":"cn","data":"ad"},{"field":"login_id","op":"cn","data":"ad"}],
"groups":[]
}
]
}
// 表示 ( `major` = ? ) AND (( `name` LIKE ?  OR  `login_id` LIKE ? ))

2、后端解析
注意:后端用go语言,使用gin+xorm
2.1、实体对象:

type QueryResult struct {
Page   int         `json:"page"`   //页码,从1开始
TotalRows   int         `json:"totalRows"`   // 页行数
TotalPages  int         `json:"totalPages"`  // 总页数
Result interface{} `json:"result"` // 结果
}

type QueryParam struct {
Rows       int           `form:"rows"json:"rows"`     // 页行数
Page       int           `form:"page"json:"page"`     // 页码,从1开始
Sort       string        `form:"sort"json:"sort"`     // 排序,类似与name,age desc
Filter     sqlgen.Filter `form:"filter"json:"filter"` // 过滤条件
Table      string        `form:"-"json:"-"`           // 表名
Selects    []string      `form:"-"json:"-"`           // select 字段列表
JoinParams []JoinParam   `form:"-"json:"-"`           // 连接表列表
}

2.2 解析

/**
* @brief: 生成where条件语句
* @ @param1 tableName: 表名
* @return1: where条件语句
* @return2: 条件值列表
* @return3: u错误信息
*/
func (f *Filter) GenWhereStmt(tableName string) (string, []interface{}, error) {

whereStatement := ""
groupWhereStatement := ""
datas := make([]interface{}, 0)

isAnd := true
if strings.ToLower(strings.TrimSpace(f.GroupOp)) == "or" {
isAnd = false
}

if len(f.Rules) > 0 {
whereStr, ruleDatas := f.GenRuleWhereStmt(tableName, f.Rules[0])
if whereStr != "" {
whereStatement = whereStr
for _, ruleData := range ruleDatas {
datas = append(datas, ruleData)
}
} else {
return whereStatement, datas, errors.New(fmt.Sprintf("the 0 rule is invalid"))
}
for i := 1; i < len(f.Rules); i++ {
whereStr, ruleDatas = f.GenRuleWhereStmt(tableName, f.Rules[i])
if whereStr != "" {
if isAnd {
whereStatement += " AND " + whereStr
} else {
whereStatement += " OR " + whereStr
}
for _, ruleData := range ruleDatas {
datas = append(datas, ruleData)
}
} else {
return whereStatement, datas, errors.New(fmt.Sprintf("the %d rule is invalid", i))
}
}
}

if len(f.Groups) > 0 {

whereStr, groupDatas, err := f.Groups[0].GenWhereStmt(tableName)
if err != nil {
return whereStatement, datas, err
}
if whereStr != "" {
groupWhereStatement = whereStr
for _, groupData := range groupDatas {
datas = append(datas, groupData)
}
} else {
return whereStatement, datas, errors.New("the 0 group is invalid")
}
for i := 1; i < len(f.Groups); i++ {
whereStr, groupDatas, err := f.Groups[i].GenWhereStmt(tableName)
if err != nil {
return whereStatement, datas, err
}
if whereStr != "" {
if isAnd {
groupWhereStatement += " AND " + whereStr
} else {
groupWhereStatement += " OR " + whereStr
}
for _, groupData := range groupDatas {
datas = append(datas, groupData)
}
} else {
return whereStatement, datas, errors.New(fmt.Sprintf("the %d group is invalid", i))
}
}
if groupWhereStatement != "" {
groupWhereStatement = "(" + groupWhereStatement + ")"
}
}
if whereStatement == "" {
whereStatement = groupWhereStatement
} else {
whereStatement = "(" + whereStatement + ")"
if groupWhereStatement != "" {
if isAnd {
whereStatement += " AND " + groupWhereStatement
} else {
whereStatement += " OR " + groupWhereStatement
}
}
}

return whereStatement, datas, nil
}

具体代码见https://github.com/hrf304/ukid.git
后续根据需求配合角色权限表可以实现数据权限控制

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐