网站建设合同严瑾,做的网站老是掉线,中国做网站公司排名,郑州 网站设计easy.server.mapper 介绍
后端开发中#xff0c;消息转换常见问题
Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean
以上的三个问题是最常见的消息转换困扰。
以Map 举例
常见做法是
手动转换
MapString,Object da…easy.server.mapper 介绍
后端开发中消息转换常见问题
Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean
以上的三个问题是最常见的消息转换困扰。
以Map 举例
常见做法是
手动转换
MapString,Object dataMap;
Person person;person.setXX(dataMap.get(XXX))..................弊端是 操作繁琐
采用反射技术实现 MapString,Object dataMap;final ClassPerson personClass Person.class;Object person personClass.newInstance();final Field[] fields personClass.getDeclaredFields();for (Field field : fields) {// 特殊类型if (Modifier.isFinal(field.getModifiers())) {continue;}field.setAccessible(Boolean.TRUE);field.set(person, dataMap.get(field.getName()));}操作简单弊端是存在性能消耗
easy.server.mapper 解决实现
final ClassPerson personClass Person.class;Person person BeanCopier2Utils.getFullData2Object(Person.class).toMapConverter(dataMap);操作简单性能几乎同 手动转换
性能与反射对比
public class ReflectTest {public static boolean warmup false;private MapString, Object data new HashMap();private MapString, Object dataMap new TreeMapString, Object() {{put(grep, 1234);put(name, liaojl);put(age, 26);put(birthday, new Date());put(arr, Arrays.asList(2312, 12423));put(arr2, data);put(array, new int[]{1, 2, 3});}};private Object[] dataArray new Object[]{13, liaojl, 26, new Date(), Arrays.asList(2312, 12423), data, new int[]{1, 2, 3}};private final ICoreData2Object2Person data2Object2 BeanCopier2Utils.getFullData2Object(Person.class);org.junit.IgnoreTestpublic void test() throws Exception {testMapCustomize2();testArrayCustomize2();testReflect();warmup true;testReflect();testMapCustomize2();testArrayCustomize2();}public static final int SIZE 1000000;private void testMapCustomize2() {final long start System.currentTimeMillis();Person person;for (int i 0; i SIZE; i) {final ClassPerson personClass Person.class;person data2Object2.toMapConverter(dataMap);}final long end System.currentTimeMillis();if (warmup)System.out.println(testMapCustomize2: (end - start));}private void testArrayCustomize2() {final long start System.currentTimeMillis();Person person null;for (int i 0; i SIZE; i) {person data2Object2.toArrayConverter(dataArray);}final long end System.currentTimeMillis();if (warmup)System.out.println(testArrayCustomize2: (end - start));}private void testReflect() throws Exception {final long start System.currentTimeMillis();for (int i 0; i SIZE; i) {final ClassPerson personClass Person.class;Object person personClass.newInstance();final Field[] fields personClass.getDeclaredFields();for (Field field : fields) {if (Modifier.isFinal(field.getModifiers())) {continue;}Ignore annotation field.getAnnotation(Ignore.class);if (annotation ! null) {continue;}field.setAccessible(Boolean.TRUE);field.set(person, dataMap.get(field.getName()));}}final long end System.currentTimeMillis();if (warmup)System.out.println(testReflect: (end - start));}
}easy.mapper性能消耗远远小于反射
easy.mapper 的使用
easy.mapper 介绍
注意项
需要转换的Bean 必须包含一个无参构造方法需要转换的属性必须包含其Getter 方法
普通转换
Data
public class Mapper {private byte b;private Byte b1;private boolean bool;private Boolean bool1;private char c;private Character c1;private short s;private Short s1;private int i;private Integer i1;private long l;private Long l1;private float f;private Float f1;private double d;private Double d1;private Date date;
}// 转换MAP 到Person 并会对Person父类的属性进行扫描赋值
Person person1 BeanCopier2Utils.getFullData2Object(Person.class).toMapConverter(dataMap);// 转换MAP 到Person 不会对Person父类的属性进行扫描赋值
Person person2 BeanCopier2Utils.getData2Object(Person.class).toMapConverter(dataMap);// 转换Servlet 到Person 不会对Person父类的属性进行扫描赋值
Person person3 BeanCopier2Utils.getFullData2WebObject(Person.class).toHttpServletRequestConverte(servelt);// 转换Servlet 到Person 并会对Person父类的属性进行扫描赋值
Person person4 BeanCopier2Utils.getData2WebObject(Person.class).toHttpServletRequestConverte(servelt);
字段忽略
io.github.jinlongliao.easy.server.mapper.core.mapstruct2.annotation.Ignore2提供 Ignore2 使用标记的字段在转换时并不会进行赋值操作
demo
public class Person extends Grep implements IAnimal {private static final Logger log LoggerFactory.getLogger(Person.class);IgnoreIgnore2private int ignore;
}特殊字段转换
字段名称与bean 中属性名不对应数据类型双方不匹配其他特殊类型
easy.mapper 默认对支持所有基础类型及其包装类String 。详情查看 io.github.jinlongliao.easy.server.mapper.core.mapstruct2.converter.IDataConverter 实现。针对特殊类型转。提供两种转换方案
重写 IDataConverter 实现
io.github.jinlongliao.easy.server.mapper.core.mapstruct2.converter.InnerConverter 接口 重写T T getT(ClassT tClass, Object extra, Object data); 针对不支持类型时会调用此方法自己仅需要 依据 参数tClass 的类型进行判断 进行返回相应值参数中的data 为消息中的值
使用 io.github.jinlongliao.easy.server.mapper.core.mapstruct2.annotation.Mapping2
public interface Mapping2 {/*** return 映射源名称*/String sourceName() default ;/*** set Method Name* return*/String putMethod() default ;/*** 针对非基本类型String,byte,short,int,float,double,long,charbr/* 除外需要指定自定义 静态转换函数* eg:* pre* public static Person person(Object obj){* return (Person)obj;* }* /pre** return 数据强转函数名称*/String converterMethod() default ;/*** return Class Name* see {link Mapping2#converterMethod()}*/Class converterClass() default InnerConverter.class;
}
converterClass 手动指定转换自己的转换类
converterMethod 设置转换函数的名称 ___ 此函数必须为 publicstatic ___ 。
putMethod 假设 bean 中的 属性a setter函数 不为 setA 通过 putMethod 可以指定新的setter函数
sourceName 假设 mesaage 中的名字不是属性a 的名字 sourceName 可以指定获取源的名字提前编译 支持
手动指定
通过 io.github.jinlongliao.easy.server.mapper.utils.MapperStructConfig可以指定 自动生成消息转换实现的 class 及其源文件 MapperStructConfig.setDev(true, ./target/, ./target/);通过 maven 插件实现 maven-generator-plugin buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.10.1/versionconfigurationannotationProcessorPathsannotationProcessorPathgroupIdio.github.jinlongliao/groupIdartifactIdeasy.server.mapper/artifactIdversion${project.version}/version/annotationProcessorPathannotationProcessorPathgroupIdio.github.jinlongliao/groupIdartifactIdeasy.server.extend/artifactIdversion${project.version}/version/annotationProcessorPath/annotationProcessorPaths/configuration/pluginplugingroupIdio.github.jinlongliao/groupIdartifactIdmaven-generator-plugin/artifactIdversion${project.version}/versionexecutionsexecutionphasecompile/phasegoalsgoaljava/goal/goals/execution/executionsconfigurationargumentsargument${project.basedir}/target/classes//argumentargument${project.basedir}/target/generated-sources/annotations//argument/arguments/configuration/plugin/plugins/build spring 支持
将 io.github.jinlongliao.easy.server.mapper.spring.BeanMapperFactoryBean设置spring 托管。既可在 spring 中 使用 IBeanMapper类型 进行操作IBeanMapper封装了常见的类型操作推荐使用
public interface IBeanMapper {/*** 基于Map 的转换** param tClass* param data* param T* return T*/T T mapBeanMapper(ClassT tClass, MapString, Object data);/*** 基于数组 的转换** param tClass* param data* param T* return T*/T T arrayBeanMapper(ClassT tClass, Object[] data);/*** 基于javax.servlet 的转换** param tClass* param req* param T* return T*/T T servletBeanMapper(ClassT tClass, javax.servlet.http.HttpServletRequest req);}