问题描述
在 Mybatis 中使用 PageHelper 插件可以轻易的实现分页查询,但是对于某些时候,从库中直接返回的 Po 对象并不是最终需要返回的类型,即分页中的结果集需要进行类型转换,当然,转换过程中不能丢失分页信息。
分析
通过观察 PageHelper 插件的源码可以知道,其分页结果为 Page
对象,继承了 ArrayList
对象,其结果集通过泛型来约束类型。而实际上,java 中的泛型类型约束偏向于编译器层面,即由编译器对泛型进行类型检查,一旦编译通过,最终会转换为原始类型,称之为类型(泛型)擦除,正是有这样的机制存在,此处可以较为简单的实现对分页结果的类型转换。
解决方案
思路
- 启动分页器,执行查询 sql 执行分页,设定结果集类型未
T
; - 提取分页结果并进行类型转换,设转换类型为
E
,保存结果为result
(List<E>
) 变量; - 对分页对象
Page<T>
执行其继承自父类的ArrayList#clear()
方法,清除原结果集; - 对
Page<T>
对象进行显示的强转,转换结果类型与result
(E
) 变量保持一致,此处会出现编译器警告,但实际上由于类型擦除的机制存在,在编译后的类型始终是原始类型Page
,(且已经提前清空了强转之前的泛型类型对象)因此此处忽略警告对编译结果不会造成异常影响; - 最后将转换的结果
result
置入强转后的Page<E>
对象中。
代码
1 | public class PageHelpers<K, E> { |
其他
当然,使用 BeanUtils#copyProperties()
复制对象的属性,或者使用反射提取其字段,都是可以实现对分页结果的类型转换。