一、图示

二、mapstruct

pom文件

        <dependency>
            <groupid>junit</groupid>
            <artifactid>junit</artifactid>
            <version>4.12</version>
        </dependency>
 
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
            <version>1.18.16</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
        <dependency>
            <groupid>commons-beanutils</groupid>
            <artifactid>commons-beanutils</artifactid>
            <version>1.9.4</version>
        </dependency>
 
        <dependency>
            <groupid>org.mapstruct</groupid>
            <artifactid>mapstruct</artifactid>
            <version>1.2.0.final</version>
        </dependency>
        <dependency>
            <groupid>org.mapstruct</groupid>
            <artifactid>mapstruct-jdk8</artifactid>
            <version>1.2.0.final</version>
        </dependency>
        <dependency>
            <groupid>org.mapstruct</groupid>
            <artifactid>mapstruct-processor</artifactid>
            <version>1.2.0.final</version>
        </dependency>
 
        <!-- dozer使用时需要配置xml 文件,不推荐使用性能和 beanutils 差不多,使用过程可以参考 https://www.jianshu.com/p/bf8f0e8aee23-->
        <!-- https://mvnrepository.com/artifact/net.sf.dozer/dozer -->
        <!--<dependency>
            <groupid>net.sf.dozer</groupid>
            <artifactid>dozer</artifactid>
            <version>5.5.1</version>
        </dependency>-->

下载插件

插件的作用是为了在本地测试的时候,生成 接口的 impl 文件(生成的文件存在与target包里面)

如果是生产环境的话,和lombok操作一样,需要在pom文件添加 mapstruct 插件依赖

<build>
        <plugins>
            <plugin>
                <groupid>org.apache.maven.plugins</groupid>
                <artifactid>maven-compiler-plugin</artifactid>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <showwarnings>true</showwarnings>
                    <annotationprocessorpaths>
                        <path>
                            <groupid>org.projectlombok</groupid>
                            <artifactid>lombok</artifactid>
                            <version>1.18.16</version>
                        </path>
                        <path>
                            <groupid>org.mapstruct</groupid>
                            <artifactid>mapstruct-processor</artifactid>
                            <version>1.2.0.final</version>
                        </path>
                    </annotationprocessorpaths>
                </configuration>
            </plugin>
 
        </plugins>
 
    </build>

代码

import com.baomidou.mybatisplus.annotation.tablename;
import lombok.allargsconstructor;
import lombok.data;
import lombok.noargsconstructor;
 
/**
 * created by yanglongfei on 2021/5/11 10:44
 * version: $
 */
@data
@allargsconstructor
@noargsconstructor
@tablename
public class student {
    private integer id;
    private string name;
    private string age;
    private string phone;
    private string address;
}
import lombok.data;
import java.io.serializable;
 
/**
 * created by yanglongfei on 2021/5/11 10:51
 * version: $
 */
@data
public class studentdto implements serializable {
    private static final long serialversionuid = 735190899850778343l;
    private integer id;
    private string name;
    private string age;
    private string phone;
    private string address;
}
import lombok.data;
import java.io.serializable;
 
/**
 * created by yanglongfei on 2021/5/11 16:59
 * version: $
 */
@data
public class studentvo implements serializable {
    private static final long serialversionuid = 2059190505074790405l;
 
    private integer pk;
    private string username;
    private string userage;
    private string userphone;
    private string useraddress;
}

接口

import com.sys.yang.dto.studentdto;
import com.sys.yang.entity.student;
import com.sys.yang.vo.studentvo;
import org.mapstruct.mapper;
import org.mapstruct.mapping;
import org.mapstruct.mappings;
import org.mapstruct.factory.mappers;
 
@mapper
public interface converterstudent {
 
    converterstudent instance = mappers.getmapper(converterstudent.class);
 
    @mappings({
            @mapping(source = "name", target = "name"),
            @mapping(source = "age", target = "age")
    })
    studentdto entitytodto(student student);
 
    @mappings({
            @mapping(source = "id", target = "pk"),
            @mapping(source = "name", target = "username"),
            @mapping(source = "age", target = "userage"),
            @mapping(source = "phone", target = "userphone"),
            @mapping(source = "address", target = "useraddress")
    })
    studentvo dtotovo(studentdto studentdto);
 
}

测试类 

import com.sys.yang.dto.studentdto;
import com.sys.yang.entity.student;
import com.sys.yang.vo.studentvo;
import org.junit.test;
import org.springframework.beans.beanutils;
import java.lang.reflect.method;
 
/**
 * 对象转换,映射
 * 方式1:效率最高 get set 方法
 * 方式2:common包 beanutils.copyproperties 反射的方式进行
 * 方式3:mapstruct 推荐使用,操作不复杂,效率和 get set 方式相差不大
 *
 * <p>
 * created by yanglongfei on 2021/5/11 10:43
 * version: $
 */
public class atob {
 
    /**
     * set get 的时候使用
     * 生成 对象的set方法
     */
    public static void main(string[] args) {
        class<studentdto> clazz = studentdto.class;
        method[] fields = clazz.getdeclaredmethods();
        for (method field: fields) {
            string name = field.getname();
            if(!name.startswith("is") && !name.startswith("get")){
                system.out.println("entity." + name + "()");
            }
        }
    }
 
    /**
     * 测试方法
     */
    @test
    public void test1() {
        student student = new student(1,"zhagnsan","18","110112113114","diqiu");
        system.out.println(student.tostring());
 
        studentdto studentdto1 = new studentdto();
        beanutils.copyproperties(student,studentdto1);
        system.out.println("beanutils: "+ studentdto1.tostring());
 
        studentdto studentdto2 = converterstudent.instance.entitytodto(student);
        system.out.println("mapstruct: entitytodto " + studentdto2.tostring());
 
        studentvo studentvo = converterstudent.instance.dtotovo(studentdto2);
        system.out.println("mapstruct: dtotovo "+ studentvo);
 
    }
 
}

生成的接口文件

三、framework cglib

要转换的对象的,字段名称 要和 原对象的字段名称一致,否则赋值会失败,可以手动 convert 方法,但是,实现后所有的转换内容都会走 convert 方法

代码

import lombok.data;
 
import java.io.serializable;
 
/**
 * created by yanglongfei on 2021/5/11 16:59
 * version: $
 */
@data
public class studentvo implements serializable {
    private static final long serialversionuid = 2059190505074790405l;
 
    private integer pk;
    private string username;
    private string userage;
    private string userphone;
    private string useraddress;
 
    // framework cglib 使用到的内容
    private string id;
    private string name;
    private integer age;
    private string phone;
    private string address;
 
}

convert 实现类

import org.springframework.cglib.core.converter;
 
/**
 * created by yanglongfei on 2021/5/11 19:53
 * version: $
 */
public class convertstudentdtotovo implements converter {
 
    /**
     * ⭐️⭐️⭐️⭐️⭐️ 要转换的属性名称,相同的情况下,才会走该方法
     * @param o 原对象属性值,value
     * @param aclass 目标对象属性 类型,class java.lang.string
     * @param o1 目标对象属性set方法,setaddress
     * @return
     */
    @override
    public object convert(object o, class aclass, object o1) {
        if (o.getclass().equals(aclass)) {
            return o;
        } else {
            if (o instanceof integer) {
                return string.valueof(o);
            }
            if (string.valueof(o1).contains("age")) {
                return integer.valueof(o.tostring());
            }
            return o;
        }
    }
 
}

测试方法

 @test
    public void test2() {
        student student = new student(1,"zhagnsan","18","110112113114","diqiu");
 
        // false 表示不使用 转换器,
        beancopier entitytodto = beancopier.create(student.class, studentdto.class, false);
        studentdto studentdto3 = new studentdto();
        // null 表示,不指定转换器,要使用转换器的化,需要实现 converter 接口
        // 属性名称之间不能指定映射关系,当属性名称不同的时候赋值操作会失败
        entitytodto.copy(student, studentdto3, null);
        system.out.println("cglib :entitytodto " + studentdto3.tostring());
 
        beancopier dtotovo = beancopier.create(studentdto.class, studentvo.class, false);
        studentvo studentvo1 = new studentvo();
        dtotovo.copy(studentdto3, studentvo1, null);
        system.out.println("cglib: dtotovo " + studentvo1.tostring());
 
        // 一旦使用converter,beancopier只使用converter定义的规则去拷贝属性,所以在convert方法中要考虑所有的属性
        beancopier dtotovo2 = beancopier.create(studentdto.class, studentvo.class, true);
        studentvo studentvo2 = new studentvo();
        dtotovo2.copy(studentdto3, studentvo2, new convertstudentdtotovo());
        system.out.println("cglib : convert "+studentvo2.tostring());
 
    }

四、问题

beanutils  不会进行 属性 类型的转换,如果字段名称相同,类型不同,不会对该字段进行赋值操作,( 测试方法中使用的 是 org.springframework.beans.beanutils )

cglib  在不定义converter 的情况下也会出现 类型转换错误的异常,可以手动自定义转换器 convert ,一旦使用converter,beancopier只使用converter定义的规则去拷贝属性,所以在convert方法中要考虑所有的属性。

springframwork 有实现 cglib 的beancopier 不需要再引用 org.easymock 依赖

到此这篇关于深入理解java对象复制的文章就介绍到这了,更多相关java对象复制内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!