摘要:想在部署的時候隨應用的啟動而初始化數據腳本,這不就是中的自動生成表結構,聽起來特別簡單,不就是配置的嘛,有什么好說的,是個人都知道。
想在部署的時候隨應用的啟動而初始化數據腳本,這不就是Spring Data Jpa中的自動生成表結構,聽起來特別簡單,不就是配置Hibernate的ddl-auto嘛,有什么好說的,是個人都知道。當初我也是這樣認為,實際操作了一把,雖然表是創建成功了,但是字段注釋,字符集以及數據庫引擎都不對,沒想到在這些細節上翻車了。
畢竟開翻的車還要自己扶起來,粗略寫點救援過程。
注:本文中使用的Spring Data JPA版本為2.1.4.RELEASE
以MySQL為例,其它數據庫可自行驗證:
import com.fasterxml.jackson.annotation.*; import org.hibernate.annotations.*; import org.springframework.data.annotation.*; import javax.persistence.*; import javax.persistence.Entity; import javax.persistence.Id; import java.math.BigDecimal; @Entity @javax.persistence.Table(name = "basic_city") @org.hibernate.annotations.Table(appliesTo = "basic_city", comment = "城市基本信息") public class CityDO { @Id @GenericGenerator(name = "idGenerator", strategy = "uuid") @GeneratedValue(generator = "idGenerator") @Column(name = "CITY_ID", length = 32) private String cityId; @Column(name = "CITY_NAME_CN", columnDefinition = "VARCHAR(255) NOT NULL COMMENT "名稱(中文)"") private String cityNameCN; @Column(name = "CITY_NAME_EN", columnDefinition = "VARCHAR(255) NOT NULL COMMENT "名稱(英文)"") private String cityNameEN; @Column(name = "LONGITUDE", precision = 10, scale = 7) private BigDecimal longitude; @Column(name = "LATITUDE", precision = 10, scale = 7) private BigDecimal latitude; @Column(name = "ELEVATION", precision = 5) private Integer elevation; @Column(name = "CITY_DESCRIPTION", length = 500) private String cityDescription; // 構造方法及get/set方法省略 }
用到的注解簡要說明一下:
@javax.persistence.Table 修改默認ORM規則,屬性name設置表名;
@org.hibernate.annotations.Table 建表時的描述, 屬性comment修改表描述;
@Id 主鍵
@GenericGenerator 該注解為Hibernate的注解,用來生成表的主鍵策略,屬性strategy的值在類DefaultIdentifierGeneratorFactory中定義:
uuid2: UUIDGenerator.class;
guid: GUIDGenerator.class;
uuid: UUIDHexGenerator.class;
uuid.hex: UUIDHexGenerator.class;
assigned: Assigned.class;
identity: IdentityGenerator.class;
select: SelectGenerator.class;
sequence: SequenceStyleGenerator.class;
seqhilo: SequenceHiLoGenerator.class;
increment: IncrementGenerator.class;
foreign: ForeignGenerator.class;
sequence-identity: SequenceIdentityGenerator.class;
enhanced-sequence: SequenceStyleGenerator.class;
enhanced-table: TableGenerator.class;
@GeneratedValue 設置主鍵策略,這里屬性generator指向@GenericGenerator策略的name,屬性strategy有四個枚舉值:
GenerationType.TABLE 使用一個額外的表來存儲主鍵;
GenerationType.SEQUENCE 使用序列的方式存儲,且需要數據庫底層支持;
GenerationType.IDENTITY 由數據庫生成,一般為主鍵自增等;
GenerationType.AUTO 表示由程序生成,不聲明則默認為該屬性;
@Column 修改默認的ORM規則,屬性有:
name設置表中字段名稱,表字段和實體類屬性相同,則該屬性可不寫;
unique設置該字段在表中是否唯一,默認false;
nullable是否可為空,默認true;
insertable表示insert操作時該字段是否響應寫入,默認為true;
updatable表示update操作時該字段是否響應修改,默認為true;
columnDefinition是自定義字段,可以用這個屬性來設置字段的注釋;
table表示當映射多個表時,指定表的表中的字段,默認值為主表的表名;
length是長度,僅對varchar類型的字段生效,默認長度為255;
precision表示一共多少位;
scale表示小數部分占precision總位數的多少位,例子中兩者共同使用來確保經緯度的精度;
接下來需要設置數據引擎和字符集,網上的例子都大把的繼承MySQL5InnoDBDialect,但是這個類已經過期了,我們這里用MySQL5Dialect:
package com.jason.config; import org.hibernate.dialect.MySQL5Dialect; import org.springframework.stereotype.Component; @Component public class MySQL5TableType extends MySQL5Dialect { @Override public String getTableTypeString() { return "ENGINE=InnoDB DEFAULT CHARSET=utf8"; } }
然后在Spring Boot的配置文件中應用上面定義的MySQL5TableType,使用spring.jpa.properties.hibernate.dialect配置(注意書寫格式,這里使用的是yml文件):
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/techno?useUnicode=true&characterEncoding=utf8 username: root password: root jpa: hibernate: ddl-auto: update database-platform: org.hibernate.dialect.MySQL5InnoDBDialect properties: hibernate: dialect: com.jason.config.MySQL5TableType
jpa.hibernate.ddl-auto使用update,其它值及說明為:
create: 啟動服務時都會重新創建表,且不管表存不存在;
create-drop: 啟動服務時都會重新創建表,且不管表存不存在,服務停止時刪除所有表,不管表中是否有數據;
update: 啟動服務時,自動更新表結構,但數據庫表中存在的舊字段不會刪除;
validate: 啟動服務時驗證表結構,若表結構存在差異則拋出異常;
至此,Sprign Data JPA生成表結構就完成了,當我們建立數據庫后,啟動服務就可以在MySQL中得到表結構了,應用可以通過ApplicaitonRunner或者CommandLineRunner接口一鍵部署,省去了初始化SQL等不必要的操作,這兩個接口的簡單使用可以參考我的另外一篇文章。
最后我們再上一個例子,主要是寫入默認值等,部分說明就直接以注釋的形式寫到代碼里,還有@ColumnDefault注解這里就不做說明,大家可以自己了解下:
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import org.hibernate.annotations.*; import org.springframework.data.jpa.repository.*; import javax.persistence.*; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.Temporal; import java.util.Date; @ApiModel(value = "賬號基礎信息") @Entity @Table(name = "basic_account") @org.hibernate.annotations.Table(appliesTo = "basic_account", comment = "賬號基礎信息表") public class AccountDO { @ApiModelProperty(name = "accountId", value = "賬號Id", hidden = true) @Id @GenericGenerator(name = "idGenerator", strategy = "uuid") @GeneratedValue(generator = "idGenerator") @Column(name = "ACCOUNT_ID", length = 32) private String accountId; @ApiModelProperty(name = "username", value = "賬號", dataType = "String", required = true) @Column(length = 32, nullable = false) private String username; // 假設密碼加密后長度為128 @ApiModelProperty(name = "password", value = "密碼", dataType = "String", required = true) @Column(length = 128, nullable = false) private String password; // 新建的賬號未過期,默認值給1,這個值由數據庫生成,則設置insertable為false @ApiModelProperty(name = "isAccountNonExpired", value = "賬號是否過期", hidden = true) @Column(name = "IS_ACCOUNT_EXPIRED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號 0:過期;1:未過期"") private Integer isAccountNonExpired; // 新建的賬號未鎖定,默認值給1,這個值由數據庫生成,則設置insertable為false @Column(name = "IS_ACCOUNT_LOCKED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號 0:鎖定;1:未鎖定"") @ApiModelProperty(name = "isAccountNonLocked", value = "賬號是否鎖定", hidden = true) private Integer isAccountNonLocked; // 新建的賬號密碼未過期,默認值給1,這個值由數據庫生成,則設置insertable為false @Column(name = "IS_CREDENTIALS_EXPIRED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "密碼 0:已過期;1:未過期"") @ApiModelProperty(name = "isCredentialsNonExpired", value = "密碼是否過期", hidden = true) private Integer isCredentialsNonExpired; // 新建的賬號需要激活,默認值給0,這個值由數據庫生成,設置insertable為false @ApiModelProperty(name = "isEnabled", value = "賬號是否可用", hidden = true) @Column(name = "IS_ENABLE", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "0" COMMENT "賬號 0:不可用;1:可用"") private Integer isEnabled; // 新建的賬號,默認值給1,這個值由數據庫生成,設置insertable為false @ApiModelProperty(name = "isDelete", value = "賬號是否刪除", hidden = true) @Column(name = "IS_DELETE", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號 0:已刪除;1:未刪除"") private Integer isDelete; // 新建賬號時間不能修改,設置updatable為false,但此處不能設置insertable = false // @Temporal(TemporalType.TIMESTAMP) 由于表字段類型為TIMESTAMP,所以將Date轉換為TIMESTAMP @ApiModelProperty(name = "createTimestamp", value = "創建時間") @Column(name = "CREATE_TIMESTAMP", nullable = false, updatable = false) @Temporal(TemporalType.TIMESTAMP) @CreationTimestamp private Date createTimestamp; public AccountDO(String username,String password) { this.username = username; this.password = password; } // 其他構造方法及get/set方法省略 }
注:@ApiModel以及@ApiModelProperty為swagger注解。
我們注冊賬號的單元測試就可以直接寫成下面這樣,僅填寫賬號和密碼,其他值則由數據庫生成:
@Test public void saveAccount() throws Exception { accountService.saveAccount(new AccountDO("123456", "654321")); }
原創不易,感謝支持。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74340.html
摘要:的配置后在其他低版本的中也有使用這種配置的,具體根據版本而定。等注解是的相關知識,后面的文章將詳細講述。 ??在我們的實際開發的過程中,無論多復雜的業務邏輯到達持久層都回歸到了增刪改查的基本操作,可能會存在關聯多張表的復雜sql,但是對于單表的增刪改查也是不可避免的,大多數開發人員對于這個簡單而繁瑣的操作都比較煩惱。 ??為了解決這種大量枯燥的簡單數據庫操作,大致的解決該問題的有三種方...
摘要:文章系列從零入門系列之從零入門系列之程序結構設計說明前言本篇文章開始代碼實踐,系統設計從底向上展開,因此本篇先介紹如何實現數據庫表實體類的設計實現。主鍵由數據庫自動生成主要是自動增長型主鍵由程序控制。 文章系列 【從零入門系列-0】Sprint Boot 之 Hello World 【從零入門系列-1】Sprint Boot 之 程序結構設計說明 前言 本篇文章開始代碼實踐,系統...
摘要:最常用的屬性,第一次加載時根據類會自動建立起表的結構前提是先建立好數據庫,以后加載時根據類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。 添加依賴 新建項目選擇web,JPA,MySQL三個依賴 showImg(https://segmentfault.com/img/bV2gNo?w=1684&h=1172); 對于已存在的項目可以在bulid.gradle加入...
摘要:忽略該字段的映射省略創建數據訪問層接口,需要繼承,第一個泛型參數是實體對象的名稱,第二個是主鍵類型。 SpringBoot 是為了簡化 Spring 應用的創建、運行、調試、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規范,引入相關的依賴就可以輕易的搭建出一個 WEB 工程 上一篇介紹了Spring JdbcTempl...
摘要:教程簡介本項目內容為教程樣例。目的是通過學習本系列教程,讀者可以從到掌握的知識,并且可以運用到項目中。本章將進一步講解,結合完成數據層訪問。創建控制器在下面創建控制器用于測試訪問程序運行和調試在類中,啟動程序。 教程簡介 本項目內容為Spring Boot教程樣例。目的是通過學習本系列教程,讀者可以從0到1掌握spring boot的知識,并且可以運用到項目中。如您覺得該項目對您有用,...
閱讀 1393·2021-11-22 15:11
閱讀 2838·2019-08-30 14:16
閱讀 2755·2019-08-29 15:21
閱讀 2914·2019-08-29 15:11
閱讀 2450·2019-08-29 13:19
閱讀 2985·2019-08-29 12:25
閱讀 417·2019-08-29 12:21
閱讀 2829·2019-08-29 11:03