open-hand/choerodon-starters

[master] SqlServerParser排序列自动拼接到SQL查询列中的问题

Closed this issue · 6 comments

// io/choerodon/mybatis/pagehelper/parser/SqlServerParser.java:449
selectMap.put(expItem.getExpression().toString(), expItem);

上句代码将查询字段中的别名也作为KEY存到了Map中。

// io/choerodon/mybatis/pagehelper/parser/SqlServerParser.java:469
SelectExpressionItem selectExpressionItem = selectMap.get(expression.toString());

上句代码判断排序列是否存在于查询列中时去获取KEY是否存在,排序字段是可以不写表别名的,而且@io.choerodon.mybatis.pagehelper.annotation.SortDefault注解中指定的排序字段也不会添加表别名。
当多表关联,并且排序字段存在于多表中,又没有写表别名时,会抛出异常

com.microsoft.sqlserver.jdbc.SQLServerException: Ambiguous column name 'xxx'.

你这种情况应该是doPageAndSort的使用中没有设置别名map,看下我提的issue,里面有一些用法

动态拼接的排序字段,某些表单一般是事先确定好的,也就是要和产品沟通表单具体那些列要排序,之后开发者就根据sql设置别名了,不一定每个字段都要放到map里面。

动态拼接的排序字段,某些表单一般是事先确定好的,也就是要和产品沟通表单具体那些列要排序,之后开发者就根据sql设置别名了,不一定每个字段都要放到map里面。

刚用了一下确实可以。
pageRequest.resetOrder("hm", Collections.emptyMap());

动态拼接的排序字段,某些表单一般是事先确定好的,也就是要和产品沟通表单具体那些列要排序,之后开发者就根据sql设置别名了,不一定每个字段都要放到map里面。

有一个问题就是这种方法把SQL别名硬编码到Java代码中,而且如果有新的排序字段,是需要修改代码的。个人还是觉得修改一下这个判断比较好,你们可以判断一下框架会不会做调整,不做调整的话我们准备覆盖。

嗯,是的,这种硬编码方式确实不好,开发这个功能的时候,对于这种join的关联查询,前端的排序字段和xml里面的数据库字段无法建立直接关系,牵扯到别名的问题就更不好处理了,所以就采取了一个map建立映射,在开发过程中让开发者决定这种映射关系,我最近也在考虑怎么处理这个问题,或者你那边有什么解决方案可以讨论下 :p

如果只是上边的这个问题的话:我打算如果列有别名就取别名作为Map的key,如果没有别名的话取列名称作为前缀,如果列名称带有表前缀,将去掉表前缀的列名也作为key。