在面向對象的設計里,繼承是非常必要的,我們會把共有的屬性和方法抽象到父類中,由它統一去實現,而在進行lombok時代之后,更多的打法是使用@Builder來進行對象賦值,我們直接在類上加@Builder之后,我們的繼承就被無情的屏蔽了,這主要是由於構造方法與父類沖突的問題導致的,事實上,我們可以把@Builder注解加到子類的全參構造方法
上就可以了!
下面做一個Jpa實體的例子
一個基類
它一般有統一的id,createdOn,updatedOn等字段 ,在基類中統一去維護。
注意:父類中的屬性需要子數去訪問,所以需要被聲明為protected,如果是private,那在賦值時將是不被允許的。
/**
* @MappedSuperclass是一個標識,不會生成這張數據表,子類的@Builder注解需要加在重寫的構造方法上.
*/
@Getter
@ToString(callSuper = true)
@AllArgsConstructor
@NoArgsConstructor
@MappedSuperclass
public abstract class EntityBase {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Column(name = "created_on")
protected LocalDateTime createdOn;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@Column(name = "updated_on")
protected LocalDateTime updatedOn;
/**
* Sets createdAt before insert
*/
@PrePersist
public void setCreationDate() {
this.createdOn = LocalDateTime.now();
this.updatedOn = LocalDateTime.now();
}
/**
* Sets updatedAt before update
*/
@PreUpdate
public void setChangeDate() {
this.updatedOn = LocalDateTime.now();
}
}
一個實現類
注意,需要重寫全參數的構造方法,否則父數中的屬性不能被賦值。
@Entity
@Getter
@NoArgsConstructor
@ToString(callSuper = true)
public class TestEntityBuilder extends EntityBase {
private String title;
private String description;
@Builder(toBuilder = true)
public TestEntityBuilder(Long id, LocalDateTime createdOn, LocalDateTime updatedOn,
String title, String description) {
super(id, createdOn, updatedOn);
this.title = title;
this.description = description;
}
}
單元測試
/**
* 測試:在實體使用繼承時,如何使用@Builder注解.
*/
@Test
public void insertBuilderAndInherit() {
TestEntityBuilder testEntityBuilder = TestEntityBuilder.builder()
.title("lind")
.description("lind is @builder and inherit")
.build();
testBuilderEntityRepository.save(testEntityBuilder);
TestEntityBuilder entity = testBuilderEntityRepository.findById(
testEntityBuilder.getId()).orElse(null);
System.out.println("userinfo:" + entity.toString());
entity = entity.toBuilder().description("修改了").build();
testBuilderEntityRepository.save(entity);
System.out.println("userinfo:" + entity.toString());
}