How to use third-party plug-ins to write elegant entity class

How to use third-party plug-ins to write elegant entity class

First of all, here to solve what everyone's wondering, what is the third-party plug-ins? What is the entity class?

First: third-party plug means:Lombok

Second: The entity class means: everybody Development bean\pojo\entity

The following have introductions at convenient programming of Lombok to bring ... ...

1.ORM entity class

When a java Beanclass as the ORMentity class, or xml、jsonwhen the mapping class, need this class has several features:

  • We have no argument constructor;
  • Have a toString()method;
  • It has a settermethod for deserialization;
  • It has a gettermethod for serialization.

First, a simple example

package xyz.mrzhangxd.lombokProject;

import lombok.Data;

@Data
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

Brush up: @DataNotes equivalent to the Assembly@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode

2.Builder

Mode configuration, frequently used in many of the tools.

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;

@Builder
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

So the question is, @Builderwhat thing, what did here ... ...

  • It creates a privatefull-arguments constructor. Which means no-argument constructor is not; it also means that this class can not directly construct the object;
  • It creates a method for each attribute assigned to the same name, the place setter, and the method returns a value of the object itself.

Come on, let's practice what:

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean();
    ub.userId(1001);
    ub.userName("MrZhangxd");
    ub.passWord("123456");
    ub.build();
    System.out.println(u);
}

However, and futile, since this Beanis not gettera method, inside the data can not be used directly. Just say useless, you will continue to find this thing output is: xyz.mrzhangxd.lombokProject.UserBean@20322d26, not even look to see what stuff. Therefore, Builder provides a possibilities, the actual need something more.

So, we need to add in order to facilitate testing  @ToString() notes, will output UserBean(userId=1001, userName=MrZhangxd,passWord=123456)

So some of the kids do not like to add ToStringannotations, I turned him into jsonoutput:

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean();
    ub.userId(1001);
    ub.userName("MrZhangxd");
    ub.passWord("123456");
    ub.build();
    ObjectMapper om = new ObjectMapper();
    System.out.println(om.writeValueAsString(u));
}

Obviously, I did lie to you, it will appear the following exception:

```com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class``` xyz.mrzhangxd.lombokProject.UserBean``` and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

So, is a mistake, we will come up with our investigation and bug big move, and the big move in the development of on-line ... ...

See no properties discovered it, yes, tools property can not be found, because there is no getter, then we add  @Getter it.

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

Serialized into jsonit, then from one jsoninto anti-sequence objects it?

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Builder
@Getter
@Setter
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

Congratulations to the kids in the award, we will encounter  com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance ofxyz.mrzhangxd.lombokProject.UserBean(no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

As already explained the only plus  @Setter is not enough, we also need a no-argument constructor. Then the following can you?

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Data;


@Builder
@Data
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

The same can not, because although the Datause of the time can be used directly, no arguments constructor, but because of Builderthe introduction of full-argument constructor, then in accordance with javathe rules of the native, non-argument constructor is not. Then coupled with a no-argument constructor

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Builder
@Data
@NoArgsConstructor
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

Yet Builderanother error, and it can not find full-argument constructor, finally, unique skills on the line ... ...

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}
  • Note that the access level of the whole argument constructor, do not destroy Builderthe rule.

Now, we are one step closer to see the entity classes with the List

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
    //用户地址
    private List<String> address;
}

This Listwe also need a new outside ArrayList, then buildinside, not comfortable to use. lombokIt provides another with the use of annotations, that is  @Singular, as follows:

package xyz.mrzhangxd.lombokProject;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Singular;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
    //用户地址
    @Singular
    private List<String> address;
}

The following test ... ...

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean()
    .userId(1001)
    .userName("MrZhangxd")
    .passWord("123456")
    .address("beijing")
    .address("shanghai")
    .build();
}

Write here, the kids are not to give me a praise it, is not simply a good feeling Doha, and also provides a clearXXXway to empty the collection.

There is also a small pit, if we add a titleproperty, then give it a default value:

package xyz.mrzhangxd.lombokProject;
import xyz.mrzhangxd.lombokProject.UserBean;

import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
    private String title = "爱你么么哒...";
}

As a senior programmer, I wrote here what most wanted to do one thing? ? You are not wrong, that is, unit testing, Come, come, take a wave ... ...

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean()
    .userId(1001)
    .userName("MrZhangxd")
    .passWord("123456")
    .build();
    System.out.println(ub.toString());
}

Well, the exciting time, take a look at the following output:

UserBean(userId=1001,uaerName=MrZhangxd,passWord=123456,title=null)

Yeah yeah yeah, not ah? titleHow could it be empty? ? This should be Builderthe principle to explain, he is actually a set of attribute values are set list, and then create an object using a full-arg constructor. So, defaults on the Bean, is not Builderon, so Builderdid the assignment, its value is null, and finally all the attributes are copied to UserBean, so ` nulL overrides the default value.

How to get Builderentity has a default value it? Just give the field level may increase @Default comment.

package xyz.mrzhangxd.lombokProject;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
    @Default
    private String title = "爱你么么哒...";
}

If the heart, dream on, just start all over again ... ...

Come, come, do not lose heart, the test to see if the output:

UserBean(userId=1001,uaerName=MrZhangxd,passWord=123456,title=爱你么么哒...)

3.Wither

A witherbuilding object mode, which Objective-Cis more common in.

The scenario is applicable, using several parameters necessary to build objects, other parameters, dynamic assembly. For example, we built a ApiClient, it's a user name and password is necessary, his ApiServiceaddress has a default value, then we can customize this address.

package xyz.mrzhangxd.lombokProject;

import lombok.AllArgsConstructor;
import lombok.experimental.Wither;

@Wither
@AllArgsConstructor
public class ApiClient {
    private String appId;
    private String appKey;
    private String endpoint="http://api.xxxx.com/xxx";
}

So the question is, how to use ah

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.ApiClient;

@Test
public class lombokDemoTest(){
    ApiClient aclient = new ApiClient(null,null,null);
    System.out.println(aclient);
  
    Object aclient1 = aclient.withAppId("20200107")
        .withAppKey("MrZhangxd")
        .withEndpoint("http://192.168.xxx.xxx/");
    System.out.println(aclient1);
}

The default use nullto initialize an object is very strange. And Builderas Witheralso offers the possibility of practical use also need to adjust it.

We can set a mandatory parameter constructors, as follows:

package xyz.mrzhangxd.lombokProject;

import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Wither;

@RequiredArgsConstructor
@Wither
@AllArgsConstructor
public class ApiClient {
    @NonNull
    private String appId;
    @NonNull
    private String appKey;
    private String endpoint="http://api.xxxx.com/xxx";
}

Very confident to tell the kids, the instrument allows to the ... ...

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.ApiClient;

@Test
public class lombokDemoTest(){
    ApiClient aclient=new ApiClient("20200107", "MrZhangxd");
    System.out.println(aclient);
        
    Object aclient1 = aclient.withEndpoint("http://192.168.xxx.xxx/");
    System.out.println(aclient)1;
}

Tell blogger, it is not elegant sorts, but actually using a chain syntax to use:

ApiClient client1=new ApiClient("20200107", "MrZhangxd").
    withEndpoint("http://192.168.xxx.xxx/");

There is also a small detail, the preceding example the following output:

xyz.mrzhangxd.lombokProject.ApiClient@786830e
xyz.mrzhangxd.lombokProject.ApiClient@470e7030

The log indicates that, with () returns the object is not the original object, but a new object, which is very important.

4.Accessors

Access mode, is to give a general increase of Bean a convenient access device, including reading and writing.

It has two operating modes, fluent and chain, exemplified:

package xyz.mrzhangxd.lombokProject;


import lombok.Accessors;
import lombok.Data;


@Data
@Accessors(fluent = true)
public class UserBean{
    //用户id
    private Integer userId;
    //用户名
    private String userName;
    //用户密码
    private String passWord;
}

So the question is, how to use ah

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean()
    .userId(1001)
    .userName("MrZhangxd")
    .passWord("123456");
    ub.setUserName("MrZ")
    System.out.println(ub.getUserName());
}

This is Buildersimilar, but smaller, and does not affect the read-write property, but the property using the same name as a string instead of getterand setter.

Another model is the chain:

package xyz.mrzhangxd.lombokDemo;
import xyz.mrzhangxd.lombokProject.UserBean;

@Test
public class lombokDemoTest(){
    UserBean ub = new UserBean()
    .setUserId(1001)
    .setUserName("MrZhangxd")
    .setPassWord("123456");
  
    ub.setUserName("MrZ")
    System.out.println(ub.getUserName());
}

Can see, this fluentdifference is the use getterand setter.

Guess you like

Origin www.cnblogs.com/MrZhangxd/p/12159865.html