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 Bean
class as the ORM
entity class, or xml、json
when the mapping class, need this class has several features:
- We have no argument constructor;
- Have a
toString()
method; - It has a
setter
method for deserialization; - It has a
getter
method 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: @Data
Notes 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, @Builder
what thing, what did here ... ...
- It creates a
private
full-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 Bean
is not getter
a 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 ToString
annotations, I turned him into json
output:
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 json
it, then from one json
into 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 of
xyz.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 Data
use of the time can be used directly, no arguments constructor, but because of Builder
the introduction of full-argument constructor, then in accordance with java
the 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 Builder
another 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
Builder
the 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 List
we also need a new outside ArrayList
, then build
inside, not comfortable to use. lombok
It 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 clearXXX
way to empty the collection.
There is also a small pit, if we add a title
property, 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? title
How could it be empty? ? This should be Builder
the 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 Builder
on, so Builder
did the assignment, its value is null
, and finally all the attributes are copied to UserBean
, so ` nul
L overrides the default value.
How to get Builder
entity 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 wither
building object mode, which Objective-C
is 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 ApiService
address 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 null
to initialize an object is very strange. And Builder
as Wither
also 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 Builder
similar, but smaller, and does not affect the read-write property, but the property using the same name as a string instead of getter
and 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 fluent
difference is the use getter
and setter
.