Spring Data JPA:建立实体类
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、