• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Spring Data JPA 生成数据表注解

武飞扬头像
我的天才女友
帮助1

Spring Data JPA 之后数据表可以自己生成,如果业务完善的话,完全不需要手动去修改数据表结构。

接下来以学生表为例子

package com.zuiuxi.plan.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicUpdate;

import lombok.Data;

/**
 *@author lv-gui
 *@date 2021-09-26 11:12
 *@description 
 **/
@Data
@Entity
@DynamicUpdate
@Table(name = "student")
public class Student {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "age")
	private Integer age;
	
	@Column(name = "birth")
	private Date birth;

}
学新通

启动控制台输入student表创建的语句

Hibernate: create table student (id bigint not null auto_increment, age integer, birth datetime(6), name varchar(255), primary key (id)) engine=InnoDB

学新通
默认id为20位,age是Integer 11位,birth 默认到毫秒, name设置为varchar(255)

为了验证生成的表结构,application.properties中设置spring.jpa.hibernate.ddl-auto为true,这样每次数据表会自动删除重新创建。

#datasource
spirng.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=daasan7ujm^YHN
#jpa
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true

注解详解

@Entity

注解表名这是一个实体类,必须

@Table

实体映射到数据库中的表名,没有的话,按照默认的命名。必须,我们去掉这个属性再试一下

Hibernate: drop table if exists student
Hibernate: create table student (id bigint not null auto_increment, age integer, birth datetime(6), name varchar(255), primary key (id)) engine=InnoDB

控制台输出删除表student和创建student表。
我们修改类名为StudentTest再试一下

Hibernate: drop table if exists student_test
Hibernate: create table student_test (id bigint not null auto_increment, age integer, birth datetime(6), name varchar(255), primary key (id)) engine=InnoDB

默认创建了student_test,命名按照驼峰命名小写,之间用下划线分割。虽然和我们预想的是一致的,但是为了防止发生不必要的错误,这里也写上具体的名字。

如果我们写了两个一样的表名嗯,启动之后发现只创建了一张表,也不保错。

@Data

lombok中的注解,用于生成字段的setter、getter、toString()等方法,这里主要是用于生成数据表字段的setter和getter方法

@DynamicUpdate

如果数据在更新的时候,会默认去除不更新字段
学新通
学新通

Hibernate: update user set birth=? where id=?

这里只修改了birth字段,然后将数据还原,去除@DynamicUpdate注解,再去更新一下,输出结果如下,此时会把所有的字段都更新一遍

Hibernate: update user set age=?, birth=?, name=? where id=?

对于age和name字段并未更新,但如果不加@DynamicUpdate的话,它还是回去执行一遍,造成资源的浪费,这里建议加上这个属性。

@Id

表明这个属性是这个表的主键,一个表里面只有一个主键,但是可以有多个字段。
多个字段的主键是不能直接给两个字段都添加@Id的,这样会报错。

复合主键的实现

package com.zuiuxi.plan.entity;

import java.io.Serializable;

import lombok.Data;

/**
 *@author lv-gui
 *@date 2021-09-26 13:36
 *@description 
 **/
@Data
public class StudentPrimaryKey implements Serializable{
	
	private Long id;
	
	private String name;

}
学新通
package com.zuiuxi.plan.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicUpdate;

import lombok.Data;

/**
 *@author lv-gui
 *@date 2021-09-26 11:12
 *@description 
 **/
@Data
@Entity
@DynamicUpdate
@Table(name = "student")
@IdClass(StudentPrimaryKey.class)
public class Student {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@Id
	@Column(name = "name")
	private String name;
	
	@Column(name = "age")
	private Integer age;
	
	@Column(name = "birth")
	private Date birth;

}
学新通

create table student (id bigint not null auto_increment, name varchar(255) not null, age integer, birth datetime(6), primary key (id, name)) engine=InnoDB

学新通
使用@IdClass(StudentPrimaryKey.class) 来指定复合主键,StudentPrimaryKey类中必须实现Serializable不然启动会报错

Composite-id class must implement Serializable: com.zuiuxi.plan.entity.StudentPrimaryKey

StudentPrimaryKey只需主键字段即可,设置和对应表字段一致。

@Column

只有加上这个字段就会被生成到对应的表中,如果不写就会按照默认的命名的方式命名,和表名默认的方式一样,这里推荐所有的字段都加上

create table student (id bigint not null auto_increment, age integer, birth datetime(6), name varchar(255), remakes varchar(255), primary key (id)) engine=InnoDB

package com.zuiuxi.plan.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicUpdate;

import lombok.Data;

/**
 *@author lv-gui
 *@date 2021-09-26 11:12
 *@description 
 **/
@Data
@Entity
@DynamicUpdate
@Table(name = "student")
public class Student {

	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "age")
	private Integer age;
	
	@Column(name = "birth")
	private Date birth;
	
	private String remakes;

}
学新通

学新通
因此,不要的属性不要写在实体中,不然会被生成在数据表中

@GeneratedValue

GeneratedValue一共有两个属性:strategy 和 generator

strategy

主键生成策略,有如下四个值

  1. GenerationType.TABLE
  2. GenerationType.SEQUENCE
  3. GenerationType.IDENTITY
  4. GenerationType.AUTO

GenerationType.IDENTITY 主键自增长,GenerationType.AUTO 默认的设置,由程序控制。
GenerationType.TABLE创建自己的表保存数据的主键增长,GenerationType.SEQUENCE会生成一个表保存自动增长的键。
学新通
最常用的还是GenerationType.IDENTITY

generator

主键生成器

@GenericGenerator 主键生成策略

static {
GENERATORS.put(“uuid”, UUIDHexGenerator.class);
GENERATORS.put(“hilo”, TableHiLoGenerator.class);
GENERATORS.put(“assigned”, Assigned.class);
GENERATORS.put(“identity”, IdentityGenerator.class);
GENERATORS.put(“select”, SelectGenerator.class);
GENERATORS.put(“sequence”, SequenceGenerator.class);
GENERATORS.put(“seqhilo”, SequenceHiLoGenerator.class);
GENERATORS.put(“increment”, IncrementGenerator.class);
GENERATORS.put(“foreign”, ForeignGenerator.class);
GENERATORS.put(“guid”, GUIDGenerator.class);
GENERATORS.put(“uuid.hex”, UUIDHexGenerator.class); //uuid.hex is deprecated
GENERATORS.put(“sequence-identity”, SequenceIdentityGenerator.class);
}

比如:uuid策略

@GeneratedValue(generator = "IdUtilGenerator")
    @GenericGenerator(name = "IdUtilGenerator", strategy = "com.zuiuxi.plan.util.IdUtilGenerator")

还可以使用自定的策略,继承对应的接口即可
例如:

	@GeneratedValue(generator = "IdUtilGenerator")
    @GenericGenerator(name = "IdUtilGenerator", strategy = "com.ruizhi.plan.config.IdUtilGenerator")

使用hutoolId生成器。引入hutool工具

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.13</version>
        </dependency>

学新通

创建对应的类:

package com.zuiuxi.plan.util;

import java.io.Serializable;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;

/**
 *@author lv-gui
 *@date 2021-09-26 15:55
 *@description id生成器
 **/
public class IdUtilGenerator implements IdentifierGenerator  {
		
    @Override
    public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
    		return  cn.hutool.core.util.IdUtil.getSnowflake(1, 1).nextId();
    }
}



学新通

调试一下

package com.zuiuxi.plan.entity;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;

import lombok.Data;

/**
 *@author lv.gui
 *@date 创建时间:2021年9月21日 下午11:01:54
 *@description 
 */
@Data
@Entity
@Table(name = "user")
public class User{

	@Id
	@Column(name = "id")
	@JSONField(serializeUsing = ToStringSerializer.class)
    @GeneratedValue(generator = "IdUtilGenerator")
    @GenericGenerator(name = "IdUtilGenerator", strategy = "com.zuiuxi.plan.util.IdUtilGenerator")
	private Long id;
	
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "age")
	private Integer age;
	
	@Column(name = "birth")
	private Date birth;
}

学新通

然后我们添加两条数据

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgkihai
系列文章
更多 icon
同类精品
更多 icon
继续加载