Spring DATA JPA:建立實體類

JAVA 8

Spring Boot 2.5.3

MySQL 5.7.21

---

 

注,本文代碼使用了 org.projectlombok:lombok (版本 由 Spring Boot 指定)。

 

目錄

1、建立實體類

2、主鍵id

3、複合主鍵

4、普通字段

4.1、使用 @Column註解

4.2、不使用 @Column註解

4.3、枚舉類型

4.4、創建時間、最後更新時間

4.5、@Transient

4.6、對象類型屬性

4.7、對象類型屬性-JSON類型(MySQL)

 

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 註解。

 

1、建立實體類

使用 @Entity 註解(javax.persistence.Entity,後面如無 特別說明,註解都來自 javax.persistence包)。

@Entity
@Data
public class User {

 

默認建立表名爲 user(全小寫),可以使用 name屬性指定表名。

@Entity(name="user2")
@Data
public class User {

 

上面兩種情況下建立的 兩張表 如下:

 

2、主鍵id

使用 @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)。

 

3、複合主鍵

@PrimaryKeyJoinColumns、@PrimaryKeyJoinColumn 註解。

 

4、普通字段

4.1、使用 @Column註解

@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 和 其它屬性的配置 衝突 時,如何建立字段?

 

4.2、不使用 @Column註解

// 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)。

 

4.3、枚舉類型

// 枚舉類 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)

 

4.4、創建時間、最後更新時間

// 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 |

 

4.5、@Transient

指明字段不存庫,也就不會在數據表中建立字段。

// User.java
@Transient
private String abcNotInDb;

 

檢查數據表,沒有發現對應字段,符合預期。

 

4.6、對象類型屬性

比如,存取用戶地址,地址中包含 省市區等,怎麼處理呢?

如下: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個字段:來自博客園

 

4.7、對象類型屬性-JSON類型(MySQL)

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              |                             |

 

》》》全文完《《《來自博客園

 

參考文檔

1、JPA對象型屬性操作

好文。

2、SpringBoot+MYSQL 配置支持json數據格式

發佈本文時,還未細看,裏面用了 mybatis。

3、MySQL 5.7 json jpa_spring data jpa + mysql使用json 類型

好文

4、

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章