使用默认配置的SpringBoot的Jpa,自动建表的时候会将驼峰命名的Bean对象的属性

在数据库中格式化为xxx_xxx的形式。

修改配置文件中的spring.jpa.hibernate.naming.physical-strategy属性可以开启或关闭该功能

  • org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl不进行格式化

  • org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy进行格式化(默认使用)

JPA 语义大全

关键字 示例 生成的SQL
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
Between findByStartDateBetween … where x.startDate between ?1 and ?2
LessThan findByAgeLessThan … where x.age < ?1
LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
GreaterThan findByAgeGreaterThan … where x.age > ?1
GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
After findByStartDateAfter … where x.startDate > ?1
Before findByStartDateBefore … where x.startDate < ?1
IsNull findByAgeIsNull … where x.age is null
IsNotNull,NotNull findByAge(Is)NotNull … where x.age not null
Like findByFirstnameLike … where x.firstname like ?1
NotLike findByFirstnameNotLike … where x.firstname not like ?1
StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collection age) … where x.age not in ?1
TRUE findByActiveTrue() … where x.active = true
FALSE findByActiveFalse() … where x.active = false
IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

嵌套实体:

findBy主实体中子实体的属性名称_子实体的属性名称

例如:

List findByAddress_ZipCode(ZipCode zipCode)

表示查询所有 Address(地址)的 zipCode(邮编)为指定值的所有Person(人员,主实体)

Bean类的注解

@Entity

声明一个类为实体Bean。

@Table

说明此实体类映射的表名,目录,schema的名字。

@Id

声明此表的主键。

@GeneratedValue

定义主键的增长策略。我这里一般交给底层数据库处理,所以调用了名叫generator的增长方式,由下边的@GenericGenerator实现

@GenericGenerator

hibernate内部的主键增长方式

@UniqueConstraint

将对应的字段设置唯一性标识

(注:UniqueConstraint只在hibernate.hbm2ddl.auto设置为create-drop才会起作用)

@Version

注解用于支持乐观锁版本控制。一般可以用 数字 或者 timestamp 类型来支持 version。

@Column

用于映射对应的字段,其中参数详解如下:

参数 说明
name = “columnName”; name 可选,列名(默认值是属性名)
boolean unique() default false; unique 可选,是否在该列上设置唯一约束(默认值false)
boolean nullable() default true; nullable 可选,是否设置该列的值可以为空(默认值true)
boolean insertable() default true; insertable 可选,该列是否作为生成的insert语句中的一个列(默认值true)
boolean updatable() default true; updatable 可选,该列是否作为生成的update语句中的一个列(默认值true)
String columnDefinition() default “”; columnDefinition 可选,为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)
String table() default “”; table 可选,定义对应的表(默认为主表)
int length() default 255; length 可选,列长度(默认值255)
int precision() default 0; precision 可选,列十进制精度(decimal precision)(默认值0)
int scale() default 0; scale 可选,如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)

@Transient
被注解成 @Transient 的 getter 方法或属性,将不会被持久化

@Basic
所有没有定义注解的属性,等价于在其上面添加了 @Basic注解可以声明属性的获取策略 ( fetch strategy )

fetch:抓取策略,延时加载与立即加载,optional:指定在生成数据库结构时字段是否允许为 null.

@Temporal
在核心的 Java API 中并没有定义时间精度 ( temporal precision )。因此处理时间类型数据时,你还需要定义将其存储在数据库中所预期的精度。
在数据库中,表示时间类型的数据有 DATE,TIME,和 TIMESTAMP 三种精度 ( 即单纯的日期,时间,或者两者兼备 )。 可使用 @Temporal 注解来调整精度。

第一种:@Temporal(TemporalType.DATE) 实体类会封装成日期“yyyy-MM-dd”的 Date类型。

第二种:@Temporal(TemporalType.TIME) 实体类会封装成时间“hh-MM-ss”的 Date类型。

第三种:@Temporal(TemporalType.TIMESTAMP) 实体类会封装成完整的时间“yyyy-MM-dd hh:MM:ss”的 Date类型。

@Index
给某一字段加索引

如果视图是只读的,您应该使用 @Immutable 注解告诉 Hibernate。 然后它将忽略对该实体的所有更改。只读声明

JPA 规范的 @GeneratedValue 注解允许您定义用于创建唯一主键值的策略。您可以选择 SEQUENCE、IDENTITY、TABLE 和 AUTO。

一般来说,我建议使用 SEQUENCE 策略,因为它允许 Hibernate 使用 JDBC 批处理和其他需要延迟执行 SQL INSERT 语句的优化策略。

然而,您不能将此策略与 MySQL 数据库一起使用。因为它需要一个数据库序列,恰好 MySQL 不支持此功能。

因此,您需要在 IDENTITY 和 TABLE 之间进行选择。考虑到 TABLE 策略的性能和可扩展性问题,这很容易作出决定。

如果您正在使用 MySQL 数据库,则应始终使用 GenerationType.IDENTITY。它使用自动增量(autoincremented )的数据库列,这是最有效的可用方法。

您可以通过使用 @GeneratedValue(strategy = GenerationType.IDENTITY) 注解主键属性来执行此操作。

Hibernate 5 中 GenerationType.AUTO

在旧版本中,Hibernate 为 MySQL 数据库选择 GenerationType.IDENTITY。 这是一个不错的选择。如之前所述,这是最有效的方法。

不幸的是此行为在 Hibernate 5 中发生了改变。现在是选择 GenerationType.TABLE,它使用数据库表来生成主键。 这种方法需要大量数据库查询和悲观锁来生成唯一值。

您可以通过定义一个 @GenericGenerator 来避免这一点,以下代码告诉 Hibernate 使用本地策略生成主键值。

@GenericGenerator(name = “native”, strategy = “native”)

@Convert 属性转换器

需要一个现实 AttributeConverter 接口类的转换器,来在实体属性存取数据库时进行转换操作

AttributeConverter 的两个方法:

convertToDatabaseColumn(X attribute)用于把输入的类型转成数据库存储的类型

convertToEntityAttribute (Y dbData) 用于把数据库搜出来的类型转成实体中想要的类型

为实体设置默认值的方法,直接在属性上给出初始值。@Column 的 columnDefinition 属性设置初始值仅在

表重新建立时生效

使用UUID做为主键的问题

  1. 将数据库中的主键,设置为varchar(32)。

  2. 在entity中类头部写入@GenericGenerator(name = “jpa-uuid”, strategy = “uuid”)

  3. 在entity中id主键顶部写入@GeneratedValue(generator = “jpa-uuid”),注意generator中的值必须与注释@GenericGenerator中name属性完全一致。

  4. 设置entity中主键ID为string类型。设置长度为32

  5. GenericGenerator是Hibernate中的注释,有两个参数。name是system-uuid“” ,策略strategy是uuid 。

  6. @GenericGenerator支持13种策略,分别是:

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

上面的12种策略,再加上native,一共是13种。

  1. @GeneratedValue注解属于一个JPA接口(从JAVA EE 5开始,存在于javax.persistence包下),其接口下包含了两个抽象的参数,GenerationType类型的strategy和String类型的generator,并且两个参数都有相应的默认值。

  2. GenerationType同样也位于javax.persistence包下,并且还继承了Enum枚举类,然后其中有4个值供我们使用,分别是:
    TABLE:使用一个特定的数据库表格来保存主键。
    SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。 这个值要与generator一起使用,generator 指定生成主键使用的生成器(可能是orcale中自己编写的序列)。
    IDENTITY:主键由数据库自动生成(主要是支持自动增长的数据库,如mysql)
    AUTO:主键由程序控制,也是GenerationType的默认值。

  3. 两个数据库对GenerationType的支持

mysql
GenerationType.TABLE
GenerationType.AUTO
GenerationType.IDENTITY
不支持GenerationType.SEQUENCE

oracle
strategy=GenerationType.AUTO
GenerationType.SEQUENCE
GenerationType.TABLE
不支持GenerationType.IDENTITY