建设个人网站ip,做海报有什么参考的网站,wordpress不识别主题,网站开发销售话术JPA 注解
Entity 常用注解
参考#xff1a;JPA Spring Data JPA学习与使用小记
指定对象与数据库字段映射时注解的位置#xff1a;如Id、Column等注解指定Entity的字段与数据库字段对应关系时#xff0c;注解的位置可以在Field#xff08;属性#xff09;或Prope…JPA 注解
Entity 常用注解
参考JPA Spring Data JPA学习与使用小记
指定对象与数据库字段映射时注解的位置如Id、Column等注解指定Entity的字段与数据库字段对应关系时注解的位置可以在Field属性或Property属性的get方法上两者统一用其中一种不能两者均有。推荐用前者。
Entity、Table
Entity必需
标注在实体类上。
映射实体类。指出该 Java 类为实体类将映射到指定的关系数据库表。
应用了此注解后将会自动将类名映射作为数据库表名、将类内的字段名映射为数据库表的列名。映射策略默认是按驼峰命名法拆分将类名或字段名拆分成多部分然后以下划线连接如StudentEntity - student_entity、studentName - student_name。若不按默认映射则可通过Table、Column 指定见下面。 Table可选
标注在实体类上。
映射数据库表名。当实体类与其映射的数据库表名不同名时需要使用 Table 标注说明该标注与 Entity 标注并列使用
schema属性指定数据库名name属性指定表名不指定时默认按驼峰命名法拆分将类名并以下划线连接 DynamicInsert、DynamicUpdate
DynamicInsert可选
标注在实体类上。
设置为 true表示 insert 对象的时候生成动态的 insert 语句如果这个字段的值是 null 就不会加入到 insert 语句中默认 false DynamicUpdate可选
标注在实体类上。 设置为 true表示执行 update 对象时在生成动态的 update 语句前会先查询该表在数据库中的字段值并对比更新使用的对象中的字段值与数据库中的字段值是否相同若相同即该值没有修改则该字段就不会被加入到 update 语句中。 默认 false表示无论更新使用实体类中的字段值与数据库中的字段值是否一致都加入到 update 语句中即都使用对象中所有字段的值覆盖数据库中的字段值。 比如只想更新某个属性但是却把整个属性都更改了这并不是希望的结果希望的结果是更改了哪写字段只要更新修改的字段就够了。 所以 jpa 更新数据库字段值无论是否有 DynamicUpdate 注解均需要手动先 select 对象然后通过 set 更新对象的属性值然后再 save 对象实现更新操作
注意 DynamicUpdate 的动态更新的含义是比较更新要使用的实体类中的所有字段值与从数据库中查询出来的所有字段值判断其是否有修改不同则加入到update语句中更新字段值。 例如数据库中 id1 的记录所有字段都是非空的但是实体类中只有 name 有值也就是所有字段都变了只是其他字段被更新为了新的空值。 Id、GeneratedValue
Id必需
标注在实体类成员变量或 getter 方法之上。
映射生成主键。用于声明一个实体类的属性映射为数据库的一个主键列。
若同时指定了下面的 GeneratedValue 则存储时会自动生成主键值否则在存入前用户需要手动为实体赋一个主键值。
主键值类型可以是 Primitive types boolean byte short char int long float double Equivalent wrapper classes from package java.lang ByteShort Character Integer Long Float Double java.math.BigInteger java.math.BigDecimal java.lang.String java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp Any enum type Reference to an entity object composite of several keys above
指定联合主键有 IdClass、EmbeddedId 两种方法。 GeneratedValue
GeneratedValue 用于标注主键的生成策略通过 strategy 属性指定。
默认情况下JPA 自动选择一个最适合底层数据库的主键生成策略SqlServer 对应 identityMySQL 对应 auto increment AUTO JPA自动选择合适的策略是默认选项 IDENTITY采用数据库 ID自增长的方式来自增主键字段Oracle 不支持这种方式 TABLE通过表产生主键框架借由表模拟序列产生主键使用该策略可以使应用更易于数据库移植。 SEQUENCE通过序列产生主键通过 SequenceGenerator 注解指定序列名MySql 不支持这种方式 Column、Basic、Transient
Column可选
标注在实体类成员变量或 getter 方法之上。
映射表格列。当实体的属性与其映射的数据库表的列不同名时需要使用 Column 标注说明。
类的字段名在数据库中对应的字段名可以通过此注解的name属性指定不指定则默认为将属性名按驼峰命名法拆分并以下划线连接如 createTime 对应 create_time。
**注意**即使name的值中包含大写字母对应到db后也会转成小写如 Column(namecreate_Time) 在数据库中字段名仍为create_time。可通过SpringBoot配置参数【spring.jpa.hibernate.naming.physical-strategy】配置对应策略如指定name值是什么数据库中就对应什么名字的列名。默认值为:【org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy】
Column注解一共有10个属性这10个属性均为可选属性各属性含义分别如下 name定义了被标注字段在数据库表中所对应字段的名称。 unique该字段是否为唯一标识默认为false。也可以使用Table标记中的UniqueConstraint。 nullable该字段是否可以为null值默认为true。 length字段的长度当字段的类型为varchar时该属性才有效默认为255个字符。 insertable在使用“INSERT”脚本插入数据时是否插入该字段的值。默认为true。 updatable在使用“UPDATE”脚本插入数据时是否更新该字段的值。默认为true。 insertable false 和updatable false 一般多用于只读的属性例如主键和外键等。这些字段的值通常是自动生成的。 columnDefinition建表时创建该字段的DDL语句一般用于通过Entity生成表定义时使用。 如果DB中表已经建好该属性没有必要使用 precision和scale表示精度当字段类型为double时precision表示数值的总长度scale表示小数点所占的位数。 table定义了包含当前字段的表名。 Basic可选
表示一个简单的属性到数据表的字段的映射对于没有任何标注的属性或getter方法默认标注为 Basic fetch 表示属性的读取策略有 EAGER 和 LAZY 两种分别为立即加载和延迟加载 optional 表示该属性是否允许为 null默认为 true Transient忽略属性
定义暂态属性。表示该属性并非一个到数据库表的字段的映射ORM 框架将忽略该属性。
如果一个属性并非数据库表的字段映射就必须将其标识为 Transient否则ORM 框架默认为其注解 Basic例如工具方法不需要映射。 Temporal时间日期精度
标注在实体类成员变量或getter方法之上。可选。
在 JavaAPI 中没有定义 Date 类型的精度而在数据库中表示 Date 类型的数据类型有 Date(年月日)Time(时分秒)TimeStamp(年月日时分秒) 三种精度进行属性映射的时候可以使用 Temporal 注解调整精度。
目前此注解只能用于修饰JavaAPI中的【java.util.Date】、【java.util.Calendar】类型的变量TemporalType 取 DATE、TIME、TIMESTAMP 时在MySQL中分别对应的 DATE、TIME、DATETIME 类型。
示例 Temporal(TemporalType.TIMESTAMP)CreationTimestamp //org.hibernate.annotations.CreationTimestamp用于在JPA执行insert操作时自动更新该字段值Column(name create_time, updatablefalse ) //为防止手动set可设false以免该字段被更新private Date createTime;Temporal(TemporalType.TIMESTAMP)UpdateTimestamp //org.hibernate.annotations.UpdateTimestamp用于在JPA执行update操作时自动更新该字段值private Date updateTime;时间日期自动更新
1、Hibernate 的注解
CreationTimestamp创建时间、UpdateTimestamp更新时间
用法在时间日期类型属性上加上注解即可
2、SpringDataJPA 的注解可参阅https://blog.csdn.net/tianyaleixiaowu/article/details/77931903
CreatedDate创建时间、LastModifiedDate更新时间、CreatedBy、LastModifiedBy
用法
在实体类加上注解 EntityListeners(AuditingEntityListener.class)在启动类上加上注解 EnableJpaAuditing在实体类中属性中加上面四种注解
示例
Data
MappedSuperclass
EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {IdGeneratedValue(strategy GenerationType.AUTO)protected Integer id;// 创建时间CreatedDateColumn(name create_time, updatablefalse ) //为防止手动set可设false以免该字段被更新private Long createTime;// 更新时间LastModifiedDateColumn(name update_time)private Long updateTime;
}其他注解
MappedSuperClass共有字段超类
标注在实体类上。
共有字段超类中声明了各 Entity 共有的字段即数据库中多表中共有的字段如 create_time、update_time、id 等。
标注为 MappedSuperclass 的类将不是一个完整的实体类将不会映射到数据库表但是其属性都将映射到其子类的数据库字段中。
标注为 MappedSuperclass 的类不能再标注 Entity 或 Table 注解也无需实现序列化接口。
允许多级继承
注解的类继承另一个实体类或标注 MappedSuperclass 类可以使用 AttributeOverride 或 AttributeOverrides 注解重定义其父类属性映射到数据库表中字段。 IdClass指定联合主键类
标注在实体类上。
指定联合主键类。如IdClass(StudentExperimentEntityPK.class)
主键类 StudentExperimentEntityPK 需要满足
实现 Serializable 接口有默认的 public 无参数的构造方法重写 equals 和 hashCode 方法。equal s方法用于判断两个对象是否相同EntityManger 通过 find 方法来查找 Entity 时是根据 equals 的返回值来判断的。hashCode 方法返回当前对象的哈希码它的类型和名称必须与使用 Id 进行标注的实体主键字段的类型和名称一致。
示例
/** * 实体类*/
Data
Entity
Table(name customer_course)
IdClass(CustomerCourseEntityPK.class) // 指定联合主键类
public class CustomerCourseEntity {IdColumn(name customer_id, length ColumnLengthConstrain.LEN_ID_MAX)private String customerId;IdColumn(name course_id, length ColumnLengthConstrain.LEN_ID_MAX)private String courseId;Column(name max_number)private Integer maxNumber;ManyToOneJoinColumn(name course_id, referencedColumnName id, nullable false, insertable false, updatable false)private CourseEntity courseByCourseId;
}/** * 联合主键类*/
Data
public class CustomerCourseEntityPK implements Serializable {private static final long serialVersionUID 1L;private String customerId;private String courseId;
}EmbeddedId联合主键
标注在实体类成员变量或 getter 方法上。
功能与 IdClass 一样用于指定联合主键。不同的是其标注在实体内的主键类变量上且主键类应该标注 Embeddable 注解。
此外在主键类内指定的字段在实体类内可以不再指定若再指定则需为 Column 加上 insertable false, updatable false 属性
示例
Data
Entity
Table(name customer_course)
IdClass(CustomerCourseEntityPK.class) // 指定联合主键类
public class CustomerCourseEntity {EmbeddedIdprivate CustomerCourseEntityPK id;Column(name max_number)private Integer maxNumber;
}/** * 联合主键类*/
Data
Embeddable
public class CustomerCourseEntityPK implements Serializable {private static final long serialVersionUID 1L;Column(name customer_id, length ColumnLengthConstrain.LEN_ID_MAX)private String customerId;Column(name course_id, length ColumnLengthConstrain.LEN_ID_MAX)private String courseId;
}Inheritance表结构复用
标注在实体类上。
用于表结构复用。指定被该注解修饰的类被子类继承后子类和父类的表结构的关系。
通过 strategy 属性指定关系有三种策略 SINGLE_TABLE适用于共同字段多独有字段少的关联关系定义。 子类和父类对应同一个表且所有字段在一个表中还会自动生成也可通过 DiscriminatorColumn 指定一个字段 varchar dtype 用来表示一条数据是属于哪个实体的。为默认值。 未使用 Inheritance 或使用了但没指定 strategy 属性时默认采用此策略。 JOINED子类和父类对应不同表父类属性对应的列除了主键不会且无法再出现在子表中。子表自动产生与父表主键对应的外键与父表关联。同样地也可通过 DiscriminatorColumn 为父类指定一个字段用于标识一条记录属于哪个子类。 TABLE_PER_CLASS子类和父类对应不同表且各类自己的所有字段包括继承的分别都出现在各自的表中表间没有任何外键关联。此策略最终效果与 MappedSuperClass 等同。 Inheritance 与 MappedSuperclass 的区别
MappedSuperclass 子类与父类没有外键关系、不会对应同一个表Inheritance 适用于表关联后者适用于定义公共字段两者是可以混合使用 Inheritance、MappedSuperClass 可用于定义 Inheritance 关系。这些方式的一个缺点是子类中无法覆盖从父类继承的字段的定义如父类中 name 是 not null但子类中允许为 null。
除了 Inheritance、MappedSuperClass 外还有一种 Inheritance 方法此法可解决上述不足先定义一个 Java POJO干净的 POJO没有任何对该类使用任何的 ORM 注解然后不同子类继承该父类并分别在不同子类中进行 ORM 定义即可。此法下不同子类拥有父类的公共字段且该字段在不同子类中对应的数据库列定义可不同。 Embedded、Embeddable
当一个实体类要在多个不同的实体类中进行使用而其不需要生成数据库表
Embeddable标注在类上表示此类是可以被其他类嵌套Embedded标注在属性上表示嵌套被Embeddable注解的同类型类 Enumerated映射枚举
使用此注解映射枚举字段以String类型存入数据库
注入数据库的类型有两种EnumType.ORDINALInterger、EnumType.STRINGString TableGenerator主键值生成器
TableGenerator定义一个主键值生成器在 GeneratedValue的属性strategy GenerationType.TABLE时generator属性中可以使用生成器的名字。生成器可以在类、方法或者属性上定义。
生成器是为多个实体类提供连续的ID值的表每一行为一个类提供ID值ID值通常是整数。
属性说明
name生成器的唯一名字可以被Id元数据使用。table生成器用来存储id值的Table定义。pkColumnName生成器表里用来保存主键名字的字段valueColumnName生成器表里用来保存主键值的字段pkColumnValue生成器表里用来保存主键名字的字段的值initialValueid值的初始值。allocationSizeid值的增量
示例
Entity
public class Employee {IdColumn(name id)TableGenerator(name hf_opert_id_gen, // 此处的名字要和下面generator属性值一致table mcs_hibernate_seq, // 主键保存到数据库的表名pkColumnName sequence_name, // 表里用来保存主键名字的字段valueColumnName sequence_next_hi_value, // 表里用来保存主键值的字段pkColumnValue user_id, // 表里名字字段对应的值allocationSize 1) // 自动增长设置为1GeneratedValue(strategy GenerationType.TABLE, generator hf_opert_id_gen)private Integer id;}JoinColumn、JoinColumns
JoinColumn指定外键
如果在实体类的某个属性上定义了联表关系OneToOne或OneTOMany等则使用JoinColumn注解来定义关系的属性。JoinColumn的大部分属性和Column类似。
属性说明
name主表的列名。若不指定默认为 关联表的名称 “_” 关联表主键的字段名例如 address_idreferencedColumnName关联表作为外键的列名。若不指定默认为关联表的主键作为外键。unique是否唯一 默认falsenullable是否允许为空默认trueinsertable是否允许插入默认trueupdatable是否允许更新默认truecolumnDefinition定义建表时创建此列的DDLsecondaryTable从表名。如果此列不建在主表上默认建在主表该属性定义该列所在从表的名字。foreignKey()外键。默认ForeignKey(ConstraintMode.PROVIDER_DEFAULT);
Data
Entity
public class Person {...// Person和Address是一对一关系。Address表中名为id_address的列作为外键指向Person表中名为address_id的列OneToOneJoinColumn(nameaddress_id, referencedColumnNameid_address, uniquetrue)private Address address;
}Data
Entity
public class Address {Idcolumn(name id_address)private Integer idAddress;
}JoinColumns
如果在实体类的某个属性上定义了联表关系OneToOne或OneTOMany等并且关系存在多个JoinColumn则使用JoinColumns注解定义多个JoinColumn的属性。
属性说明
value定义JoinColumn数组指定每个JoinColumn的属性
Data
Entity
public class Custom {// Custom和Order是一对一关系。Order表中一个名为CUST_ID的列作为外键指向Custom对应表中名为ID_CUST的列另一名为CUST_NAME的列作为外键指向Custom对应表中名为NAME_CUST的列OneToOneJoinColumns({JoinColumn(nameCUST_ID, referencedColumnNameID_CUST),JoinColumn(nameCUST_NAME, referencedColumnNameNAME_CUST)})private Order order;
}OneToOne、OneToMany
OneToOne
描述一个 一对一的关联
属性说明
fetch表示抓取策略默认为FetchType.LAZYcascade表示级联操作策略。CascadeType.ALL当前类增删改查改变之后关联类跟着增删改查。
Data
Entity
public class Person {...// Person和Address是一对一关系。Address表中名为id_address的列作为外键指向Person表中名为address_id的列OneToOneJoinColumn(nameaddress_id, referencedColumnNameid_address, uniquetrue)private Address address;
}OneToMany
描述一个 一对多的关联该属性应该为集体类型在数据库中并没有实际字段。
属性说明
fetch表示抓取策略默认为FetchType.LAZY因为关联的多个对象通常不必从数据库预先读取到内存cascade表示级联操作策略,对于OneToMany类型的关联非常重要通常该实体更新或删除时其关联的实体也应当被更新或删除
例如实体User和Order是OneToMany的关系则实体User被删除时其关联的实体Order也应该被全部删除 ManyToOne、ManyToMany
ManyToOne
表示一个多对一的映射该注解标注的属性通常是数据库表的外键
属性说明
optional是否允许该字段为null该属性应该根据数据库表的外键约束来确定默认为truefetch表示抓取策略默认为FetchType.EAGERcascade表示默认的级联操作策略可以指定为ALLPERSISTMERGEREFRESH和REMOVE中的若干组合默认为无级联操作targetEntity表示该属性关联的实体类型。该属性通常不必指定ORM框架根据属性类型自动判断 targetEntity ManyToMany
描述一个多对多的关联。多对多关联上是两个一对多关联但是在ManyToMany描述中中间表是由ORM框架自动处理
属性说明
targetEntity表示多对多关联的另一个实体类的全名例如package.Book.classmappedBy表示多对多关联的另一个实体类的对应集合属性名称
两个实体间相互关联的属性必须标记为ManyToMany并相互指定targetEntity属性 需要注意的是有且只有一个实体的ManyToMany注解需要指定mappedBy属性指向targetEntity的集合属性名称利用ORM工具自动生成的表除了User和Book表外还自动生成了一个User_Book表用于实现多对多关联 NamedStoredProcedureQuery
定义在一个实体上面声明存储过程。有多个存储过程可以用NamedStoredProcedureQueries。
name自定义存储过程在java中的唯一别名调用时使用procedureName数据库中的存储过程名parameters存储过程的参数 StoredProcedureParameter定义存储过程的参数属性 name参数名。和数据库里的参数名字一样mode参数模式。ParameterMode.IN、OUT、INOUT、REF_CURSORtype参数数据类型。String.class、Integer.classLong.class等 JsonFormat、DateTimeFormat
JsonFormat
后端到前端的时间格式的转换。注意该注解并非 JPA 注解。
// 出参时间格式化
JsonFormat(pattern yyyy-MM-dd HH:mm:ss, timezone GMT8)
private Date createTime;也可以在配置文件中配置进行时间戳统一转换
spring.jackson.date-formatyyyy-MM-dd HH:mm:ss
spring.jackson.time-zoneGMT8DateTimeFormat
前端到后端的时间格式的转换。注意该注解并非 JPA 注解。
// 入参出参时间格式化。请求报文只需要传入yyyy-MM-dd HH:mm:ss格式字符串进来则自动转换为Date类型数据
DateTimeFormat(pattern yyyy-MM-dd HH:mm)
private Date createTime;主键生成策略
通用策略
GeneratedValue 注解介绍
参考JPA注解之“GeneratedValue”详解 通过 annotation 来映射 hibernate 实体基于 annotation 的 hibernate 主键标识 Id由 GeneratedValue 设定其生成规则。 GeneratedValue 注解用于标注主键的生成策略通过 strategy 属性指定。 默认情况下JPA 自动选择一个最适合底层数据库的主键生成策略 SqlServer 对应 identityMySQL 对应 auto increment 。
源码定义
Target({METHOD,FIELD})
Retention(RUNTIME)
public interface GeneratedValue{ GenerationType strategy() default AUTO; String generator() default ;
} 其中GenerationType
public enum GenerationType{ TABLE, SEQUENCE, IDENTITY, AUTO
} JPA 提供的四种标准用法为 AUTOJPA 自动选择合适的策略是默认选项 IDENTITY采用数据库ID自增长的方式来自增主键字段。Oracle 不支持这种方式 TABLE通过表产生主键框架借由表模拟序列产生主键使用该策略可以使应用更易于数据库移植 SEQUENCE通过序列产生主键通过SequenceGenerator 注解指定序列名。MySql不支持这种方式 AUTO、IDENTITY、SEQUENCE 策略 AUTO 策略 用法 // 指定主键
Id
// 指定主键生成策略默认为 AUTO
GeneratedValue(strategy GenerationType.AUTO) IDENTITY 策略 用法 Id
GeneratedValue(strategy GenerationType.IDENTITY) SEQUENCE 策略 用法 // 使用示例
Id
GeneratedValue(strategy GenerationType.SEQUENCE, generatoraaa)
SequenceGenerator(nameaaa, sequenceNameseq_payment) SequenceGenerator 源码定义 Target({TYPE, METHOD, FIELD})
Retention(RUNTIME)
public interface SequenceGenerator { String name(); String sequenceName() default ; int initialValue() default 0; int allocationSize() default 50;
} 以上属性说明如下 name 表示该表主键生成策略的名称它被引用在GeneratedValue中设置的“generator”值中 sequenceName 表示生成策略用到的数据库序列名称 initialValue 表示主键初识值默认为0 allocationSize 表示每次主键值增加的大小。例如设置成1则表示每次创建新记录后自动加1默认为50
TABLE 策略 用法示例 Id
GeneratedValue(strategy GenerationType.TABLE, generatorpk_gen)
TableGenerator(name pk_gen, tabletb_generator, pkColumnNamegen_name, valueColumnNamegen_value, pkColumnValuePAYABLEMOENY_PK, allocationSize1
) 在主键生成后这条纪录的 value 值按 allocationSize 递增。 使用此策略需要数据库存在相应的表 -- 定义应用表 tb_generator
CREATE TABLE tb_generator ( id NUMBER NOT NULL, gen_name VARCHAR2(255) NOT NULL, gen_value NUMBER NOT NULL, PRIMARY KEY(id)
) -- 插入纪录供生成主键使用
INSERT INTO tb_generator(id, gen_name, gen_value) VALUES (1,PAYABLEMOENY_PK, 1); TableGenerator 的源码定义 Target({TYPE, METHOD, FIELD})
Retention(RUNTIME)
public interface TableGenerator { String name(); String table() default ; String catalog() default ; String schema() default ; String pkColumnName() default ; String valueColumnName() default ; String pkColumnValue() default ; int initialValue() default 0; int allocationSize() default 50; UniqueConstraint[] uniqueConstraints() default {};
} 以上属性说明如下 name 表示该表主键生成策略的名称它被引用在GeneratedValue中设置的“generator”值中 table 表示表生成策略所持久化的表名例如这里表使用的是数据库中的“tb_generator” catalog 属性和 schema属性具体指定表所在的目录名或是数据库模式名 pkColumnName 属性的值表示在持久化表中该主键生成策略所对应键值的名称。 例如在“tb_generator”中将“gen_name”作为数据库表中主键的键值对的名称 valueColumnName 属性的值表示在持久化表中该主键当前所生成的值它的值将会随着每次创建累加。 例如在“tb_generator”中将“gen_value”作为数据库表中主键的键值对的键值 pkColumnValue 属性的值表示在持久化表中该生成策略所对应的主键。例如在“tb_generator”表中将“gen_name”的值为“CUSTOMER_PK” initialValue 表示主键初始值默认为0 allocationSize 表示每次主键值增加的大小。例如设置成1则表示每次创建新记录后自动加1默认为50 UniqueConstraint 与Table标记中的用法类似 hibernate 策略
hibernate 提供多种主键生成策略有点是类似于 JPA基于 Annotation 的方式通过 GenericGenerator 注解实现。
GenericGenerator 注解介绍
源码定义
Target({PACKAGE, TYPE, METHOD, FIELD})
Retention(RUNTIME)
public interface GenericGenerator { String name(); String strategy(); Parameter[] parameters() default {};
} 以上属性说明如下
name 属性指定生成器名称strategy 属性指定具体生成器的类名parameters 得到strategy指定的具体生成器所用到的参数 hibernate 特有策略 native将主键的生成工作交由数据库完成hibernate 不管常用 对于 oracle 采用 Sequence 方式对于 MySQL 和 SQL Server 采用 identity自增主键生成机制 uuid采用 128 位的 uuid 算法生成主键uuid 被编码为一个 32 位 16 进制数字的字符串占用空间大字符串类型 hilo使用 hilo 生成策略要在数据库中建立一张额外的表默认表名为 hibernate_unique_key默认字段为 integer 类型名称是 next_hi比较少用 assigned在插入数据的时候主键由程序处理很常用这是 generator 元素没有指定时的默认生成策略。 等同于 JPA 中的 AUTO identity使用 SQL Server 和 MySQL 的自增字段 注意这个方法不能放到 Oracle 中Oracle 不支持自增字段要设定sequenceMySQL 和 SQL Server 中很常用 等同于 JPA 中的 INDENTITY increment插入数据的时候 hibernate 会给主键添加一个自增的主键但是一个 hibernate 实例就维护一个计数器所以在多个实例运行的时候不能使用这个方法 select使用触发器生成主键主要用于早期的数据库主键生成机制少用 sequence调用底层数据库的序列来生成主键要设定序列名不然hibernate无法找到 seqhilo通过 hilo 算法实现但是主键历史保存在 Sequence 中 适用于支持 Sequence 的数据库如 Oracle比较少用 foreign使用另外一个相关联的对象的主键通常和one-to-one联合起来使用 guid采用数据库底层的 guid 算法机制 对应 MYSQL 的 uuid() 函数SQL Server 的 newid() 函数ORACLE 的rawtohex(sys_guid()) 函数等 uuid.hex看 uuid建议用 uuid 替换 sequence-identitysequence 策略的扩展采用立即检索策略来获取 sequence 值 注意需要 JDBC3.0 和 JDK4 以上含1.4版本
使用示例
// uuid
GeneratedValue(generator paymentableGenerator)
GenericGenerator(name paymentableGenerator, strategy uuid)
// 除以下所列特殊适配格式外其他策略均采用上面第一种格式
// select
GeneratedValue(generator paymentableGenerator)
GenericGenerator(nameselect, strategyselect, parameters { Parameter(name key, value idstoerung) })
// sequence
GeneratedValue(generator paymentableGenerator)
GenericGenerator(name paymentableGenerator, strategy sequence, parameters { Parameter(name sequence, value seq_payablemoney) })
// seqhilo
GeneratedValue(generator paymentableGenerator)
GenericGenerator(name paymentableGenerator, strategy seqhilo, parameters { Parameter(name max_lo, value 5) })
// foreign
GeneratedValue(generator idGenerator)
GenericGenerator(name idGenerator, strategy foreign, parameters { Parameter(name property, value employee) })
// sequence-identity
GeneratedValue(generator paymentableGenerator)
GenericGenerator(name paymentableGenerator, strategy sequence-identity,parameters { Parameter(name sequence, value seq_payablemoney) })对于这些 hibernate 主键生成策略和各自的具体生成器之间的关系在 org.hibernate.id.IdentifierGeneratorFactory 中指定了
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);
}
// 上面十二种策略加上nativehibernate一共默认支持十三种生成策略。自定义策略
hibernate 每种主键生成策略提供接口 org.hibernate.id.IdentifierGenerator 的实现类如果要实现自定义的主键生成策略也必须实现此接口。
IdentifierGenerator 提供一个 generate 方法generate 方法返回产生的主键。
// 源码展示
public interface IdentifierGenerator { public static final String ENTITY_NAME entity_name; public Serializable generate(SessionImplementor session, Object object) throws HibernateException;
} 自定义主键生成策略 方式1自定义类实现 IdentifierGenerator 接口 方式2自定义类继承 hibernate 的主键生成器类间接实现了 IdentifierGenerator 接口 示例 import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.UUIDHexGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import java.io.Serializable;
import java.util.Properties;/*** 自定义主键生成策略。实现自己设置ID同时保留原来的主键生成策略32位UUID不变。* 调用的保存方法需为Repository.save()或EntityManager.merge()* 若调用的保存方法为EntityManager.persist()且传入对象有id值时仍会报错*/
public class CustomUUIDGenerator extends UUIDHexGenerator {private String entityName;Overridepublic void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {entityName params.getProperty(ENTITY_NAME);if (entityName null) {throw new MappingException(no entity name);}super.configure(type, params, serviceRegistry);}Overridepublic Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException {Serializable id session.getEntityPersister(entityName, object).getIdentifier(object, session);if (id ! null) {return id;}return super.generate(session, object);}
}Entity 实体类中使用 GeneratedValue(generator paymentableGenerator)
GenericGenerator(name paymentableGenerator, strategy {自定义主键生成策略的全限定类名})
private String id;Repository 相关注解
Repository 相关注解主要在 SpringDataJpa 的 Repository 中使用。 Query自定义 JPQL 或原生 Sql 查询摆脱命名查询的约束 Query(select u from User u where u.firstname :firstname) // JPQL
User findByLastnameOrFirstname(Param(lastname) String lastname);Query(value SELECT * FROM USERS WHERE X ?1, nativeQuery true) // 原生sql
User findByEmailAddress(String X);关于 **Query **中参数的占位符 方式1标识符 :参数名 可以定义好参数名赋值时采用 Param(“参数名”)而不用管顺序。 方式2使用索引下标 ?索引值 索引值从 1 开始查询中 ”?X” 个数需要与方法定义的参数个数相一致并且顺序也要一致。 ModifyingDELETE 和 UPDATE 操作必须加上 modifying 注解以通知 Spring Data 这是一个 DELETE 或 UPDATE 操作 TransactionalUPDATE 或者 DELETE 操作需要使用事务 Async异步操作 NoRepositoryBean避免 Spring 容器为此接口创建实例。 不被Service层直接用到的Repository如base repository均应加此声明 可用于定义公共 Repository并将业务中用到的公共方法抽离到公共Repository中 NoRepositoryBean
public interface BaseRepositoryT, ID {ModifyingQuery(update #{#entityName} set isDeleteN where id in ?1 )Integer myUpdateAsNotDeleted(CollectionString ids);
}