@记录mysql order by和limit未一起使用导致数据无效
首先解释一下遇到的数据库查询问题:
我在sql查询语句都是默认写order by和limit进行排序和分页,使用起来非常正常。但这次偶然遇到一个需求,需要查询所有数据,所以我将limit分页条件语句去掉,于是就出现order by 语句不论怎么写都不生效,所有数据都能正确地根据条件查询到,但数据的排序未按照order by 的规则,order by写了等于没写,被mysql直接忽略了。
下面是sql代码
SELECT * FROM( <!
(
SELECT
COUNT(1) AS id
, NULL AS field_id, NULL AS book_by, NULL AS serial_code, NULL AS book_time_count
, NULL AS book_time, NULL AS create_by, NULL AS update_by, NULL AS create_time
, NULL AS update_time, NULL AS active ,NULL AS book_time_unit
,NULL AS field_area_code,NULL AS field_name,NULL AS field_type
,NULL AS price_unit,NULL AS field_img,NULL AS user_phone
FROM field_book as T LEFT JOIN field T1 ON T.field_id = T1.id
LEFT JOIN sys_user T2 ON T.book_by = T2.user_name
WHERE ${ew.sqlSegment}
)
UNION
(
SELECT
T.id
, T.field_id, T.book_by, T.serial_code, T.book_time_count
, T.book_time, T.create_by, T.update_by, T.create_time
, T.update_time, T.active,T1.book_time_unit
,T1.field_area_code,T1.field_name,T1.field_type
,T1.price_unit,T1.field_img,T2.phonenumber
FROM field_book as T LEFT JOIN field T1 ON T.field_id = T1.id
LEFT JOIN sys_user T2 ON T.book_by = T2.user_name
WHERE ${ew.sqlSegment}
ORDER BY T.book_time
${ew.pageSql}
)
)AS T3
;
这段上面半块是查总数的,主要看UNION的下面半块代码,${ew.sqlSegment}是mybatisplus的wrapper原生的where语句输出方法,不重要
ew.pageSql则是单纯输出“LIMIT1,10”的分页语句现在这段sql所查数据的问题就在于,如果{ew.pageSql}则是单纯输出“ LIMIT 1,10 ”的分页语句 现在这段sql所查数据的问题就在于,如果ew.pageSql则是单纯输出“LIMIT1,10”的分页语句现在这段sql所查数据的问题就在于,如果{ew.pageSql}输出空串,不输出“ LIMIT 1,10 ”,也就是这段sql语句不分页查询mysql排序,它上一行的order by也会跟着失效。
简而言之,limit和order by得一起混用,否则order by会离奇地失效。
解决办法是把limit加回去,写成比如limit 1 ,100000这样
PS:
关于${ew.sqlSegment},在mybatisplus源码里,ew通常代表wrapper实体,sqlSegment是一个官方封装好的方法,输出的字符串就是 sql ,是经过Wrapper拼凑的where语句
此图是xml对应的dao层mapper中的一个接口
@Param( Constants.WRAPPER )这个注解,Constants.WRAPPER就是“ew”
排除所有其它原因以后,现在进入正题
关键就在这个 ${ew.pageSql} 的有和无,此方法是我自己写到wrapper里面的,作用只是输出sql的字符串

具体用法在服务层实现类通过setPage方法赋值,用法如下
这是setPage方法的实现,

setPage这个方法3个入参中,第三个pageAble有默认值true,前端只需要把pageAble传入false,setPage就不执行, ${ew.pageSql}就会输出空串“”
至于SuperWrapper,是我写的一个比较好用的Wrapper封装,用法也很方便,我平常就这样在MVC服务层的实现写代码,如下
SuperWrapper spWrapper = new SuperWrapper()
.setPage( params.getPageNum() , params.getPageSize() , params.getPageAble() )
.ne( "T.active" , 0 );
if ( param != null ) {
spWrapper
.likes( "T2.phonenumber" , param.getUserPhone() )
.likes( "T.id" , param.getId() )
.likes( "T.field_id" , param.getFieldId() )
.likes( "T.book_by" , param.getBookBy() )
.likes( "T.serial_code" , param.getSerialCode() )
.likes( "T.book_time_count" , param.getBookTimeCount() )
.likes( "T.book_time" , param.getBookTime() )
.likes( "T.create_by" , param.getCreateBy() )
.likes( "T.update_by" , param.getUpdateBy() )
.likes( "T.create_time" , param.getCreateTime() )
.likes( "T.update_time" , param.getUpdateTime() )
.likes( "T.active" , param.getActive() )
.betweens( "T.create_time" , param.getTimeRange() )
;
spWrapper.betweens( "T.book_time", bookDay );
List< FieldBookDataVo > DTOList = fieldBookMapper.query( spWrapper );
我后续还会继续写关于我的SuperWrapper的奇特用法,比如很多个wrapper放进同一个wrapper里面,生成非常复杂的复合sql语句,想进一步了解可以互相学习关注一下
(编辑:92站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|