博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Springboot + easyui + mybatis 高级搜索功能实现
阅读量:4073 次
发布时间:2019-05-25

本文共 6225 字,大约阅读时间需要 20 分钟。

最近接了个项目,客户要求项目支持高级搜索,他可以自选字段,然后自选运算符,然后输入值,字段可随意组合,类似于下图。

1 前端处理 

 

遇到问题首先抽象:

 字段类型一般有4种,第一种普通输入框,第二种日期,第三种数字,第四种下拉。

 如果是下拉的话,只支持精确匹配  =, 其他的支持所有的运算符。

 按照我的性格,这个高级搜索功能肯定是要配置出来的,而不是傻乎乎的写html代码。

 首先确定配置JSON 文件格式,然后做通用页面,解析配置,配置比较简单,就不多解释了

var advanceConfig = [{name:'name',title:'人员姓名',type:'input'},{name:'sex',title:'性别',type:'book',code:'sex'},{name:'birthday',title:'出生年月',type:'date',formart:'yyyy-MM'},{name:'primaryClassification',title:'一级分类',type:'book',code:'primary_classification'},];

 然后写公共代码。

 

添加

 经过上面的代码,前段基本处理完成,下面讲解后端代码如何处理。

 

2 后端处理 

     首先在VO中创建接收前段搜索条件的字段。

    

/**     * 高级搜索过滤条件     */    @Transient    private String extAdvanceFilterParam;

  然后写格式化sql的代码。

  

private static final Map
SIMPLE_OPERATOR = new HashMap(); static { SIMPLE_OPERATOR.put(POJOConstant.EQ, " = "); SIMPLE_OPERATOR.put(POJOConstant.LIKE, " LIKE "); SIMPLE_OPERATOR.put(POJOConstant.NEQ, " != "); SIMPLE_OPERATOR.put(POJOConstant.BIGGER_EQ, " >= "); SIMPLE_OPERATOR.put(POJOConstant.LESS_EQ, " <= "); SIMPLE_OPERATOR.put(POJOConstant.LESS, " < "); SIMPLE_OPERATOR.put(POJOConstant.START_WITH, " LIKE "); SIMPLE_OPERATOR.put(POJOConstant.END_WITH, " LIKE "); SIMPLE_OPERATOR.put(POJOConstant.BIGGER, " > "); } /** * 获取高级搜索的where条件 * * @return */ public String getAdvanceSearchSql() { if (extAdvanceFilterParam == null) { return null; } JSONObject extAdvanceFilterParamJson = JSON.parseObject(extAdvanceFilterParam); String filterType = " OR "; boolean isOr = true; if (extAdvanceFilterParamJson.getString("filterType").equals("and")) { filterType = " AND "; isOr = false; } JSONArray extAdvanceFilterParamArray = extAdvanceFilterParamJson.getJSONArray("extAdvanceFilterParamArray"); JSONObject tempAFilter = null; Field field = null; String sqlField = null; String tempVal = null; StringBuilder whereSql = new StringBuilder(isOr ? " AND (" : " AND "); boolean isHashWhere = false; for (int i = 0; i < extAdvanceFilterParamArray.size(); i++) { tempAFilter = extAdvanceFilterParamArray.getJSONObject(i); field = ReflectUtils.getDeclaredField(this.getClass(), tempAFilter.getString("name")); if (field == null) { log.error("字段不存在:" + field); continue; } sqlField = getSqlField(field); tempVal = formartVal(field, tempAFilter.get("val"), tempAFilter.getString("filterType"), tempAFilter.getString("searchKeyType") , tempAFilter.getString("fieldName")); if (sqlField == null || tempVal == null || !SIMPLE_OPERATOR.containsKey(tempAFilter.getString("filterType"))) { log.error("条件不满足,无法拼接此字段,详情请打断点:" + field); continue; } if (whereSql.length() > 6) { whereSql.append(filterType); } whereSql.append(sqlField + ("searchKey".equals(field.getName()) ? " LIKE " : SIMPLE_OPERATOR.get(tempAFilter.getString("filterType"))) + tempVal + " "); isHashWhere = true; } if(!isHashWhere){ return ""; } whereSql.append(isOr ? ")" : ""); return whereSql.toString(); } /** * 格式化值 * * @param field lambdaSett * @param val 值 * @param filterType * @return 值的sql格式 */ protected String formartVal(Field field, Object val, String filterType, String searchKeyType, String fieldName) { if (val == null || "null".equals(val)) { return "null"; } Class
type = field.getType(); String result = null; // 字符串直接是字段名 if (!CheckUtils.isNullOrEmpty(searchKeyType)) { if ("str".equals(searchKeyType)) { return " CONCAT('%','\"" + fieldName + "\"','%','" + val + "','%') "; } if ("streq".equals(searchKeyType)) { return " CONCAT('%','\"" + fieldName + "\":\"" + val + "\"','%') "; } else if ("date".equals(searchKeyType)) { return " CONCAT('%','\"" + fieldName + "\":\"" + val + "','%') "; } else if ("int".equals(searchKeyType)) { return " CONCAT('%','\"" + fieldName + "\":\"" + val + "\"','%') "; } } //只有字符串才有like 需要特殊处理 if (type == String.class) { if (POJOConstant.LIKE.equals(filterType)) { result = " CONCAT('%','" + val + "','%') "; } else if (POJOConstant.START_WITH.equals(filterType)) { result = " CONCAT('" + val + "','%') "; } else if (POJOConstant.END_WITH.equals(filterType)) { result = " CONCAT('%','" + val + "') "; } else { result = "'" + val + "'"; } } else if (type == Number.class || Number.class.isAssignableFrom(type)) { result = ConverterUtils.toString(val); } else if (type == Date.class || Date.class.isAssignableFrom(type)) { Date dateVal = DateUtils.parseStr(ConverterUtils.toString(val)); return "FROM_UNIXTIME(" + (dateVal.getTime() / 1000) + ")"; } else { log.warn("格式不支持:" + field + val); return null; } return result; } public String getSqlField(Field field) { if (field.isAnnotationPresent(TableField.class)) { TableField tableField = field.getAnnotation(TableField.class); if (tableField.exist()) { return tableField.value(); } else { return null; } } else if (field.isAnnotationPresent(Column.class)) { Column column = field.getAnnotation(Column.class); return column.name(); } return null; }

通过上面代码,基本上已经把sql拼接出来了,如果觉得不安全可以加个sql的过滤,如果有人故意黑,可以抛异常。

有了sql 之后拼到查询语句中就可以了。

 

转载地址:http://chwni.baihongyu.com/

你可能感兴趣的文章
游戏测试的技术难点和测试技术
查看>>
线程简介
查看>>
线程挂起自己,让出CPU
查看>>
线程同步(C# 编程指南)
查看>>
创建高效的线程安全类的步骤
查看>>
Failed to load class "org.slf4j.impl.StaticLoggerB
查看>>
使用 Apache MINA 2 开发网络应用
查看>>
MANIFEST.MF文件的格式
查看>>
NIO入门-了解Buffer
查看>>
database如何管理超过4GB的文件
查看>>
[转载]java.util.concurrent.ConcurrentHashMap 如何在不损失线程安全的同时提供更高的并发性...
查看>>
sun game server (sgs)初探
查看>>
類別 ConcurrentHashMap<K,V>的更新,删除
查看>>
如何使用Flex 4新的CSS语法,兼容halo组件
查看>>
flex addChild 的一个小细节
查看>>
Future模式,探讨mina中的Iofuture
查看>>
Java动态数组
查看>>
人生时间表. 如果您有了时间
查看>>
Adobe Flash gets its full launch on Android
查看>>
java.nio.BufferOverflowException
查看>>