package com.wxj233.util;
import java.util.List;
/**
* 完成数据持久化层到传输层自动赋值
* @version 0.0.1
* @since 2019/01/09
* @author wxj233
*
*/
public interface DataTransfer {
/**
* 完成持久化层到传输层数据赋值,(反向赋值也可以)
* @param dto 传输层
* @param dao 持久化辰
* @return 赋值后的传输层
*/
Object getDtoFromEntity(Object dto, Object entity);
/**
* 集合类映射
* @param <T> 目标集合类型
* @param <S> 源集合
* @return 目标集合(自动赋值)
*/
<T, S> List<T> ListToList(List<S> src, Class<T> t);
}
package com.wxj233.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public class DataTransferImp implements DataTransfer {
@Override
public Object getDtoFromEntity(Object dto, Object entity) {
// TODO Auto-generated method stub
//Field[] fields = dto.getClass().getDeclaredFields();
Method[] dtoMethods = dto.getClass().getMethods();
Method[] entityMethods = entity.getClass().getMethods();
for(Method dtoMethod : dtoMethods) {
if(dtoMethod.getName().startsWith("set")) {
for(Method entityMethod : entityMethods) {
if(entityMethod.getName().startsWith("get")
&& entityMethod.getName().substring(3).equals(dtoMethod.getName().substring(3))) {
try {
if(dtoMethod.getParameterTypes()[0].isAssignableFrom(List.class) ) {
//System.out.println(dtoMethod.getGenericParameterTypes()[0].toString());
Type[] paramTypes = dtoMethod.getGenericParameterTypes();
Type[] actualTypes = ((ParameterizedType)paramTypes[0]).getActualTypeArguments();
//System.out.println(actualTypes[0].toString());
dtoMethod.invoke(dto, ListToList((List<?>)entityMethod.invoke(entity),(Class<?>)actualTypes[0]));
}else {
//invoke第一个参数是代表调用该方法的对象
dtoMethod.invoke(dto, entityMethod.invoke(entity));
}
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
return dto;
}
@SuppressWarnings("unchecked")
@Override
public <T, S> List<T> ListToList(List<S> src, Class<T> tType) {
// TODO Auto-generated method stub
List<T> target = new ArrayList<>();
for(S s : src) {
// //Method method = DataTransferImp.class.getMethod("ListToList", List.class,Class.class);
//
// //获取参数
// Type[] paramTypes = method.getGenericParameterTypes();
//
// //获取参数的类型
// //Type rawType = ((ParameterizedType)paramTypes[1]).getRawType();
//
// //获取参数中泛型,一个参数中泛型可能有多个
// Type[] actualTypes = ((ParameterizedType)paramTypes[1]).getActualTypeArguments();
// System.out.println(((T)actualTypes[0]).getClass().toGenericString());
// T t = (T) actualTypes[0].getClass().getDeclaredConstructor().newInstance();
try {
T t = tType.getDeclaredConstructor().newInstance();
target.add((T) getDtoFromEntity(t,s));
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return target;
}
}
DataTransferImp实现DataTransfer接口,一共两个方法,使用到的原理主要是java反射机制实现赋值,
测试如下:
package com.wxj233.util;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.wxj233.entity.OperationRecord;
import com.wxj233.entity.User;
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:springmvc-servlet.xml")
@WebAppConfiguration
public class DataTransferImpTest {
@Autowired
DataTransfer dataTransfer;
@Test
public void testGetclass() {
//作者的用户类,你可以用其他的类来做测试
User user = new User();
user.setId(123);
OperationRecord operationRecord = new OperationRecord();
operationRecord.setId(456);
user.getOperationRecords().add(operationRecord);
User usera = new User();
usera = (User) dataTransfer.getDtoFromEntity(usera, user);
System.out.println(usera.getOperationRecords().get(0).getId());
fail("Not yet implemented");
}
}
输出结果为:456