1.
java使用 org.springframework.beans.BeanUtils 工具类,把一个bean的属性值复制到另一个bean中,前提是这个复制的bean的字段要完全包含在被复制的bean中
代码如下
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String city;
private Integer age;
}
@Data
public class Child extends Person{
private String hobby;
private String work;
}
import org.springframework.beans.BeanUtils;
public class CopyBean {
public static void main(String[] args) {
Person person = new Person("jack", "北京", 12);
Child child = new Child();
BeanUtils.copyProperties(person,child);
child.setHobby("看电视");
child.setWork("看门");
System.out.println(child.getCity());
}
}
可以实现bean之间的属性的完全复制
2.使用org.apache.commons.beanutils.BeanUtils.copyProperties
需要的jar包
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String city;
private Integer age;
}
@Data
public class Child extends Person{
private String hobby;
private String work;
}
import org.apache.commons.beanutils.BeanUtils;
public class CopyBean {
public static void main(String[] args) throws Exception{
Person person = new Person("jack", "北京", 12);
Child child = new Child();
BeanUtils.copyProperties(child,person);
System.out.println(child.getName());
}
}
与第一种实现方式的不同在于,source和target的位置相反
3.反射实现
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String city;
private Integer age;
}
@Data
public class Child extends Person{
private String hobby;
private String work;
}
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class CopyBean {
public static void main(String[] args) throws Exception{
Person person = new Person("jack", "北京", 12);
Child child = new Child();
child = copyBean(child,person);
System.out.println(child.getName());
}
public static <T extends PO, PO> T copyBean(T dest, PO source) throws IntrospectionException {
BeanInfo beanInfo = Introspector.getBeanInfo(dest.getClass()) ;
PropertyDescriptor[] pdes = beanInfo.getPropertyDescriptors() ;
for(int i = 0,length =pdes.length ;i<length ;i++ ){
PropertyDescriptor pd = pdes[i] ;
try {
PropertyDescriptor sourcePd = new PropertyDescriptor(pd.getName(), source.getClass()) ;
Method sourceMethod = sourcePd.getReadMethod() ;
Object result = sourceMethod.invoke(source) ;
Method pdWriteMethod = pd.getWriteMethod() ;
pdWriteMethod.invoke(dest, result) ;
} catch (Exception e) {
continue ;
}
}
return dest ;
}
}
4.使用 net.sf.cglib.beans.BeanCopier.copy的方式,需要自定义转换器Converter实现类
需要的jar包
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String city;
private Integer age;
}
@Data
public class Child extends Person{
private String hobby;
private String work;
}
//自定义转换类 converter的具体实现类
import net.sf.cglib.core.Converter;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.util.Date;
public class CopyConverter implements Converter {
@Override
public Object convert(Object value, Class target, Object context) {
String s = value.toString();
if (target.equals(int.class) || target.equals(Integer.class)) {
return Integer.parseInt(s);
}
if (target.equals(long.class) || target.equals(Long.class)) {
return Long.parseLong(s);
}
if (target.equals(float.class) || target.equals(Float.class)) {
return Float.parseFloat(s);
}
if (target.equals(double.class) || target.equals(Double.class)) {
return Double.parseDouble(s);
}
if (target.equals(Date.class)) {
while (s.indexOf("-") > 0) {
s = s.replace("-", "/");
}
return new Date(s);
}
if (target.equals(BigDecimal.class)) {
if (!StringUtils.isEmpty(s) && !s.equals("NaN")) {
return new BigDecimal(s);
}
}
return value;
}
}
import net.sf.cglib.beans.BeanCopier;
public class CopyBean {
public static void main(String[] args) throws Exception{
Person person = new Person("jack", "北京", 12);
Child child = new Child();
BeanCopier beanCopier = BeanCopier.create(Person.class,
Child.class, true);
beanCopier.copy(person, child, new CopyConverter());
System.out.println(child.getCity());
}
}
5.使用org.springframework.cglib.beans.BeanCopier.copy
实现方式同4
6.Orika实现方式 Orika
是 Java Bean
映射框架,可以实现从一个对象递归拷贝数据至另一个对象。它的优点是:名字相同类型不同也能直接复制
需要的jar包
<dependency>
<groupId>ma.glasnost.orika</groupId>
<artifactId>orika-core</artifactId>
<version>1.5.4</version>
</dependency>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private String city;
private Integer age;
}
@Data
public class Child extends Person{
private String hobby;
private String work;
}
import ma.glasnost.orika.impl.DefaultMapperFactory;
public class CopyBean {
public static void main(String[] args) throws Exception{
Person person = new Person("jack", "北京", 12);
Child child = new Child();
new DefaultMapperFactory.Builder().build().getMapperFacade().map(person,child);
System.out.println(child.getName());
}
}
7.使用MapStruct实现
需要的jar 包
<dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>1.3.0.Final</version> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>1.3.0.Final</version> </dependency>
首先定义Mapper转换接口
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper
public interface CopyMapper {
@Mapping(source = "name",target = "name")
Child mapperToBean(Person person);
}
再通过反射机制实现复制bean
import org.mapstruct.factory.Mappers;
public class CopyBean {
public static void main(String[] args) throws Exception {
Person person = new Person("jack", "北京", 12);
CopyMapper copyMapper = Mappers.getMapper(CopyMapper.class);
Child child = copyMapper.mapperToBean(person);
System.out.println(child.getAge());
}
}