Is there a more elegant way to convert java entity classes?

conventional conversion method:

a.setId(b.getId());
a.setUserName(b.getName());

when there are dozens of member variables in a class, this approach will become very bad, error-prone and difficult to troubleshoot. Is there a better way to solve this problem?
is there a better way to solve this problem?

Apr.11,2021

If there are few

attributes, you can simply set.

if there are many attributes, you can consider using the Bean toolkit in Apache, mainly using BeanUtils.copyProperties (Object dest,Object orig) and PropertyUtils.copyProperties (Object dest,Object orig), principle is nothing more than reflection to read the list of attributes, and then circular assignment. The main attention is to copy only fields with the same name of dest and orig. For example, orig has a userName attribute and dest has a userName attribute, then orig's userName will be assigned to dest's userName.

I see that when you assign your example name to userName, the above tool is not applicable. Let's simply make a transformation, and the above tool class can be applied. Please take a look at the example:

public class Original{
    private Integer id;
    
    private String name;
    
    private String desc;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public String toString() {
        return "Original [id=" + id + ", name=" + name + ", desc=" + desc + "]";
    }
}


public class Dest{
    
    private Integer id;
    
    private String userName;
    
    private String desc;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    @Override
    public String toString() {
        return "Dest [id=" + id + ", userName=" + userName + ", desc=" + desc
                + "]";
    }
}

import org.apache.commons.beanutils.PropertyUtils;
public class Test {
    
    public static void main(String[] args) throws Exception {
        Original o = new Original();
        o.setId(7);
        o.setName("");
        o.setDesc("");
        Dest d = new Dest();
        PropertyUtils.copyProperties(d, o);
        System.out.println(d);//Dest [id=7, userName=null, desc=]
    }
}

because the userName attribute in d is inconsistent with the name attribute name in original, and the tool knows how to map, we add a public void setName (String userName) {this.userName = userName;} method to the dest class, and then print it out correctly. [id=7, userName= Qixi Festival is happy. The best Qixi Festival gift given to me by desc= 's wife is to give me a day alone]

General bean direct copy, there are many attribute names are the same, a few different, you can use the above method, if there are many different attribute names, then you can write a tool class to achieve mapping configuration.


a.initFromB (b) ?


you can try Bean copy, but the most traditional method is the fastest


.

BeanUtils:
public static void copyProperties (java.lang.Object dest, java.lang.Object orig) throws java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException;

where dest is the target and orig is the original
Spring utility class


this question I also want to know, probably the most elegant way is to click the right mouse button, and then click to copy, the landlord can actually write a plug-in for idea to meet this requirement. It is not difficult to develop plug-ins, you can get started to a simple function in a few hours, and then Slack Off will be ready. / chuckle


you can try the lombok project, using the builder mode, by adding @ Builder
, which is also recommended by Google's code specification:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

/**
 * Created by echo on 2018/8/17.
 */
@Builder
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class User {

  private String name;
  private Integer age;
  private String address;

  public static void main(String[] args) {
    User user = User.builder().name("echo").age(28).address("China").build();
    System.out.println(user);
  }
}
User(name=echo, age=28, address=China)

Process finished with exit code 0

what you need is MapStrut. Because no reflection mechanism is used, the performance is much higher than that of BeanUtil. Conversion is also supported when the attributes or types of the two entities are inconsistent.

A simple example:

1.maven introduces MapStrut as a component

2. Entity examples

class Good{
    int a;
    int b;
    int c;
    //..... 1000000
}
class GoodDto{
   int a;
   int b;
   int c
   // Good 10000001
}

3. Define a transformation interface (you don't need to implement it, the component implements the class for you)

@Mapper(componentModel = "spring")
public interface GoodDtoMapper {

     GoodDto from(Good good);
     
}

4. In the class that needs to be converted

class GoodController{
  
   @Autowired
   GoodDtoMapper dtoMapper;

   public void list(){
         //  Good 
        Good good = findGoods();
        
        //   list to list 
        GoodDto dto = dtoMapper.from(good)

   }

}

example 1:
https://blog.csdn.net/lu_ckid.

example 2:

https://codeshelper.com/a/11.

example 3:
https://www.jianshu.com/p/a04.

MySQL Query : SELECT * FROM `codeshelper`.`v9_news` WHERE status=99 AND catid='6' ORDER BY rand() LIMIT 5
MySQL Error : Disk full (/tmp/#sql-temptable-64f5-1e435d2-44a08.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
MySQL Errno : 1021
Message : Disk full (/tmp/#sql-temptable-64f5-1e435d2-44a08.MAI); waiting for someone to free some space... (errno: 28 "No space left on device")
Need Help?