tamper是一款处理bean/map进行属性复制映射的工具,支持递归,集合等深度映射.
这里列觉了几种需要使用tamper的场景:
- model 和 DO的转化 (DO = Data Object , 数据库对象的设计是一种大宽表的设计,domain/model的设计,会有层次结构&具体)。 比如表设计存储会采用json存储动态数据,而在model中会是具体的属性
- model 和 VO的转化 (VO = View Object , 公司的产品detail页面,涉及了后端n多个domain/model的组合展示,这时候会进行包装成VO,包装一些页面组装逻辑)
- model 和 DTO的转化 (DTO = Data Transfer Object ,公司子系统比较多,系统之间会有比较多的rpc等remote调用)
- form -> bean的转化 (现在流行的几个MVC框架,都已经开始支持view层的参数注入,比如@Paramter(name="field")String , @Form("name=xx")Bean)。 提交的form表单数据,基本都是以map+list为主,就会涉及一个mapping
- 解决BeanUtils, BeanCopier?使用上的局限,只能针对同名属性的拷贝
- 相比于BeanUtils,性能提升是它的优势
- 相比于BeanCopier,类型之间的convertor是它的优势
- 支持插件方式的扩展,自身框架的设计也是基于插件扩展。
- default value支持
- convetor转换
- script脚本支持 (EL表达式处理)
- bean creator(嵌套对象自动创建)
<dependency> <groupId>com.alibaba.tamper</groupId> <artifactId>tamper</artifactId> <version>1.0.3</version> </dependency>
1.How to import to eclipse by maven?
mvn eclipse:eclipse
2.How to build project by maven?
mvn clean package
3.How to run testcase by maven?
mvn test
bean-mappings xmlns="https://github.com/alibaba/tamper/schema/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://github.com/alibaba/tamper/schema/mapping https://raw.github.com/alibaba/tamper/master/src/main/resources/META-INF/mapping.xsd"> <!-- (bean-bean) mapping 测试 --> <bean-mapping batch="true" srcClass="com.agapple.mapping.object.SrcMappingObject" targetClass="com.agapple.mapping.object.TargetMappingObject" reversable="true"> <field-mapping srcName="intValue" targetName="intValue" /> <field-mapping targetName="integerValue" script="src.intValue + src.integerValue" /> <!-- 测试script --> <field-mapping srcName="start" targetName="start" /> <field-mapping srcName="name" targetName="targetName" /> <!-- 注意不同名 --> <field-mapping srcName="mapping" targetName="mapping" mapping="true" /> </bean-mapping><bean-mapping batch="true" srcClass="com.agapple.mapping.object.NestedSrcMappingObject" targetClass="com.agapple.mapping.object.NestedTargetMappingObject" reversable="true"> <field-mapping srcName="name" targetName="name" defaultValue="ljh" /> <!-- 测试default value --> <field-mapping srcName="bigDecimalValue" targetName="value" targetClass="string" defaultValue="10" /> <!-- 测试不同名+不同类型+default value --> </bean-mapping> </bean-mappings></pre>
public BeanMapping srcMapping = BeanMapping.create(SrcMappingObject.class, TargetMappingObject.class); public BeanMapping targetMapping = BeanMapping.create(TargetMappingObject.class , SrcMappingObject.class);@Test public void testBeanToBean_ok() { SrcMappingObject srcRef = new SrcMappingObject(); srcRef.setIntegerValue(1); srcRef.setIntValue(1); srcRef.setName("ljh"); srcRef.setStart(true); TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象 srcMapping.mapping(srcRef, targetRef); SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次 targetMapping.mapping(targetRef, newSrcRef); }</pre>
public BeanCopy srcCopy = BeanCopy.create(SrcMappingObject.class, TargetMappingObject.class); public BeanCopy targetCopy = BeanCopy.create(TargetMappingObject.class , SrcMappingObject.class);@Test public void testBeanToBean_ok() { SrcMappingObject srcRef = new SrcMappingObject(); srcRef.setIntegerValue(1); srcRef.setIntValue(1); srcRef.setName("ljh"); srcRef.setStart(true); TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象 srcCopy.copy(srcRef, targetRef); SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次 targetCopy.copy(targetRef, newSrcRef); }</pre>
public BeanMap beanMap = BeanMap.create(SrcMappingObject.class); @Test public void testDescribe_Populate_ok() { SrcMappingObject srcRef = new SrcMappingObject(); srcRef.setIntegerValue(1); srcRef.setIntValue(1); srcRef.setName("ljh"); srcRef.setStart(true);Map map = beanMap.describe(srcRef); SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次 beanMap.populate(newSrcRef, map); }</pre>
BeanMappingBuilder builder = new BeanMappingBuilder() {protected void configure() { mapping(HashMap.class, HashMap.class).batch(false).reversable(true).keys("src", "target"); fields(srcField("one"), targetField("oneOther")).convertor("convertor").defaultValue("ljh"); fields(srcField("two").clazz(String.class), targetField("twoOther")).script("1+2").convertor( StringToCommon.class); fields(srcField("three").clazz(ArrayList.class), targetField("threeOther").clazz(HashSet.class)).recursiveMapping( true); } };</pre>
通过builder可以比较方便的构造mapping config,最后需要生成mapping实例,还需要做一步:
BeanMapping mapping = new BeanMapping(builder); mapping.mapping(src, dest);//使用or
BeanMappingConfigHelper.getInstance().register(builder); // 进行注册 BeanMappingObject object = BeanMappingConfigHelper.getInstance().getBeanMappingObject(srcClass,targetClass); mapping.mapping(src, dest);//使用
- qq交流群: 161559791
- 邮件交流: [email protected]
- 新浪微博: agapple0002
- 报告issue:issues
tamper's People
Forkers
sandzhang fyatao frankswu jusescn twlkyao 13911205241 xleader iyangming joliny jxqlovejava ycaihua rzs840707 kimmking ccvcd impulsehu rocky-zh liaolei0826 blademainer wangwangdi clarkhan rocwzp 450531875 zofuthan pepsing poneyo xiaoj-l liuylmr shook2012 mackstone debenson cloudxtreme haikuo81 xty88645 codingdock jihaixiao8 yajxh parselife slamke lwlzpn84 alex-135 kerou richardy2012 sdgdsffdsfff alibaba-boonya zjpjohn liuzantian meifans liuqianshuai googlezhang is00hcw rongfengliang hyqgod anymijun haojile cycled h-hao lianyuqiang tigerlh zlhades3 conanpeng jframeye huahua035 bryant1410 kevin82008 gspandy tangkuo chtgit070920 mayue100 hanxueming126 kindwgy bzvs1992 lanyejingyu iqinning ponywise yangjb7151 mway08 archer-christ chiwenheng waterif xiaoniao swabber-kun cairenjie1985 zhanghongfeng fglxy shezhanjun lorry2018 wudeyong richardplas zhouhailin lvhaoran winsomexjs lugt eshaohu codebyteme samuelgavin jlleitschuh 582635133 ldw-sh-cn tsingfu xjz1842tamper's Issues
List<A>和List<B>集合拷贝?
List和List集合拷贝,A和B中属性名称相同。example中例子没看懂,请教大神
与 springboot 集成时报错
java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter overrides final method visit.(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) at net.sf.cglib.core.AbstractClassGenerator.<init>(AbstractClassGenerator.java:38) at net.sf.cglib.reflect.FastClass$Generator.<init>(FastClass.java:55) at net.sf.cglib.reflect.FastClass.create(FastClass.java:43) at net.sf.cglib.reflect.FastClass.create(FastClass.java:39) at com.alibaba.tamper.core.introspect.Introspector.getFastClass(Introspector.java:165) at com.alibaba.tamper.core.introspect.Introspector.getFastMethod(Introspector.java:66) at com.alibaba.tamper.core.introspect.FastPropertySetExecutor.discover(FastPropertySetExecutor.java:63) at com.alibaba.tamper.core.introspect.PropertyBatchExecutor.buildGetBulkBean(PropertyBatchExecutor.java:49) at com.alibaba.tamper.core.introspect.PropertyBatchExecutor.<init>(PropertyBatchExecutor.java:19) at com.alibaba.tamper.core.introspect.UberspectImpl.getBatchExecutor(UberspectImpl.java:36) at com.alibaba.tamper.core.BeanMappingExecutor.getGetBatchExecutor(BeanMappingExecutor.java:180) at com.alibaba.tamper.core.BeanMappingExecutor.execute(BeanMappingExecutor.java:52) at com.alibaba.tamper.BeanCopy.copy(BeanCopy.java:55) at com.zyf.springboot.BeanCopyTest.testCopy_ok(BeanCopyTest.java:33) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at junit.framework.TestCase.runTest(TestCase.java:176) at junit.framework.TestCase.runBare(TestCase.java:141) at junit.framework.TestResult$1.protect(TestResult.java:122) at junit.framework.TestResult.runProtected(TestResult.java:142) at junit.framework.TestResult.run(TestResult.java:125) at junit.framework.TestCase.run(TestCase.java:129) at junit.framework.TestSuite.runTest(TestSuite.java:252) at junit.framework.TestSuite.run(TestSuite.java:247) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
是否支持类似Dozer的map-id的功能
dozer有一个特性,可以根据不同的场景选择不同的映射方式,方法是map的时候提供map-id。
tamper是否支持这个特性,或者有什么变通的办法呢?另外,文档对配置文件放在哪里,mapper的实例如何获得等等都没有写,对我这种小白实在是有点困惑
这个项目还在维护吗?
如题
这个项目现在还有人在维护吗?
最后一次更新都是13年了,还有没有下文?
建议添加在配置中添加include的配置
建议在配置中添加include功能 引入其他配置的功能,如果项目转换方面的职责全部交给mapping来处理的话,就1个配置文件太笼统了,注册多次配置又显得比较麻烦。
1对1的对象转换,但是转化后的对象包含多个引用的属性
使用xml配置,实现A Bean中多个属性---> B Bean的多个属性中
A中有24个属性
B中属性为对象,只有3个,3个对象的属性包含了A中24个属性
这个如何配置哇?java.lang.IllegalArgumentException对象copy问题
java.lang.IllegalArgumentException: Cannot find method public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
at net.sf.cglib.reflect.FastMethod.helper(FastMethod.java:39) ~[cglib-3.2.4.jar:na]
at net.sf.cglib.reflect.FastMethod.(FastMethod.java:28) ~[cglib-3.2.4.jar:na]
at net.sf.cglib.reflect.FastClass.getMethod(FastClass.java:104) ~[cglib-3.2.4.jar:na]
at com.agapple.mapping.core.introspect.Introspector.getFastClass(Introspector.java:150) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.introspect.Introspector.getFastMethod(Introspector.java:65) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.introspect.PropertySetExecutor.discover(PropertySetExecutor.java:63) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.introspect.PropertyBatchExecutor.buildGetBulkBean(PropertyBatchExecutor.java:49) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.introspect.PropertyBatchExecutor.(PropertyBatchExecutor.java:19) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.introspect.Uberspector.getBatchExecutor(Uberspector.java:47) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.BeanMappingExecutor.getSetBatchExecutor(BeanMappingExecutor.java:122) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.core.BeanMappingExecutor.execute(BeanMappingExecutor.java:51) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.BeanCopy.copy(BeanCopy.java:59) ~[mapping-1.0.0.jar:na]
at com.agapple.mapping.BeanMappingUtil.copy(BeanMappingUtil.java:33) ~[mapping-1.0.0.jar:na]深度拷贝不生效,thrownet.sf.cglib.beans.BulkBeanException: com.alibaba.tamper.object.NestedSrcMappingObject cannot be cast to com.alibaba.tamper.object.NestedTargetMappingObject
将注解去掉后或抛异常,并不能深度拷贝
public void testCopy_ok() {
SrcMappingObject srcRef = new SrcMappingObject();
srcRef.setIntegerValue(1);
srcRef.setIntValue(1);
srcRef.setName("ljh");
srcRef.setStart(true);// NestedSrcMappingObject nestedSrcRef = new NestedSrcMappingObject(); // nestedSrcRef.setBigDecimalValue(BigDecimal.ONE); // srcRef.setMapping(nestedSrcRef); TargetMappingObject targetRef = new TargetMappingObject();// 测试一下mapping到一个Object对象 srcCopyer.copy(srcRef, targetRef); assertEquals(targetRef.getIntegerValue(), srcRef.getIntegerValue()); assertEquals(targetRef.getIntValue(), srcRef.getIntValue()); assertNull(targetRef.getTargetName());// 为null,因为属性不匹配 assertEquals(targetRef.isStart(), srcRef.isStart()); SrcMappingObject newSrcRef = new SrcMappingObject();// 反过来再mapping一次 targetCopyer.copy(targetRef, newSrcRef); assertEquals(newSrcRef.getIntegerValue(), targetRef.getIntegerValue()); assertEquals(newSrcRef.getIntValue(), targetRef.getIntValue()); assertNull(newSrcRef.getName());// 为null,因为属性不匹配 assertEquals(newSrcRef.isStart(), targetRef.isStart()); }
请问把属性向上升级怎么做?
public class User{ private String name; private String age; private Address address; setter ..getter } public class Address{ private Long id; private String location; private String street; private String houseNumber; private String otherAttr; } public class UserVO{ private String name; private String age; private String street; private String location; private String houseNumber; }
业务场景:
User 表有 address 属性,类型为Address
前台使用REST接口输出数据,需要把Address中的一个或多个数据向上作为UserVO的属性传递到前台表格展现。文档优化
- 补充下配置文件的处理
Recommend Projects
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
TensorFlow
An Open Source Machine Learning Framework for Everyone
Django
The Web framework for perfectionists with deadlines.
Laravel
A PHP framework for web artisans
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
Recommend Topics
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
web
Some thing interesting about web. New door for the world.
server
A server is a program made to process requests and deliver data to clients.
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Visualization
Some thing interesting about visualization, use data art
Game
Some thing interesting about game, make everyone happy.
Recommend Org
We are working to build community through open source technology. NB: members must have two-factor auth.
Microsoft
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba
Alibaba Open Source for everyone
D3
Data-Driven Documents codes.
Tencent
China tencent open source team.