国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

從零開始 Spring Boot 51:JPA 中的默認(rèn)列值

這篇具有很好參考價(jià)值的文章主要介紹了從零開始 Spring Boot 51:JPA 中的默認(rèn)列值。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

從零開始 Spring Boot 51:JPA 中的默認(rèn)列值

從零開始 Spring Boot 51:JPA 中的默認(rèn)列值

圖源:簡書 (jianshu.com)

JPA 是一個(gè) ORM 框架,因此,通常我們需要在實(shí)體類中定義表結(jié)構(gòu),這其中就包含可能的字段默認(rèn)值。

本文介紹如何在 Hibernate(JPA)中設(shè)置默認(rèn)列值(Default Column Value)。

默認(rèn)屬性值

最簡單的方式是對實(shí)體類指定一個(gè)默認(rèn)的屬性值,比如:

@Data
@Table(name = "USER_TREE")
@Entity
public class Tree {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(nullable = false)
    private Integer age = 5;
}

測試用例:

@Test
void testAddTreeWithDefaultValue(){
    Tree tree = new Tree();
    treeRepository.save(tree);
    Assertions.assertEquals(5, tree.getAge());
}

這樣做的缺點(diǎn)是由 Hibernate 自動(dòng)生成的表結(jié)構(gòu)中并不會(huì)體現(xiàn)字段的默認(rèn)值:

CREATE TABLE `user_tree` (
  `id` bigint NOT NULL,
  `age` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

一般來說是不會(huì)產(chǎn)生什么影響的,但如果我們直接在數(shù)據(jù)庫中執(zhí)行 INSERT SQL,并且期望對擁有默認(rèn)值的字段使用缺省,就無法實(shí)現(xiàn)。

columnDefinition

通過@ColumncolumnDefinition屬性,我們可以指定表結(jié)構(gòu)的字段定義,可以利用這一點(diǎn)指定 DDL 語句中的字段默認(rèn)值:

@Data
@Table(name = "USER_TEACHER")
@Entity
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(columnDefinition = "varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'icexmoon'")
    private String name;
}

Hibernate 生成的表結(jié)構(gòu)中的確會(huì)出現(xiàn)字段的默認(rèn)值:

CREATE TABLE `user_teacher` (
  `id` bigint NOT NULL,
  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'icexmoon',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci

但遺憾的是,Hibernate 并不能識(shí)別columnDefinition屬性中的表字段默認(rèn)值,并像我們期待的那樣在添加實(shí)體實(shí)例時(shí)自動(dòng)使用:

@Test
void testAddTeacherWithDefaultValue() {
    Teacher teacher = new Teacher();
    teacherRepository.save(teacher);
    var findTeacher = teacherRepository.findAll().stream().findFirst().get();
    Assertions.assertNull(findTeacher.getName());
}

這個(gè)示例中添加到數(shù)據(jù)庫中的Teacher實(shí)際上其namenull。

@DynamicInsert

可以使用@@DynamicInsert解決上述問題,這個(gè)注解可以讓實(shí)體的 INSERT SQL 排除值為null的字段:

@DynamicInsert
// ...
public class Teacher {
	// ...
}

測試用例:

@Test
void testAddTeacherWithDefaultValue() {
    Teacher teacher = new Teacher();
    teacherRepository.save(teacher);
    var findTeacher = teacherRepository.findAll().stream().findFirst().get();
    Assertions.assertNotNull(findTeacher.getName());
    Assertions.assertEquals("icexmoon", findTeacher.getName());
}

可以看到此時(shí)的 Hibernate SQL 日志:

Hibernate: insert into user_teacher (id) values (?)

所以自然而然的,插入的數(shù)據(jù)中name字段使用了 DDL name 字段的默認(rèn)值。

但這樣做依然有一個(gè)問題——不會(huì)體現(xiàn)在我們用于插入的實(shí)體上,需要重新從數(shù)據(jù)庫加載實(shí)體才行:

@Test
void testAddTeacherWithDefaultValue2() {
    Teacher teacher = new Teacher();
    teacherRepository.save(teacher);
    Assertions.assertNull(teacher.getName());
    // ...
}

可以看到,Hibernate 并不會(huì)在這種情況下幫助我們自動(dòng)重新加載實(shí)體(以獲取通過數(shù)據(jù)庫指定的字段默認(rèn)值)。

默認(rèn)屬性+columnDefinition

更合理的做法是結(jié)合默認(rèn)屬性以及用columnDefinition指定 DDL 字段默認(rèn)值:

@Getter
@Setter
@Entity
@ToString
@EqualsAndHashCode
@Table(name = "USER_STUDENT")
@Accessors(chain = true)
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @EqualsAndHashCode.Exclude
    private Long id;

    public static final String DEFAULT_NAME = "icexmoon";
    @Column(name = "NAME", columnDefinition = "varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'icexmoon'")
    private String name = DEFAULT_NAME;

    public static final LocalDate DEFAULT_BIRTH_DAY = LocalDate.of(2022, 1, 1);
    @Setter(AccessLevel.NONE)
    @Column(name = "BIRTH_DAY", columnDefinition = "date DEFAULT '2002-01-01'")
    private LocalDate birthDay = DEFAULT_BIRTH_DAY;

    @Transient
    @Setter(AccessLevel.NONE)
    @Getter(AccessLevel.NONE)
    @EqualsAndHashCode.Exclude
    @Nullable
    private Integer age;

    public static final Gender DEFAULT_GENDER = Gender.MALE;
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "gender", columnDefinition = "tinyint DEFAULT '0'")
    private Gender gender = DEFAULT_GENDER;
    // ...
}

這樣做其實(shí)依然有個(gè)缺陷,如果要修改屬性默認(rèn)值,最好同時(shí)修改columnDefinition中的default值,否則就會(huì)出現(xiàn)語義上的不一致。我有嘗試過在指定columnDefinition值時(shí)用表達(dá)式指定默認(rèn)值,但只能使用常量表達(dá)式,無法實(shí)現(xiàn)復(fù)雜語義。

測試用例:

@Test
void testNewStudentWithDefaultValue() {
    Student student = new Student();
    studentRepository.save(student);
    Assertions.assertEquals(Student.DEFAULT_NAME, student.getName());
    Assertions.assertEquals(Student.DEFAULT_BIRTH_DAY, student.getBirthDay());
    Assertions.assertEquals(Student.DEFAULT_GENDER, student.getGender());
    var findStudent = studentRepository.findOne(Example.of(new Student().setName(Student.DEFAULT_NAME))).get();
    Assertions.assertNotNull(findStudent);
    Assertions.assertEquals(Student.DEFAULT_NAME, findStudent.getName());
    Assertions.assertEquals(Student.DEFAULT_BIRTH_DAY, findStudent.getBirthDay());
    Assertions.assertEquals(Student.DEFAULT_GENDER, findStudent.getGender());
}

The End,謝謝閱讀。

可以從這里獲取本文的完整測試用例。文章來源地址http://www.zghlxwxcb.cn/news/detail-510945.html

參考資料

  • Default Column Values in JPA | Baeldung
  • hibernate設(shè)置默認(rèn)值

到了這里,關(guān)于從零開始 Spring Boot 51:JPA 中的默認(rèn)列值的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 從零開始學(xué)Spring Boot系列-前言

    在數(shù)字化和信息化的時(shí)代,Java作為一種成熟、穩(wěn)定且廣泛應(yīng)用的編程語言,已經(jīng)成為構(gòu)建企業(yè)級(jí)應(yīng)用的首選。而在Java生態(tài)系統(tǒng)中,Spring框架無疑是其中最為耀眼的一顆明星。它提供了全面的編程和配置模型,用于構(gòu)建企業(yè)級(jí)應(yīng)用。隨著Spring Boot的出現(xiàn),這一框架變得更加易于

    2024年02月22日
    瀏覽(34)
  • 從零開始學(xué)Spring Boot系列-SpringApplication

    SpringApplication類提供了一種從main()方法啟動(dòng)Spring應(yīng)用的便捷方式。在很多情況下, 你只需委托給 SpringApplication.run這個(gè)靜態(tài)方法 : 當(dāng)應(yīng)用啟動(dòng)時(shí), 你應(yīng)該會(huì)看到類似下面的東西: 默認(rèn)情況下會(huì)顯示INFO級(jí)別的日志信息, 包括一些相關(guān)的啟動(dòng)詳情, 比如啟動(dòng)應(yīng)用的用戶等。 通過

    2024年04月08日
    瀏覽(27)
  • 從零開始 Spring Boot 63:Hibernate 繼承映射

    從零開始 Spring Boot 63:Hibernate 繼承映射

    圖源:簡書 (jianshu.com) 關(guān)系型數(shù)據(jù)庫設(shè)計(jì)中是不存在繼承概念的,但實(shí)體類可以用繼承來組織代碼結(jié)構(gòu),所以需要用一種方式將實(shí)體類的繼承結(jié)構(gòu)映射到表結(jié)構(gòu)。 本文將介紹幾種在 JPA(Hibernate)中映射實(shí)體類繼承層次的方式。 第一種方式是用 @MappedSuperclass 標(biāo)記超類(Super

    2024年02月12日
    瀏覽(19)
  • 從零開始學(xué)Spring Boot系列-集成Kafka

    Apache Kafka是一個(gè)開源的分布式流處理平臺(tái),由LinkedIn公司開發(fā)和維護(hù),后來捐贈(zèng)給了Apache軟件基金會(huì)。Kafka主要用于構(gòu)建實(shí)時(shí)數(shù)據(jù)管道和流應(yīng)用。它類似于一個(gè)分布式、高吞吐量的發(fā)布-訂閱消息系統(tǒng),可以處理消費(fèi)者網(wǎng)站的所有動(dòng)作流數(shù)據(jù)。這種動(dòng)作流數(shù)據(jù)包括頁面瀏覽、搜

    2024年03月21日
    瀏覽(23)
  • 從零開始學(xué)Spring Boot系列-集成mybatis

    在Spring Boot的應(yīng)用開發(fā)中,MyBatis是一個(gè)非常流行的持久層框架,它支持定制化SQL、存儲(chǔ)過程以及高級(jí)映射。在本篇文章中,我們將學(xué)習(xí)如何在Spring Boot項(xiàng)目中集成MyBatis,以便通過MyBatis進(jìn)行數(shù)據(jù)庫操作。 首先,我們需要在項(xiàng)目中添加MyBatis的依賴。在Spring Boot中,我們通常會(huì)使

    2024年03月10日
    瀏覽(25)
  • Spring Boot(04):讓你的Spring Boot應(yīng)用“火力全開”,從零開始學(xué)習(xí)starter

    Spring Boot(04):讓你的Spring Boot應(yīng)用“火力全開”,從零開始學(xué)習(xí)starter

    ????????Spring Boot是一款非常流行的Java開發(fā)框架,其具有快速開發(fā)、自動(dòng)化配置、內(nèi)嵌服務(wù)器、易于擴(kuò)展等特點(diǎn),因此備受開發(fā)者歡迎。在日常開發(fā)中,我們經(jīng)常需要在不同的環(huán)境中進(jìn)行測試和部署,此時(shí),如何實(shí)現(xiàn)開發(fā)、測試、生產(chǎn)環(huán)境的快速切換,成為了我們需要解決

    2024年04月13日
    瀏覽(22)
  • 從零開始 Spring Boot 37:初始化 ApplicationContext

    從零開始 Spring Boot 37:初始化 ApplicationContext

    圖源:簡書 (jianshu.com) 從前文可以知道,作為 Ioc 容器的 ApplicationContext,需要進(jìn)行一系列步驟來初始化以最終就緒(對于 Web 應(yīng)用來說就是可以提供Http服務(wù))。 這些步驟大概可以分為以下內(nèi)容: 準(zhǔn)備上下文關(guān)聯(lián)的 Environment 。 初始化 ApplicationContext( ApplicationContextInitializers

    2024年02月08日
    瀏覽(26)
  • 從零開始 Spring Boot 38:Lombok 與依賴注入

    從零開始 Spring Boot 38:Lombok 與依賴注入

    圖源:簡書 (jianshu.com) 在之前的文章中,我詳細(xì)介紹了 Lombok 的用法,考慮到在 Spring 中使用依賴注入(DI)是如此的頻繁,因此有必要討論使用 Lombok 時(shí)可能對依賴注入造成的影響。 我們都知道,Spring 中的依賴注入分為三種情況: 通過屬性進(jìn)行依賴注入。 通過構(gòu)造器進(jìn)行依

    2024年02月08日
    瀏覽(37)
  • 從零開始 Spring Boot 52:@Embedded 和 @Embeddable

    從零開始 Spring Boot 52:@Embedded 和 @Embeddable

    圖源:簡書 (jianshu.com) 這篇文章會(huì)介紹 @Embedded 和 @Embeddable 兩個(gè)注解在 JPA 中的用法。 先看一個(gè)示例: 這里使用了 Lombok 相關(guān)注解(比如 @Builder )幫助構(gòu)建實(shí)體類,詳細(xì)內(nèi)容可以閱讀我的相關(guān)文章。 user_student 是一個(gè)學(xué)生表,其中的 contacts_ 開頭的字段保存聯(lián)系人信息,這體

    2024年02月12日
    瀏覽(17)
  • 從零開始學(xué)Spring Boot系列-外部化配置

    從零開始學(xué)Spring Boot系列-外部化配置

    Spring Boot 允許你將配置外部化,以便可以在不同的環(huán)境中使用相同的應(yīng)用程序代碼??梢允褂脤傩晕募?、YAML文件、環(huán)境變量和命令行參數(shù)將配置外部化。屬性值可以通過使用 @Value 注解直接注入 bean,可以通過 Spring 的 Environment 抽象訪問,也可以通過 @ConfigurationProperties。 Sp

    2024年04月10日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包