Spring Data JPA 生成数据表注解详解

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

student表结构
默认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;

}

student表结构
因此,不要的属性不要写在实体中,不然会被生成在数据表中

@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
最常用的还是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>

Snowflake

创建对应的类:

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

然后我们添加两条数据

生成的数据

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
视频详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 1、课程简介 Spring框架是一系列应用框架的核心,也可以说是整合其他应用框架的基座。同时还是SpringBoot的基础。在当下的市场开发环境中,Spring占据的地位是非常高的,基本已经成为了开发者绕不过去的框架了。它里面包含了SpringSpringMVC,SpringData(事务),SrpingTest等等。 其中: Spring本身里面包含了两大核心IOC和AOP。IOC负责降低我们代码间的依赖关系,使我们的项目灵活度更高,可复用性更强。AOP是让方法间的各个部分更加独立,达到统一调用执行,使后期维护更加的方便。 SpringMVC本身是对Servlet和JSP的API进行了封装,同时在此基础上进一步加强。它推出的一套注解,可以降低开发人员的学习成本,从而更轻松的做表现层开发。同时,在3.x版本之后,它开始之初Rest风格的请求URL,为开发者提供了开发基于Restful访问规则的项目提供了帮助。 SpringData是一组技术合集。里面包含了JDBC,Data JPAData Redis,Data Mongodb,Data Rabbit,Data ElasticSearch等等。合集中的每一项都是针对不同数据存储做的简化封装,使我们在操作不同数据库时,以最简洁的代码完成需求功能。 SpringTest它是针对Junit单元测试的整合。让我们在开发中以及开发后期进行测试时,直接使用Junit结合spring一起测试。 本套课程中,我们将全面剖析SpringSpringMVC两个部分。从应用场景分析,到基本用法的入门案例,再到高级特性的分析及使用,最后是执行原理的源码分析。让学生通过学习本套课程不仅可以知其然,还可以知其所以然。最终通过一个综合案例,实现灵活运用Spring框架中的各个部分。 2、适应人群 学习spring,要有一定的Java基础,同时应用过spring基于xml的配置。(或者学习过官网的Spring课程) 学习springmvc,要有一定java web开发基础。同时对spring框架要有一定了解。 3、课程亮点 系统的学习Spring框架中各个部分,掌握Spring中一些高级特性的使用。 l Spring IoC n 设计模式-工厂模式 n 基础应用-入门案例 n 基础应用-常用注解使用场景介绍及入门 n 高级特性-自定义BeanNameGenerator n 高级特性-自定义TypeFilter n 高级特性-ImportSelector和ImportBeanDefinitionRegistrar的分析 n 高级特性-自定义ImportSelector n 高级特性-FilterType中的AspectJTypeFilter的使用 n 高级特性-自定义ImportBeanDefinitionRegistrar n 高级特性-自定义PropertySourceFactory实现解析yaml配置文件 n 源码分析-BeanFactory类视图和常用工厂说明 n 源码分析-AnnotationConfigApplicationContext的register方法 n 源码分析-AnnotationConfigApplicationContext的scan方法 n 源码分析-AbstractApplicationContext的refresh方法 n 源码分析-AbstractBeanFactory的doGetBean方法 l Spring Aop n 设计模式-代理模式 n 编程思想-AOP思想 n 基础应用-入门案例 n 基础应用-常用注解 n 高级应用-DeclareParents注解 n 高级应用-EnableLoadTimeWeaving n 源码分析-@EnableAspectJAutoproxy注解加载过程分析 n 源码分析-AnnotationAwareAspectJAutoProxyCreator n 技术详解-切入点表达式详解 l Spring JDBC n 基础应用-JdbcTemplate的使用 n 源码分析-自定义JdbcTemplate n 设计模式-RowMapper的策略模式 n 高级应用-NamedParameterJdbcTemplate的使用 n 源码分析-TransactionTemplate n 源码分析-DataSourceUtils n 源码分析-TransactionSynchronizationManager

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的天才女友

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值