我的需求

我现在有一个接口查询用户列表 User ,返回的字段没有实体类那么多,于是我自定义了一个vo类比如 TmpVo。希望能做成如下结果:

        LambdaQueryWrapper<User> wrapper = Wrappers.<User>lambdaQuery();
        List<TmpVo> list = this.list(wrapper);

但是我发现没什么卵用,返回的还是User实体类的字段。

我的尝试

然后有两个设置entity的方法:

wrapper.setEntityClass()
wrapper.setEntity()

但是这两个方法的泛型约束了只能传入User实体类的子类。

曲线救国

使用BeanUtil.copy的方法将属性复制

        List<TmpVo> list = new ArrayList<>();
        list.stream().forEach(item -> {
            TmpVo vo = new TmpVo();
            BeanUtils.copyProperties(item,vo);
            list.add(vo);
        });

这种方式确实可以返回自定义的实体类,但是影响性能,如果返回集合数量比较多,而vo类的属性也比较多时就很慢了。

改进方式

使用stream的并行方式 parallelStream(注意多线程并发问题)

        List<TmpVo> list = new CopyOnWriteArrayList<>(); (或者使用Collections.synchronizedList(list)将集合转为并发的集合)
        list.parallelStream().forEach(item -> {
            TmpVo vo = new TmpVo();
            BeanUtils.copyProperties(item,vo);
            list.add(vo);
        });

那么这样确实可以提高速度,但是注意 parallelStream 并行流底层使用的时 forkjoin框架,默认全局使用同一个线程池,也就是说整个项目的的 parallelStream 都是共用一个线程池,越往后线程池数量越多,处理越慢。 解决方案就是自定义线程池,但是自定义多少,定义几个合适也是个问题。

也有人说写 sql来解决,可是我使用plus的目的就是为了不写sql,这跟我的初衷背离了。一个很简单的映射居然要搞得这么复杂,为什么? 我刚使用plus两个月,也许是我没有找到办法,还请大佬指点迷津。

如果楼下有人喷我,请不要喷我的脸,因为我要靠他吃饭。😄

Comment From: miemieYaho

不能,这是mybatis规定的

Comment From: zhuzhenwen-github

推荐使用mapstruct,目前我项目从数据库查询出来的entity转vo对象 都是通过mapstruct做转换,挺好用的

Comment From: chf-gh

不能,这是mybatis规定的

是mybatis 规定的还是 mybatisplus规定的?是否存在改进的可能性?