#java #mybatis #PageHelper #PageInfo #泛型
背景
通常在使用 Mybatis PageHelper 插件时,会将 PageInfo 对象直接作为 response 返回。
经常会遇到如下类似的场景:
controller 层返回的 PageInfo 泛型类型通常会定义为 VO 等类型。但是在 mapper 层,返回的 PageInfo 对象通常是 model 类型。
所以返回的时候还需要有很多手动处理类型转换的代码。造成代码很臃肿,类似的代码在项目中会出现很多。
目标
提供一个工具类,将相同的代码封装起来,可变的部分暴露给开发者自己实现。
工具类
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import java.util.List;
import java.util.stream.Collectors;
public class PageInfoUtil {
@FunctionalInterface
public interface PageInfoConvertor<T, R> {
/**
* convert 将 T 类型对象转换为 R 类型对象
*
* @param t 原始类型对象
* @return 目标类型对象
*/
R convert(T t);
}
/**
* convertPageInfo 转换 PageInfo 泛型类型
*
* @param sourcePageInfo 原始的 pageInfo 对象
* @param convertor 自定义转换器
* @param <T> 原始类型
* @param <R> 目标类型
* @return 转换之后的 PageInfo 对象
*/
public static <T, R> PageInfo<R> convertPageInfo(PageInfo<T> sourcePageInfo, PageInfoConvertor<T, R> convertor) {
Page<R> page = new Page<>(sourcePageInfo.getPageNum(), sourcePageInfo.getPageSize());
page.setTotal(sourcePageInfo.getTotal());
PageInfo<R> targetPageInfo = new PageInfo<>(page);
List<R> targetList = sourcePageInfo.getList().stream().map(convertor::convert).collect(Collectors.toList());
targetPageInfo.setList(targetList);
return targetPageInfo;
}
/**
* convertPageInfo 转换 PageInfo 泛型类型
*
* @param sourcePageInfo 原始的 pageInfo 对象
* @param targetClazz 需要转换的 PageInfo 泛型类型
* @param <T> 原始类型
* @param <R> 目标类型
* @return 转换之后的 PageInfo 对象
*/
public static <T, R> PageInfo<R> convertPageInfo(PageInfo<T> sourcePageInfo, Class<R> targetClazz) {
Page<R> page = new Page<>(sourcePageInfo.getPageNum(), sourcePageInfo.getPageSize());
page.setTotal(sourcePageInfo.getTotal());
PageInfo<R> targetPageInfo = new PageInfo<>(page);
List<R> targetList = sourcePageInfo.getList().stream().map(e -> {
try {
R r = targetClazz.getDeclaredConstructor().newInstance();
BeanUtils.copyProperties(e, r);
return r;
} catch (Exception exception) {
throw new RuntimeException("convertPageInfo cause exception", exception);
}
}).collect(Collectors.toList());
targetPageInfo.setList(targetList);
return targetPageInfo;
}
}
提供两个方法:
convertPageInfo(PageInfo<T> sourcePageInfo, PageInfoConvertor<T, R> convertor)
其中 PageInfoConvertor 是一个函数式接口,用户可以在开发的时候自定义泛型类型的转换规则。
有时候我们需要转换的类型中部分字段需要其他的业务逻辑处理,就可以采用这种方式。
convertPageInfo(PageInfo<T> sourcePageInfo, Class<R> targetClazz)
通过第二参数指定泛型转换的类型,该方法内部是通过 BeanUtils.copyProperties() 方法做类型转换的。
当原类型和目标类型属性一致的场景下个,可以采用这种方式。
使用
指定泛型转换类型:
PageInfo<Bean2> targetPageInfo = PageInfoUtil.convertPageInfo(pageInfo, Bean2.class);
自定义转换规则:
PageInfo<Bean2> targetPageInfo = PageInfoUtil.convertPageInfo(pageInfo, (bean1) -> {
Bean2 bean2 = new Bean2();
bean2.setName(bean1.getName());
return bean2;
});
完事!🎉🎉🎉🎉