實體繼承與@Builder注解共存(cun)
在面向對象的設計里,繼承是非常必要的,我們會把共有的屬性和方法抽象到父類中,由它統一去實現,而在進行lombok時代之后,更多的打法是使用@Builder來進行對象賦值,我們直接在類上加@Builder之后,我們的繼承就被無情的屏蔽了,這主要是由于構造方法與父類沖突的問題導致的,事實上,我們可以把@Builder注解加到子類的全參構造方法上就可以了!
下面做(zuo)一(yi)個Jpa實體的(de)例子(zi)
一個基類
它一(yi)般有統一(yi)的(de)id,createdOn,updatedOn等(deng)字段 ,在基(ji)類中(zhong)統一(yi)去維護。
注意(yi):父類(lei)中(zhong)的屬性(xing)需要子數去訪問,所以需要被(bei)聲明為protected,如果是private,那(nei)在(zai)賦值時將(jiang)是不被(bei)允(yun)許的。
/**
* @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();
}
}
一個實現類
注(zhu)意,需(xu)要重寫全參數(shu)的構(gou)造方法,否(fou)則父數(shu)中的屬性不能被(bei)賦值(zhi)。
@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());
}