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

  • 相关阅读:
    项目管理软件选择:redmine or JIRA
    为已编译的DLL附带强命名
    NET简单的一个画图程序
    公共的Json操作类
    ASP.NET 程序优化
    提高ASP.NET页面载入速度的方法
    DataTable快速定制之Expression属性表达式
    TCP和UDP Client 代码
    Jquery实现异步上传图片
    C语言Socket编程(计算机网络作业)
  • 原文地址:https://www.cnblogs.com/luo630/p/15484570.html
Copyright © 2020-2023  润新知