JAVA 8
Spring Boot 2.5.3
MySQL 5.7.21
---
注,本文代碼使用了 org.projectlombok:lombok (版本 由 Spring Boot 指定)。
目錄
Spring Boot項目數據庫配置:
數據庫配置
# MySQL on Ubuntu
spring.datasource.url=jdbc:mysql://mylinux:3306/jpa?serverTimezone=Asia/Shanghai
spring.datasource.username=springuser
spring.datasource.password=ThePassword
#spring.datasource.driver-class-name =com.mysql.jdbc.Driver # This is deprecated
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# 打開使用過程中執行的SQL語句
spring.jpa.show-sql: true
實體類都是 POJO 對象,因此使用了 lombok 的 @Data 註解。
使用 @Entity 註解(javax.persistence.Entity,後面如無 特別說明,註解都來自 javax.persistence包)。
@Entity
@Data
public class User {
默認建立表名爲 user(全小寫),可以使用 name屬性指定表名。
@Entity(name="user2")
@Data
public class User {
上面兩種情況下建立的 兩張表 如下:
使用 @Id 註解 即可;
使用 @GeneratedValue 註解,是配置 主鍵的 自增策略;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
自增策略 可見 GenerationType 枚舉類:
TABLE
SEQUENCE
IDENTITY
AUTO
對於MySQL,不是每種都支持(TODO)。
@PrimaryKeyJoinColumns、@PrimaryKeyJoinColumn 註解。
@Column(columnDefinition = "VARCHAR(100) NOT NULL")
private String firstName;
@Column(columnDefinition = "VARCHAR(100) NOT NULL")
private String lastName;
@Column(columnDefinition = "INT DEFAULT 0")
private Integer age;
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| age | int(11) | YES | | 0 | |
| first_name | varchar(100) | NO | | NULL | |
| last_name | varchar(100) | NO | | NULL | |
除了上面使用的 columnDefinition屬性 外, @Column 還有其它屬性 來做配置。
@Column的name屬性用來自定義 數據表中字段名稱。
問題:
1)columnDefinition 和 其它屬性的配置 一致 時,如何建立字段?
2)columnDefinition 和 其它屬性的配置 衝突 時,如何建立字段?
// User.java
private Integer property;
private Float height;
private Float weight;
private String slogan;
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| height | float | NO | | NULL | |
| weight | float | NO | | NULL | |
| slogan | varchar(255) | YES | | NULL | |
| property | int(11) | YES | | NULL | |
默認值Default 都是 NULL,String類型 默認爲 varchar(255)。
// 枚舉類 UserSex.java
@Getter
public enum UserSex {
MALE(0, "MALE"),
FEMALE(1, "FEMALE");
private int code;
private String info;
private UserSex(int code, String info) {
this.code = code;
this.info = info;
}
}
// User.java
// 不使用 @Column 註解
private UserSex sex;
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| sex | int(11) | YES | | NULL | |
數據表中類型爲 int(11)。
實際存儲的數據爲:0、1
mysql> select distinct sex from user;
+------+
| sex |
+------+
| 0 |
| 1 |
+------+
2 rows in set (0.00 sec)
// User.java
@Column(insertable = false, columnDefinition = "DATETIME DEFAULT NOW()")
private Date createTime;
@Column(insertable = false, updatable = false, columnDefinition = "DATETIME DEFAULT NOW() ON UPDATE NOW()")
private Date updateTime;
像上面一樣配置以後,就無需再 新增、更新 記錄時設置 這兩個字段的值了。
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| create_time | datetime | YES | | CURRENT_TIMESTAMP | |
| update_time | datetime | YES | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
指明字段不存庫,也就不會在數據表中建立字段。
// User.java
@Transient
private String abcNotInDb;
檢查數據表,沒有發現對應字段,符合預期。
比如,存取用戶地址,地址中包含 省市區等,怎麼處理呢?
如下:POJO對象中使用 @Embeddable,實體類中使用 @Embedded + @AttributeOverrides + @AttributeOverride。
// Address.java 4個屬性
@Data
@Embeddable
public class Address {
/**
* 郵政編碼
*/
@Column(updatable = false)
private String zipCode;
// 省市區3級
// 省
private String province;
// 市
private String city;
// 區
private String district;
}
// User.java
@Embedded
@AttributeOverrides({
@AttributeOverride(name="zipCode", column = @Column(name = "address_zip_code")),
@AttributeOverride(name="province", column = @Column(name = "address_province")),
@AttributeOverride(name="city", column = @Column(name = "address_city")),
@AttributeOverride(name="district", column = @Column(name = "address_district"))
})
private Address address;
數據表中效果:
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| address_zip_code | varchar(255) | YES | | NULL | |
| address_city | varchar(255) | YES | | NULL | |
| address_district | varchar(255) | YES | | NULL | |
| address_province | varchar(255) | YES | | NULL | |
試錯:實體類中 不使用各個註解,只 使用Address對象時,也會生成數據表字段,但沒有address前綴了。
增加一個 address2 屬性:
// User.java
private Address address2;
數據表中新增了4個字段:來自博客園
MySQL 5.7.8 開始提供 JSON類型。
注意,試驗前需要刪除 4.6節 生成的 city、district、province、zip_code 四個字段。
// User.java
@Column(columnDefinition = "JSON")
private Address jsonAddress;
啓動項目:沒有發現建立 json_address 字段。但是,生成了 city、district、province、zip_code 等4個字段。
未成功!
自測給user表添加 JSON 類型字段:成功。來自博客園
mysql> alter table user add json1 JSON;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc user;
...
| json1 | json | YES | | NULL | |
+------------------+--------------+------+-----+-------------------+-----------------------------+
22 rows in set (0.00 sec)
這樣看來,是JPA不支持MySQL的JSON類型了。
和 下面的配置有關係嗎?TODO
// application.properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
試驗了參考文檔3中的方法,實現了添加 JSON類型對象。
pom.xml中添加依賴包:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.4.3</version>
</dependency>
最新版本依賴包:
複製 上面的 Address 建立 Address2類,但是,去掉其 @Embeddable 註解。
@Data
//@Embeddable // JSON類型時,需要刪除
//public class Address2 implements Serializable { // 不需要實現 Serializable接口
public class Address2 {
/**
*
*/
// private static final long serialVersionUID = 211030L;
/**
* 郵政編碼
*/
@Column(updatable = false)
private String zipCode2;
...
}
實體類添加:來自博客園
// User.java
// Address屬性,無效,,會建立 Address下的 4個字段
@Type(type = "json")
@Column(columnDefinition = "json")
private Address jsonAddress;
// Address2 屬性,有效,,會建立JSON類型字段 json_address2
@Type(type = "json")
@Column(columnDefinition = "json")
private Address2 jsonAddress2;
上面的部分註解不是來自javax.persistence包:
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
啓動項目,修改表的SQL日誌語句:來自博客園
2021-10-30 10:58:15.409 INFO 19068 --- [ main] org.hibernate.dialect.Dialect :
HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Hibernate: alter table user add column city varchar(255)
Hibernate: alter table user add column district varchar(255)
Hibernate: alter table user add column province varchar(255)
Hibernate: alter table user add column zip_code varchar(255)
Hibernate: alter table user add column json_address2 json
數據表中效果:來自博客園
mysql> desc user;
+------------------+--------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+-------------------+-----------------------------+
| city | varchar(255) | YES | | NULL | |
| district | varchar(255) | YES | | NULL | |
| province | varchar(255) | YES | | NULL | |
| zip_code | varchar(255) | YES | | NULL | |
| json_address2 | json | YES | | NULL | |
》》》全文完《《《來自博客園
參考文檔
好文。
2、SpringBoot+MYSQL 配置支持json數據格式
發佈本文時,還未細看,裏面用了 mybatis。
3、MySQL 5.7 json jpa_spring data jpa + mysql使用json 類型
好文
4、