成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

Spring Data JPA 自動(dòng)生成表結(jié)構(gòu)

lewif / 3614人閱讀

摘要:想在部署的時(shí)候隨應(yīng)用的啟動(dòng)而初始化數(shù)據(jù)腳本,這不就是中的自動(dòng)生成表結(jié)構(gòu),聽(tīng)起來(lái)特別簡(jiǎn)單,不就是配置的嘛,有什么好說(shuō)的,是個(gè)人都知道。

想在部署的時(shí)候隨應(yīng)用的啟動(dòng)而初始化數(shù)據(jù)腳本,這不就是Spring Data Jpa中的自動(dòng)生成表結(jié)構(gòu),聽(tīng)起來(lái)特別簡(jiǎn)單,不就是配置Hibernateddl-auto嘛,有什么好說(shuō)的,是個(gè)人都知道。當(dāng)初我也是這樣認(rèn)為,實(shí)際操作了一把,雖然表是創(chuàng)建成功了,但是字段注釋?zhuān)址约皵?shù)據(jù)庫(kù)引擎都不對(duì),沒(méi)想到在這些細(xì)節(jié)上翻車(chē)了。

畢竟開(kāi)翻的車(chē)還要自己扶起來(lái),粗略寫(xiě)點(diǎn)救援過(guò)程。

注:本文中使用的Spring Data JPA版本為2.1.4.RELEASE

MySQL為例,其它數(shù)據(jù)庫(kù)可自行驗(yàn)證:

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 "名稱(chēng)(中文)"")
    private String cityNameCN;
    
    @Column(name = "CITY_NAME_EN", columnDefinition = "VARCHAR(255) NOT NULL COMMENT "名稱(chēng)(英文)"")
    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;
    
    // 構(gòu)造方法及get/set方法省略
}

用到的注解簡(jiǎn)要說(shuō)明一下:

@javax.persistence.Table 修改默認(rèn)ORM規(guī)則,屬性name設(shè)置表名;

@org.hibernate.annotations.Table 建表時(shí)的描述, 屬性comment修改表描述;

@Id 主鍵

@GenericGenerator 該注解為Hibernate的注解,用來(lái)生成表的主鍵策略,屬性strategy的值在類(lèi)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 設(shè)置主鍵策略,這里屬性generator指向@GenericGenerator策略的name,屬性strategy有四個(gè)枚舉值:

GenerationType.TABLE 使用一個(gè)額外的表來(lái)存儲(chǔ)主鍵;

GenerationType.SEQUENCE 使用序列的方式存儲(chǔ),且需要數(shù)據(jù)庫(kù)底層支持;

GenerationType.IDENTITY 由數(shù)據(jù)庫(kù)生成,一般為主鍵自增等;

GenerationType.AUTO 表示由程序生成,不聲明則默認(rèn)為該屬性;

@Column 修改默認(rèn)的ORM規(guī)則,屬性有:

name設(shè)置表中字段名稱(chēng),表字段和實(shí)體類(lèi)屬性相同,則該屬性可不寫(xiě);

unique設(shè)置該字段在表中是否唯一,默認(rèn)false;

nullable是否可為空,默認(rèn)true;

insertable表示insert操作時(shí)該字段是否響應(yīng)寫(xiě)入,默認(rèn)為true;

updatable表示update操作時(shí)該字段是否響應(yīng)修改,默認(rèn)為true;

columnDefinition是自定義字段,可以用這個(gè)屬性來(lái)設(shè)置字段的注釋?zhuān)?/p>

table表示當(dāng)映射多個(gè)表時(shí),指定表的表中的字段,默認(rèn)值為主表的表名;

length是長(zhǎng)度,僅對(duì)varchar類(lèi)型的字段生效,默認(rèn)長(zhǎng)度為255;

precision表示一共多少位;

scale表示小數(shù)部分占precision總位數(shù)的多少位,例子中兩者共同使用來(lái)確保經(jīng)緯度的精度;

接下來(lái)需要設(shè)置數(shù)據(jù)引擎和字符集,網(wǎng)上的例子都大把的繼承MySQL5InnoDBDialect,但是這個(gè)類(lèi)已經(jīng)過(guò)期了,我們這里用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的配置文件中應(yīng)用上面定義的MySQL5TableType,使用spring.jpa.properties.hibernate.dialect配置(注意書(shū)寫(xiě)格式,這里使用的是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,其它值及說(shuō)明為:

create: 啟動(dòng)服務(wù)時(shí)都會(huì)重新創(chuàng)建表,且不管表存不存在;

create-drop: 啟動(dòng)服務(wù)時(shí)都會(huì)重新創(chuàng)建表,且不管表存不存在,服務(wù)停止時(shí)刪除所有表,不管表中是否有數(shù)據(jù);

update: 啟動(dòng)服務(wù)時(shí),自動(dòng)更新表結(jié)構(gòu),但數(shù)據(jù)庫(kù)表中存在的舊字段不會(huì)刪除;

validate: 啟動(dòng)服務(wù)時(shí)驗(yàn)證表結(jié)構(gòu),若表結(jié)構(gòu)存在差異則拋出異常;

至此,Sprign Data JPA生成表結(jié)構(gòu)就完成了,當(dāng)我們建立數(shù)據(jù)庫(kù)后,啟動(dòng)服務(wù)就可以在MySQL中得到表結(jié)構(gòu)了,應(yīng)用可以通過(guò)ApplicaitonRunner或者CommandLineRunner接口一鍵部署,省去了初始化SQL等不必要的操作,這兩個(gè)接口的簡(jiǎn)單使用可以參考我的另外一篇文章。

最后我們?cè)偕弦粋€(gè)例子,主要是寫(xiě)入默認(rèn)值等,部分說(shuō)明就直接以注釋的形式寫(xiě)到代碼里,還有@ColumnDefault注解這里就不做說(shuō)明,大家可以自己了解下:

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 = "賬號(hào)基礎(chǔ)信息")
@Entity
@Table(name = "basic_account")
@org.hibernate.annotations.Table(appliesTo = "basic_account", comment = "賬號(hào)基礎(chǔ)信息表")
public class AccountDO {

    @ApiModelProperty(name = "accountId", value = "賬號(hào)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 = "賬號(hào)", dataType = "String", required = true)
    @Column(length = 32, nullable = false)
    private String username;

    // 假設(shè)密碼加密后長(zhǎng)度為128
    @ApiModelProperty(name = "password", value = "密碼", dataType = "String", required = true)
    @Column(length = 128, nullable = false)
    private String password;

    // 新建的賬號(hào)未過(guò)期,默認(rèn)值給1,這個(gè)值由數(shù)據(jù)庫(kù)生成,則設(shè)置insertable為false
    @ApiModelProperty(name = "isAccountNonExpired", value = "賬號(hào)是否過(guò)期", hidden = true)
    @Column(name = "IS_ACCOUNT_EXPIRED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號(hào) 0:過(guò)期;1:未過(guò)期"")
    private Integer isAccountNonExpired;

    // 新建的賬號(hào)未鎖定,默認(rèn)值給1,這個(gè)值由數(shù)據(jù)庫(kù)生成,則設(shè)置insertable為false
    @Column(name = "IS_ACCOUNT_LOCKED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號(hào) 0:鎖定;1:未鎖定"")
    @ApiModelProperty(name = "isAccountNonLocked", value = "賬號(hào)是否鎖定", hidden = true)
    private Integer isAccountNonLocked;

    // 新建的賬號(hào)密碼未過(guò)期,默認(rèn)值給1,這個(gè)值由數(shù)據(jù)庫(kù)生成,則設(shè)置insertable為false
    @Column(name = "IS_CREDENTIALS_EXPIRED", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "密碼 0:已過(guò)期;1:未過(guò)期"")
    @ApiModelProperty(name = "isCredentialsNonExpired", value = "密碼是否過(guò)期", hidden = true)
    private Integer isCredentialsNonExpired;

    // 新建的賬號(hào)需要激活,默認(rèn)值給0,這個(gè)值由數(shù)據(jù)庫(kù)生成,設(shè)置insertable為false
    @ApiModelProperty(name = "isEnabled", value = "賬號(hào)是否可用", hidden = true)
    @Column(name = "IS_ENABLE", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "0" COMMENT "賬號(hào) 0:不可用;1:可用"")
    private Integer isEnabled;

    // 新建的賬號(hào),默認(rèn)值給1,這個(gè)值由數(shù)據(jù)庫(kù)生成,設(shè)置insertable為false
    @ApiModelProperty(name = "isDelete", value = "賬號(hào)是否刪除", hidden = true)
    @Column(name = "IS_DELETE", insertable = false, columnDefinition = "CHAR(1) NOT NULL DEFAULT "1" COMMENT "賬號(hào) 0:已刪除;1:未刪除"")
    private Integer isDelete;

    // 新建賬號(hào)時(shí)間不能修改,設(shè)置updatable為false,但此處不能設(shè)置insertable = false
    // @Temporal(TemporalType.TIMESTAMP) 由于表字段類(lèi)型為T(mén)IMESTAMP,所以將Date轉(zhuǎn)換為T(mén)IMESTAMP
    @ApiModelProperty(name = "createTimestamp", value = "創(chuàng)建時(shí)間")
    @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;
    }
    
    // 其他構(gòu)造方法及get/set方法省略
}

注:@ApiModel以及@ApiModelPropertyswagger注解。

我們注冊(cè)賬號(hào)的單元測(cè)試就可以直接寫(xiě)成下面這樣,僅填寫(xiě)賬號(hào)和密碼,其他值則由數(shù)據(jù)庫(kù)生成:

    @Test
    public void saveAccount() throws Exception {
        accountService.saveAccount(new AccountDO("123456", "654321"));
    }

原創(chuàng)不易,感謝支持。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74340.html

相關(guān)文章

  • SpringBoot2.0之三 優(yōu)雅整合Spring Data JPA

    摘要:的配置后在其他低版本的中也有使用這種配置的,具體根據(jù)版本而定。等注解是的相關(guān)知識(shí),后面的文章將詳細(xì)講述。 ??在我們的實(shí)際開(kāi)發(fā)的過(guò)程中,無(wú)論多復(fù)雜的業(yè)務(wù)邏輯到達(dá)持久層都回歸到了增刪改查的基本操作,可能會(huì)存在關(guān)聯(lián)多張表的復(fù)雜sql,但是對(duì)于單表的增刪改查也是不可避免的,大多數(shù)開(kāi)發(fā)人員對(duì)于這個(gè)簡(jiǎn)單而繁瑣的操作都比較煩惱。 ??為了解決這種大量枯燥的簡(jiǎn)單數(shù)據(jù)庫(kù)操作,大致的解決該問(wèn)題的有三種方...

    ningwang 評(píng)論0 收藏0
  • 【從零入門(mén)系列-2】Spring Boot 之 數(shù)據(jù)庫(kù)實(shí)體定義實(shí)現(xiàn)

    摘要:文章系列從零入門(mén)系列之從零入門(mén)系列之程序結(jié)構(gòu)設(shè)計(jì)說(shuō)明前言本篇文章開(kāi)始代碼實(shí)踐,系統(tǒng)設(shè)計(jì)從底向上展開(kāi),因此本篇先介紹如何實(shí)現(xiàn)數(shù)據(jù)庫(kù)表實(shí)體類(lèi)的設(shè)計(jì)實(shí)現(xiàn)。主鍵由數(shù)據(jù)庫(kù)自動(dòng)生成主要是自動(dòng)增長(zhǎng)型主鍵由程序控制。 文章系列 【從零入門(mén)系列-0】Sprint Boot 之 Hello World 【從零入門(mén)系列-1】Sprint Boot 之 程序結(jié)構(gòu)設(shè)計(jì)說(shuō)明 前言 本篇文章開(kāi)始代碼實(shí)踐,系統(tǒng)...

    nemo 評(píng)論0 收藏0
  • Spring Boot快速入門(mén)(四):使用jpa進(jìn)行數(shù)據(jù)庫(kù)操作

    摘要:最常用的屬性,第一次加載時(shí)根據(jù)類(lèi)會(huì)自動(dòng)建立起表的結(jié)構(gòu)前提是先建立好數(shù)據(jù)庫(kù),以后加載時(shí)根據(jù)類(lèi)自動(dòng)更新表結(jié)構(gòu),即使表結(jié)構(gòu)改變了但表中的行仍然存在不會(huì)刪除以前的行。 添加依賴(lài) 新建項(xiàng)目選擇web,JPA,MySQL三個(gè)依賴(lài) showImg(https://segmentfault.com/img/bV2gNo?w=1684&h=1172); 對(duì)于已存在的項(xiàng)目可以在bulid.gradle加入...

    Kyxy 評(píng)論0 收藏0
  • 一起來(lái)學(xué)SpringBoot | 第六篇:整合SpringDataJpa

    摘要:忽略該字段的映射省略創(chuàng)建數(shù)據(jù)訪(fǎng)問(wèn)層接口,需要繼承,第一個(gè)泛型參數(shù)是實(shí)體對(duì)象的名稱(chēng),第二個(gè)是主鍵類(lèi)型。 SpringBoot 是為了簡(jiǎn)化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問(wèn)題而誕生的產(chǎn)物,自動(dòng)裝配的特性讓我們可以更好的關(guān)注業(yè)務(wù)本身而不是外部的XML配置,我們只需遵循規(guī)范,引入相關(guān)的依賴(lài)就可以輕易的搭建出一個(gè) WEB 工程 上一篇介紹了Spring JdbcTempl...

    Dionysus_go 評(píng)論0 收藏0
  • Spring Boot 教程(二):使用Spring Boot JPA完成數(shù)據(jù)層訪(fǎng)問(wèn)

    摘要:教程簡(jiǎn)介本項(xiàng)目?jī)?nèi)容為教程樣例。目的是通過(guò)學(xué)習(xí)本系列教程,讀者可以從到掌握的知識(shí),并且可以運(yùn)用到項(xiàng)目中。本章將進(jìn)一步講解,結(jié)合完成數(shù)據(jù)層訪(fǎng)問(wèn)。創(chuàng)建控制器在下面創(chuàng)建控制器用于測(cè)試訪(fǎng)問(wèn)程序運(yùn)行和調(diào)試在類(lèi)中,啟動(dòng)程序。 教程簡(jiǎn)介 本項(xiàng)目?jī)?nèi)容為Spring Boot教程樣例。目的是通過(guò)學(xué)習(xí)本系列教程,讀者可以從0到1掌握spring boot的知識(shí),并且可以運(yùn)用到項(xiàng)目中。如您覺(jué)得該項(xiàng)目對(duì)您有用,...

    DevWiki 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

lewif

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<