版权声明:严禁用于任何商业用途的转发,转载请说明出处!
数据库中某张用于zTree结构的表,tree_sorts排序字段结构是:
10,20,10,
10,100,10,
这种结构,此时直接用order by 对tress_sorts字段升序排序会将10,100,10, 排到前面去
此类情况在SQL中可以用以下方式解决掉:
to_number(REGEXP_SUBSTR(field, '[^,]+', start_position, nth_appearance)) NULLS FIRST
完整查询代码如下:
select a.menu_name as treeName , a.* from sys_menu a
order by to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, 1)) NULLS FIRST,
to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, 2)) NULLS FIRST,
to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, 3)) NULLS FIRST,
to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, 4)) NULLS FIRST;
1. java中如何拼接order by 排序条件:重点是如何确定循环几次可以得到所有拆分后的tree_sorts
我的解决思路是实体对应的表中增加一个tree_level(层次级别)的字段来控制循环次数
/**
* 返回该实体类物理表中最大层级
* @param entity
* @return
*/
private int getMaxTreeLevel(T entity){
QueryWrapper<T> queryWrapper = new QueryWrapper<T>(entity);
List<T> list = super.list(queryWrapper);
int maxLevel = 0;
for (int i = 0; i < list.size(); i++) {
int _treeLevel = ((TreeEntity)list.get(i)).getTreeLevel();
if (_treeLevel > maxLevel){
maxLevel = _treeLevel;
}
}
return maxLevel;
}
2. 拆分tree_sorts后拼接一个String
/**
* 该方法用于构建 order by 排序条件,返回 字符串类型,如果用@select注解构建order by时,注意要使用 ${orderByStr} 传入
* 当treeData的实体类排序字段为此类结构时:10,20,30, 此时排序可能存在问题
* to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, " + (i + 1) + ")) NULLS FIRST 可以拆分该字段
* @param entity
* @return
*/
public String orderByString(T entity){
int maxLevel = getMaxTreeLevel(entity);
StringBuffer sb = new StringBuffer();
for (int i = 0; i <= maxLevel ; i++) {
if (i == 0){
sb.append("to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, " + (i + 1) + ")) NULLS FIRST");
}else {
sb.append(",to_number(REGEXP_SUBSTR(tree_sorts, '[^,]+', 1, " + (i + 1) + ")) NULLS FIRST");
}
}
return sb.toString();
}
3. 重点:
3.1 QueryWrapper方式排序时,不能使用orderBy此类排序方法,因为不论任何一个方法都会自动追加 asc或desc,用last方法写入order by。
queryWrapper.last("order by " + this.orderByString(entity));
3.2 @select方式:
注意:传参时要用${},#{}会把参数识别为 一整个字符串
@Select("select a.menu_name as treeName , a.* from sys_menu a order by ${orderByStr}")
List<Menu> getAllMenus(@Param("orderByStr")String orderByStr);