三、从零开始-填坑
填上一章的坑,对 VO 的使用进行优化
导航
上一章地址:二、从零开始-用户管理
下一章地址:四、从零开始-优化用户管理新增
说明
- 贴代码时会贴整个类的全量代码,防止找不到我改的是哪个
- 创建的类在哪个包下不会单独说明,因为全量代码里有 package 直接看这个就可以了
- gitee 代码存放地址 https://gitee.com/mxw13579/study-scaffold 可以直接下下来看更加清晰
三、从零开始-填坑
3.1、填坑
上期不是还留了两个坑吗,一个是 VO 的转换,还有一个是查全量然后展示少数会浪费问题
3.1.1、VO 转换问题
这个是分为两项,一个是转换效率不高,一个是抽取公共
转换效率不高这个问题吧,怎么说呢,分页这玩意本来数据量就小,其实不改也不是不行
抽取公共的话,有两个思路,一个是去 DEBUG 跟一下他是什么时候转换为类型的,一个是写一个工具类
3.1.1.1、转换效率问题
这个的话采用 MapStruct 来做转换来处理。
别问为什么快,问就是 BeanUtil 这种方式采取的是反射向里写入数据,而 MapStruct 采取的是字节码生成一个带有 Get/Set 方法的转换方法,所以快。
当然区别只有在数据量比较大的情况下才能看出来,数据量小的话,我只能说根本没啥区别
首先导入依赖文件
<!-- mapStruct开始 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.4.2.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
<!-- mapStruct结束 -->
然后写一个接口
package com.lzl.study.scaffold.studyscaffold.common.mapstruct;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzl.study.scaffold.studyscaffold.user.entity.SysUserEntity;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserPageDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserSaveDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageHomeVo;
import org.mapstruct.Mapper;
/**
* @ClassName MapStructConv
* @Author lizelin
* @Description MapStruct 转换器
* 规定方法格式为
* convert+源类型+To+目标类型
* convertSysUserEntityToSysUserPageHomeVo
* @Date 2023-10-11 5:16
* @Version 1.0
*/
@Mapper(componentModel = "spring")
public interface MapStructConvert {
/**
* @param entity
* @return com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageHomeVo
* @Description SysUserEntity 转 SysUserPageHomeVo
* @author lizelin
* @date 2023-10-11 5:36
**/
SysUserPageHomeVo convertSysUserEntityToSysUserPageHomeVo(SysUserEntity entity);
/**
* @param dto
* @return com.lzl.study.scaffold.studyscaffold.user.entity.SysUserEntity
* @Description SysUserSaveDto 转 SysUserEntity
* @author lizelin
* @date 2023-10-11 6:34
**/
SysUserEntity convertSysUserSaveDtoToSysUserEntity(SysUserSaveDto dto);
/**
* @param dto
* @return com.lzl.study.scaffold.studyscaffold.user.entity.SysUserEntity
* @Description SysUserPageDto 转 SysUserEntity
* @author lizelin
* @date 2023-10-11 7:14
**/
SysUserEntity convertSysUserPageDtoToSysUserEntity(SysUserPageDto dto);
/**
* @param page
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page
* @Description Page 转 Page
* @author lizelin
* @date 2023-10-11 7:12
**/
Page convertPageToPage(Page page);
/**
* @param page
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page
* @Description SysUserPageDto 转 Page
* @author lizelin
* @date 2023-10-11 7:14
**/
Page convertSysUserPageDtoToPage(SysUserPageDto page);
}
说明一下写的格式
返回参数 方法名(传参)
比如说你想 A 类型转换为 B 类型
B xxxx(A)
方法名可以随便写,保证 A 类型的字段名和格式与 B 类型一致就可以了,不一致的转换方式后面用到了讲
但是在这个项目中由于使用到了反射调用,所以要按规定方法格式来写
然后 maven 打一下包,就会在 target/generated-sources/annotations/com/lzl/study/scaffold/studyscaffold/common/mapstruct/MapStructConvertImpl.java
生成一个实现类的文件
更改转换器也就搞定了
3.1.1.2、抽取公共方法
首先我们先将转换器抽取出来一个工具类
package com.lzl.study.scaffold.studyscaffold.common.mapstruct;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName MapStructConvertUtil
* @Author lizelin
* @Description MapStruct 转换工具类
* @Date 2023-10-11 5:53
* @Version 1.0
*/
public class MapStructConvertUtil {
private MapStructConvertUtil() {
throw new IllegalStateException("工具类不允许实例化");
}
private static MapStructConvert mapStructConvert;
static {
MapStructConvert bean = SpringUtil.getBean(MapStructConvert.class);
MapStructConvertUtil.mapStructConvert = bean;
}
/**
* @param list 分页数据
* @param tClass 转换目标类型
* @return java.util.List<T>
* @Description 转换 Page 的 records
* @author lizelin
* @date 2023-10-11 6:38
**/
public static <T,E> List<T> getRecords(List<E> list, Class<T> tClass) {
Object collect = list.stream().map(item -> mapStructConvert(item, tClass)).collect(Collectors.toList());
return (List<T>) collect;
}
/**
* @param source 源对象
* @param tClass 目标 class
* @return T
* @Description 将源对象转换为 目标对象
* @author lizelin
* @date 2023-10-11 6:37
**/
public static <T> T mapStructConvert(Object source, Class<T> tClass) {
Class<?> aClass = source.getClass();
String sourceName = aClass.getSimpleName();
String targetName = tClass.getSimpleName();
//拼接方法名
StringBuilder builder = StrUtil.builder();
builder.append("convert");
builder.append(sourceName);
builder.append("To");
builder.append(targetName);
String me = builder.toString();
try {
//反射调用方法
Method method = mapStructConvert.getClass().getMethod(me, aClass);
Object invoke = method.invoke(mapStructConvert, source);
return (T) invoke;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
采用反射的方式去调用转换器的方法,这样一个对象只用反射一次,然后直接调用 Get/Set 方法
不过这里还可以继续改进,用一个全局缓存存储 method 这样就不用每次都去反射找 method 了
然后我们将分页转换也做一个工具类
package com.lzl.study.scaffold.studyscaffold.common.util;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzl.study.scaffold.studyscaffold.common.mapstruct.MapStructConvertUtil;
import java.util.List;
/**
* @ClassName PageUtil
* @Author lizelin
* @Description 分页工具类
* @Date 2023-10-11 6:45
* @Version 1.0
*/
public class PageUtil {
private PageUtil() {
throw new IllegalStateException("工具类不允许实例化");
}
/**
* @param page
* @param tClass
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<T>
* @Description 转换 page
* @author lizelin
* @date 2023-10-11 6:50
**/
public static <T, E> Page<T> convertPage(Page<E> page, Class<T> tClass) {
List<E> records = page.getRecords();
Page<T> voPage = MapStructConvertUtil.mapStructConvert(page, Page.class);
voPage.setRecords(MapStructConvertUtil.getRecords(records, tClass));
return voPage;
}
}
这样公共方法就被抽取出来了,然后我们去修改一下 service 实现就搞定了
package com.lzl.study.scaffold.studyscaffold.user.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzl.study.scaffold.studyscaffold.common.mapstruct.MapStructConvertUtil;
import com.lzl.study.scaffold.studyscaffold.common.util.PageUtil;
import com.lzl.study.scaffold.studyscaffold.common.util.QueryWrapperBuildUtil;
import com.lzl.study.scaffold.studyscaffold.user.entity.SysUserEntity;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserPageDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserSaveDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageHomeVo;
import com.lzl.study.scaffold.studyscaffold.user.mapper.SysUserMapper;
import com.lzl.study.scaffold.studyscaffold.user.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @ClassName SysUserServiceImpl
* @Author lizelin
* @Description 用户管理 serviceImpl
* @Date 2023-10-09 19:58
* @Version 1.0
*/
@Service
@Slf4j
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService {
/**
* @param sysUserSaveDto
* @return java.lang.Boolean
* @Description 通过 dto 新增
* @author lizelin
* @date 2023-10-10 0:08
**/
@Override
public Boolean dtoSave(SysUserSaveDto sysUserSaveDto) {
SysUserEntity entity = MapStructConvertUtil.mapStructConvert(sysUserSaveDto, SysUserEntity.class);
return save(entity);
}
/**
* @param dto
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageVo>
* @Description 分页查询
* @author lizelin
* @date 2023-10-10 17:44
**/
@Override
public Page<SysUserPageHomeVo> dtoPage(SysUserPageDto dto) {
SysUserEntity entity = MapStructConvertUtil.mapStructConvert(dto, SysUserEntity.class);
Page<SysUserEntity> page = MapStructConvertUtil.mapStructConvert(dto, Page.class);
page(page, Wrappers.lambdaQuery(entity));
//转换分页
return PageUtil.convertPage(page, SysUserPageHomeVo.class);
}
}
然后我们进行测试
返回结果一切正常
VO 转换问题也就搞定了
然后我们在优化一下
/**
* @param source 源对象
* @param tClass 目标 class
* @return T
* @Description 将源对象转换为 目标对象
* @author lizelin
* @date 2023-10-11 6:37
**/
public static <T> T mapStructConvert(Object source, Class<T> tClass) {
Class<?> aClass = source.getClass();
String sourceName = aClass.getSimpleName();
String targetName = tClass.getSimpleName();
//拼接方法名
StringBuilder builder = StrUtil.builder();
builder.append("convert");
builder.append(sourceName);
builder.append("To");
builder.append(targetName);
String me = builder.toString();
try {
//反射调用方法
Method method = mapStructConvert.getClass().getMethod(me, aClass);
Object invoke = method.invoke(mapStructConvert, source);
return (T) invoke;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
看这里,每次过来都需要反射去拿他的方法,而实际上这个东西只要你方法名称不变,那么实际上也就意味着你执行的 method 不会变,因为我们之前规定过方法名称格式嘛,所以我们可以做一个缓存对他进行存储,就不需要再次反射拿方法了
首先引入 guava 包
<!-- guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
然后在 MapStructConvertUtil 上加一个缓存
package com.lzl.study.scaffold.studyscaffold.common.mapstruct;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
/**
* @ClassName MapStructConvertUtil
* @Author lizelin
* @Description MapStruct 转换工具类
* @Date 2023-10-11 5:53
* @Version 1.0
*/
public class MapStructConvertUtil {
private MapStructConvertUtil() {
throw new IllegalStateException("工具类不允许实例化");
}
private static MapStructConvert mapStructConvert;
/**
* Method 缓存 避免多次反射
*/
private static Cache<String, Method> methodCache;
static {
methodCache = CacheBuilder.newBuilder()
//初始容量
.initialCapacity(2048)
.maximumSize(2000)
.build();
MapStructConvert bean = SpringUtil.getBean(MapStructConvert.class);
MapStructConvertUtil.mapStructConvert = bean;
}
/**
* @param list 分页数据
* @param tClass 转换目标类型
* @return java.util.List<T>
* @Description 转换 Page 的 records
* @author lizelin
* @date 2023-10-11 6:38
**/
public static <T, E> List<T> getRecords(List<E> list, Class<T> tClass) {
Object collect = list.stream().map(item -> mapStructConvert(item, tClass)).collect(Collectors.toList());
return (List<T>) collect;
}
/**
* @param source 源对象
* @param tClass 目标 class
* @return T
* @Description 将源对象转换为 目标对象
* @author lizelin
* @date 2023-10-11 6:37
**/
public static <T> T mapStructConvert(Object source, Class<T> tClass) {
Class<?> aClass = source.getClass();
String sourceName = aClass.getSimpleName();
String targetName = tClass.getSimpleName();
//拼接方法名
StringBuilder builder = StrUtil.builder();
builder.append("convert");
builder.append(sourceName);
builder.append("To");
builder.append(targetName);
String me = builder.toString();
try {
Method present = methodCache.getIfPresent(me);
if (present == null) {
//反射获取方法
present = mapStructConvert.getClass().getMethod(me, aClass);
methodCache.put(me, present);
}
Object invoke = present.invoke(mapStructConvert, source);
return (T) invoke;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
这样也就搞定了
3.1.2、浪费问题
查全量然后展示少数会浪费问题,这个问题的话,实际上就是我们在查询的时候指定查询哪些字段
而这个问题的话,我们可以通过在 生成 QueryWrapper 的时候去调用他的 select 方法来得到指定
那现在问题就来了,能指定那么改如何获取字段呢?
**通过反射的方式获取 VO 的字段,并且设置到 QueryWrapper **
我们来做一个生成 QueryWrapper 的工具类
package com.lzl.study.scaffold.studyscaffold.common.util;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.lang.reflect.Field;
/**
* @ClassName QueryWrapperBuildUtil
* @Author lizelin
* @Description 查询包装 构建工具类
* @Date 2023-10-10 18:33
* @Version 1.0
*/
public class QueryWrapperBuildUtil {
/**
* 缓存 避免多次反射
*/
private static Cache<Class, String[]> tableFideCache;
static {
tableFideCache = CacheBuilder.newBuilder()
//初始容量
.initialCapacity(2048)
.maximumSize(2000)
.build();
}
private QueryWrapperBuildUtil() {
throw new IllegalStateException("工具类不允许实例化");
}
/**
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
* @Description 获取 QueryWrapper
* @author lizelin
* @date 2023-10-10 17:52
**/
public static <T> QueryWrapper<T> buildQueryWrapper(T obj) {
return Wrappers.query(obj);
}
/**
* @param obj 期望的条件实体
* @return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<T>
* @Description 获取 LambdaQueryWrapper
* @author lizelin
* @date 2023-10-12 18:19
**/
public static <T> LambdaQueryWrapper<T> buildLambdaQueryWrapper(T obj) {
return Wrappers.lambdaQuery(obj);
}
/**
* @param obj 期望的条件实体
* @param voClass 希望查的字段
* @return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<T>
* @Description 获取指定 vo 字段的 QueryWrapper
* @author lizelin
* @date 2023-10-12 18:19
**/
public static <T> LambdaQueryWrapper<T> buildLambdaQueryWrapper(T obj, Class<?> voClass) {
QueryWrapper<T> query = Wrappers.query(obj);
String[] voTableFide = tableFideCache.getIfPresent(voClass);
if (voTableFide == null) {
voTableFide = getVoTableFide(voClass);
tableFideCache.put(voClass, voTableFide);
}
query.select(voTableFide);
return query.lambda();
}
/**
* @param voClass vo
* @return java.lang.String[]
* @Description 获取 vo 存在的字段
* @author lizelin
* @date 2023-10-12 18:18
**/
private static String[] getVoTableFide(Class<?> voClass) {
Field[] fields = voClass.getDeclaredFields();
String[] fieldsStr = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
String underlineCase = CharSequenceUtil.toUnderlineCase(fieldName);
fieldsStr[i] = underlineCase;
}
return fieldsStr;
}
}
然后去改造一下实现类
package com.lzl.study.scaffold.studyscaffold.user.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzl.study.scaffold.studyscaffold.common.mapstruct.MapStructConvertUtil;
import com.lzl.study.scaffold.studyscaffold.common.util.PageUtil;
import com.lzl.study.scaffold.studyscaffold.common.util.QueryWrapperBuildUtil;
import com.lzl.study.scaffold.studyscaffold.user.entity.SysUserEntity;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserPageDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.dto.SysUserSaveDto;
import com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageHomeVo;
import com.lzl.study.scaffold.studyscaffold.user.mapper.SysUserMapper;
import com.lzl.study.scaffold.studyscaffold.user.service.SysUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @ClassName SysUserServiceImpl
* @Author lizelin
* @Description 用户管理 serviceImpl
* @Date 2023-10-09 19:58
* @Version 1.0
*/
@Service
@Slf4j
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService {
/**
* @param sysUserSaveDto
* @return java.lang.Boolean
* @Description 通过 dto 新增
* @author lizelin
* @date 2023-10-10 0:08
**/
@Override
public Boolean dtoSave(SysUserSaveDto sysUserSaveDto) {
SysUserEntity entity = MapStructConvertUtil.mapStructConvert(sysUserSaveDto, SysUserEntity.class);
return save(entity);
}
/**
* @param dto
* @return com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.lzl.study.scaffold.studyscaffold.user.entity.vo.SysUserPageVo>
* @Description 分页查询
* @author lizelin
* @date 2023-10-10 17:44
**/
@Override
public Page<SysUserPageHomeVo> dtoPage(SysUserPageDto dto) {
SysUserEntity entity = MapStructConvertUtil.mapStructConvert(dto, SysUserEntity.class);
Page<SysUserEntity> page = MapStructConvertUtil.mapStructConvert(dto, Page.class);
page(page, QueryWrapperBuildUtil.buildLambdaQueryWrapper(entity, SysUserPageHomeVo.class));
//转换分页
return PageUtil.convertPage(page, SysUserPageHomeVo.class);
}
}
然后看一下效果如何
可以看到是生效了的
但是这个时候就发现了一个小问题,ID 没有出来,反射的时候取字段的话只能取到当前类的字段,所以我们得优化一下方法,将父类的字段也给取出来
package com.lzl.study.scaffold.studyscaffold.common.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName QueryWrapperBuildUtil
* @Author lizelin
* @Description 查询包装 构建工具类
* @Date 2023-10-10 18:33
* @Version 1.0
*/
public class QueryWrapperBuildUtil {
/**
* 缓存 避免多次反射
*/
private static Cache<Class<?>, String[]> tableFideCache;
static {
tableFideCache = CacheBuilder.newBuilder()
//初始容量
.initialCapacity(2048)
.maximumSize(2000)
.build();
}
private QueryWrapperBuildUtil() {
throw new IllegalStateException("工具类不允许实例化");
}
/**
* @return com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
* @Description 获取 QueryWrapper
* @author lizelin
* @date 2023-10-10 17:52
**/
public static <T> QueryWrapper<T> buildQueryWrapper(T obj) {
return Wrappers.query(obj);
}
/**
* @param obj 期望的条件实体
* @return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<T>
* @Description 获取 LambdaQueryWrapper
* @author lizelin
* @date 2023-10-12 18:19
**/
public static <T> LambdaQueryWrapper<T> buildLambdaQueryWrapper(T obj) {
return Wrappers.lambdaQuery(obj);
}
/**
* @param obj 期望的条件实体
* @param voClass 希望查的字段
* @return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<T>
* @Description 获取指定 vo 字段的 QueryWrapper
* @author lizelin
* @date 2023-10-12 18:19
**/
public static <T> LambdaQueryWrapper<T> buildLambdaQueryWrapper(T obj, Class<?> voClass) {
QueryWrapper<T> query = Wrappers.query(obj);
String[] voTableFide = tableFideCache.getIfPresent(voClass);
if (voTableFide == null) {
voTableFide = getVoTableFide(voClass);
tableFideCache.put(voClass, voTableFide);
}
query.select(voTableFide);
return query.lambda();
}
/**
* @param voClass vo
* @return java.lang.String[]
* @Description 获取 vo 存在的字段
* @author lizelin
* @date 2023-10-12 18:18
**/
private static String[] getVoTableFide(Class<?> voClass) {
List<Field> fields = new ArrayList();
getTableFide(voClass, fields);
String[] fieldsStr = new String[fields.size()];
for (int i = 0; i < fields.size(); i++) {
Field field = fields.get(i);
String fieldName = field.getName();
String underlineCase = CharSequenceUtil.toUnderlineCase(fieldName);
fieldsStr[i] = underlineCase;
}
return fieldsStr;
}
/**
* @param aClass
* @param fields
* @return java.lang.String[]
* @Description 递归 取得父类字段
* @author lizelin
* @date 2023-10-12 18:44
**/
private static void getTableFide(Class<?> aClass, List<Field> fields) {
Field[] aClassDeclaredFields = aClass.getDeclaredFields();
//排除掉 序列化版本 ID
for (Field item : aClassDeclaredFields) {
if (!StrUtil.equals("serialVersionUID", item.getName())) {
fields.add(item);
}
}
Class<?> superclass = aClass.getSuperclass();
if (superclass != Object.class) {
getTableFide(superclass, fields);
}
}
我们新增了一个 getTableFide 方法,通过递归的方式,取出来父类存在的字段,这样就解决了问题
这里就可以看到效果了