open-hand / choerodon-starters

This is the toolkit developed by Choerodon and provides some basic dependencies for use in the development process.
http://choerodon.io
Apache License 2.0
78 stars 64 forks source link

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

Closed RavenCM closed 5 years ago

RavenCM commented 5 years ago
// 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'.
superlee007 commented 5 years ago

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

superlee007 commented 5 years ago

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

RavenCM commented 5 years ago

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

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

RavenCM commented 5 years ago

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

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

superlee007 commented 5 years ago

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

RavenCM commented 5 years ago

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