github地址:
https://github.com/wei198621/allTypes_mappingTools
参考文章:
https://www.cnblogs.com/songhaibin/p/13382799.html
参考文章(mapstruct)
https://www.bbsmax.com/A/8Bz8PVq6zx/
apache BeanUtils 进行mapping
代码
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<!--//org.apache.commons.beanutils.BeanUtils-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
</dependencies>
package com.tz.leo.apcheBeanUtils;
import com.tz.leo.apcheBeanUtils.beans.Order;
import com.tz.leo.apcheBeanUtils.beans.OrderQueryParam;
import org.apache.commons.beanutils.BeanUtils;
import java.lang.reflect.InvocationTargetException;
/**
* Author: tz_wl
* Date: 2020/8/12 16:55
* Content:
*/
public class ApacheBeanUtilsTest {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Order order = new Order();
order.setId(12345L);
order.setOrderSn("orderSn");
order.setOrderType(0);
order.setReceiverKeyword("keyword");
order.setSourceType(1);
order.setStatus(2);
OrderQueryParam orderQueryParam = new OrderQueryParam();
BeanUtils.copyProperties(orderQueryParam,order); // (dest,source)
System.out.println("orderQueryParam is : " + orderQueryParam);
}
}
orderQueryParam is : OrderQueryParam(id=12345, orderSn=orderSn, receiverKeyword=keyword, receiverKeyword2=null, status=2, orderType=0, orderType2=null, sourceType=1)
spring BeanUtils 进行mapping
代码
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
</dependencies>
package com.tz.leo.springBeanUtils;
import com.tz.leo.springBeanUtils.beans.Order;
import com.tz.leo.springBeanUtils.beans.OrderQueryParam;
import org.springframework.beans.BeanUtils;
import java.lang.reflect.InvocationTargetException;
/**
* Author: tz_wl
* Date: 2020/8/12 16:55
* Content:
*/
public class SpringBeanUtilsTest {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Order order = new Order();
order.setId(12345L);
order.setOrderSn("orderSn");
order.setOrderType(0);
order.setReceiverKeyword("keyword");
order.setSourceType(1);
order.setStatus(2);
OrderQueryParam orderQueryParam = new OrderQueryParam();
BeanUtils.copyProperties(order,orderQueryParam); //(source,dest)
System.out.println("通过springframework的BeanUtils, orderQueryParam is : " + orderQueryParam);
}
}
cglib 进行 mapping
代码
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.10</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>reflectasm</artifactId>
<version>1.11.7</version>
</dependency>
</dependencies>
package com.tz.leo.CglibBeanCopier01;
import com.tz.leo.CglibBeanCopier01.beans.User;
import com.tz.leo.CglibBeanCopier01.beans.UserDto;
import net.sf.cglib.beans.BeanCopier;
/**
* Author: tz_wl
* Date: 2020/8/12 18:27
* Content:
*/
public class BeanCopierTest01 {
public static void main(String[] args) {
CopyUser2UserDto();
}
/**
*@Description: User.age (int) UserDto.age (int)
* User 与 UserDto age name 都是相同类型 所以可以从User映射到UserDto
*@Param:
*@return:
*@date: 2020/8/12
*/
private static void CopyUser2UserDto() {
final BeanCopier beanCopier = BeanCopier.create(User.class, UserDto.class, false);
User user = new User();
user.setAge(10) ;
user.setName("zhangsan01");
UserDto userDto = new UserDto();
beanCopier.copy(user,userDto,null);
System.out.println("======CopyUser2UserDto========");
System.out.println(userDto.getAge());
System.out.println(userDto.getName());
System.out.println("======CopyUser2UserDto========");
}
}

package com.tz.leo.CglibBeanCopier03withWrapper;
import com.tz.leo.CglibBeanCopier03withWrapper.beans.Account;
import com.tz.leo.CglibBeanCopier03withWrapper.beans.AccountDto;
import net.sf.cglib.beans.BeanCopier;
import java.math.BigDecimal;
import java.util.Date;
/**
* Author: tz_wl
* Date: 2020/8/12 19:09
* Content:
*/
public class BeanCopier3Test {
public static void main(String[] args) {
CopeOrigional();
CopeWithWrapper();
}
/**
*@Description: 原始的copy 方法
*@Param:
*@return:
*@date: 2020/8/12
*/
private static void CopeOrigional() {
Account account = new Account();
account.setId(1);
account.setCreateTime(new Date());
account.setBalance(BigDecimal.valueOf(4000L));
BeanCopier copier = BeanCopier.create(Account.class, AccountDto.class, false);
AccountDto accountDto = new AccountDto();
copier.copy(account, accountDto, null);
System.out.println("==============CopeSimple1================");
System.out.println(accountDto.getId()); //1
System.out.println(accountDto.getBalance()); //null
System.out.println(accountDto.getCreateTime()); //null
System.out.println("=============CopeSimple1=================");
}
/**
*@Description: 封装copy类 增加缓存 效果更好
*@Param:
*@return:
*@date: 2020/8/12
*/
private static void CopeWithWrapper() {
Account account = new Account();
account.setId(1);
account.setCreateTime(new Date());
account.setBalance(BigDecimal.valueOf(4000L));
AccountDto accountDto = new AccountDto();
WrapperBeanCopier.copyProperties(account,accountDto);
System.out.println("==============CopeWithWrapper================");
System.out.println(accountDto.getId()); //1
System.out.println(accountDto.getBalance()); //null
System.out.println(accountDto.getCreateTime()); //null
System.out.println("=============CopeWithWrapper=================");
}
}
WrapperBeanCopier–BeanCopier缓存化
package com.tz.leo.CglibBeanCopier03withWrapper;
import com.esotericsoftware.reflectasm.ConstructorAccess;
import net.sf.cglib.beans.BeanCopier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static java.lang.String.format;
/**
* Author: tz_wl
* Date: 2020/8/12 19:09
* Content:
* BeanCopier拷贝速度快,性能瓶颈出现在创建BeanCopier实例的过程中。 所以,把创建过的BeanCopier实例放到缓存中,下次可以直接获取,提升性能:
*
*/
public class WrapperBeanCopier {
private WrapperBeanCopier() {
//do nothing
}
private static final Map<String, BeanCopier> BEAN_COPIER_CACHE = new ConcurrentHashMap<String, BeanCopier>();
private static final Map<String, ConstructorAccess> CONSTRUCTOR_ACCESS_CACHE = new ConcurrentHashMap<String, ConstructorAccess>();
public static void copyProperties(Object source, Object target) {
BeanCopier copier = getBeanCopier(source.getClass(), target.getClass());
copier.copy(source, target, null);
}
private static BeanCopier getBeanCopier(Class sourceClass, Class targetClass) {
String beanKey = generateKey(sourceClass, targetClass);
BeanCopier copier = null;
if (!BEAN_COPIER_CACHE.containsKey(beanKey)) {
copier = BeanCopier.create(sourceClass, targetClass, false);
BEAN_COPIER_CACHE.put(beanKey, copier);
} else {
copier = BEAN_COPIER_CACHE.get(beanKey);
}
return copier;
}
/**
* 两个类的全限定名拼接起来构成Key
*
* @param sourceClass
* @param targetClass
* @return
*/
private static String generateKey(Class<?> sourceClass, Class<?> targetClass) {
return sourceClass.getName() + targetClass.getName();
}
public static <T> T copyProperties(Object source, Class<T> targetClass) {
T t = null;
try {
t = targetClass.newInstance();
} catch (Exception e) {
throw new RuntimeException(format("Create new instance of %s failed: %s", targetClass, e.getMessage()));
}
copyProperties(source, t);
return t;
}
public static <T> List<T> copyPropertiesOfList(List<?> sourceList, Class<T> targetClass) {
if (sourceList == null || sourceList.isEmpty()) {
return Collections.emptyList();
}
ConstructorAccess<T> constructorAccess = getConstructorAccess(targetClass);
List<T> resultList = new ArrayList<T>(sourceList.size());
for (Object o : sourceList) {
T t = null;
try {
t = constructorAccess.newInstance();
copyProperties(o, t);
resultList.add(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return resultList;
}
private static <T> ConstructorAccess<T> getConstructorAccess(Class<T> targetClass) {
ConstructorAccess<T> constructorAccess = CONSTRUCTOR_ACCESS_CACHE.get(targetClass.getName());
if (constructorAccess != null) {
return constructorAccess;
}
try {
constructorAccess = ConstructorAccess.get(targetClass);
constructorAccess.newInstance();
CONSTRUCTOR_ACCESS_CACHE.put(targetClass.toString(), constructorAccess);
} catch (Exception e) {
throw new RuntimeException(format("Create new instance of %s failed: %s", targetClass, e.getMessage()));
}
return constructorAccess;
}
}
cglib.BeanCopier VS spring.BeanUtilsBeanCopie 速度非常快
BeanUtils start time is :1597236554316
BeanUtils end time is :1597236554637
BeanUtils took time: 321(ms)
====================================================
BeanCopie start time is :1597236554667
BeanCopie rend time is :1597236554667
BeanCopier took time: 0(ms)
package com.tz.leo.BeanCopierVSBeanUtils;
import com.tz.leo.BeanCopierVSBeanUtils.beans.User;
import com.tz.leo.BeanCopierVSBeanUtils.beans.UserDto;
import net.sf.cglib.beans.BeanCopier;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Author: tz_wl
* Date: 2020/8/12 20:33
* Content: BeanCopier 速度非常快
*/
public class appTest {
public static void main(String[] args) {
List<User> list1 = new ArrayList<User>(9900000);
for (int i = 0; i < 100; i++) {
User po = new User();
po.setAge(1);
po.setName("lili"+ (new Random()).toString());
list1.add(po);
}
//*************************** BeanUtils 9900000 用时测试 ************************************
long startBeanUtils = System.currentTimeMillis();
System.out.println("BeanUtils start time is :" +startBeanUtils);
List<UserDto> list2 = new ArrayList<UserDto>(9900000);
for (User user : list1) {
UserDto dto = new UserDto();
BeanUtils.copyProperties(user, dto); //270 ms
list2.add(dto);
}
long endBeanUtils =System.currentTimeMillis();
System.out.println("BeanUtils end time is :" + endBeanUtils );
System.out.printf("BeanUtils took time: %d(ms)%n", endBeanUtils - startBeanUtils);
//************************** BeanCopier 9900000 用时测试 *************************************
System.out.println("====================================================");
BeanCopier copier = BeanCopier.create(User.class, UserDto.class, false);
long startBeanCopier = System.currentTimeMillis();
List<UserDto> list3 = new ArrayList<UserDto>(9900000);
System.out.println("BeanCopie start time is :" +startBeanCopier);
for (User user : list1) {
UserDto dto = new UserDto();
copier.copy(user, dto, null); //20 ms
list3.add(dto);
}
long endBeanCopier =System.currentTimeMillis();
System.out.println("BeanCopie rend time is :" + endBeanCopier );
System.out.printf("BeanCopier took time: %d(ms)%n", endBeanCopier - startBeanCopier);
}
}
mapstruct 方式进行映射
代码
<properties>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<dependencies>
<!--//需要将编译环境设置为1.8及以上方式编译-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
</dependency>
</dependencies>
package com.tz.leo.MapStruts.mappers;
import com.tz.leo.MapStruts.beans.Order;
import com.tz.leo.MapStruts.beans.OrderQueryParam;
import org.mapstruct.Mapper;
/**
* Author: tz_wl
* Date: 2020/8/12 16:07
* Content:
*/
//只有一个要求, 在接口上写 @Mapper 注解即可
@Mapper
public interface OrderMapper {
OrderQueryParam entity2queryParam(Order order);
}
package com.tz.leo.MapStruts;
import com.tz.leo.MapStruts.beans.Order;
import com.tz.leo.MapStruts.beans.OrderQueryParam;
import com.tz.leo.MapStruts.mappers.OrderMapper;
import org.mapstruct.factory.Mappers;
/**
* Author: tz_wl
* Date: 2020/8/12 16:08
* Content:
*/
public class MapStructTest {
public static void main(String[] args) {
Order order = new Order();
order.setId(12345L);
order.setOrderSn("orderSn");
order.setOrderType(0);
order.setReceiverKeyword("keyword");
order.setSourceType(1);
order.setStatus(2);
OrderMapper mapper = Mappers.getMapper(OrderMapper.class);
OrderQueryParam orderQueryParam = mapper.entity2queryParam(order);
System.out.println(orderQueryParam.getOrderSn());
System.out.println(orderQueryParam.getReceiverKeyword());
}
}
代码
// An highlighted block
var foo = 'bar';
// An highlighted block
var foo = 'bar';
博客介绍了多种 Bean 映射方式,包括 apache BeanUtils、spring BeanUtils、cglib 及 mapstruct 等方式进行映射,还提及了 cglib 的 WrapperBeanCopier 缓存化,对比了 cglib.BeanCopier 和 spring.BeanUtilsBeanCopie 的速度,并给出了相关代码示例及参考文章和 github 地址。

被折叠的 条评论
为什么被折叠?



