JPA支持postgresql数组, 枚举及初始化
大约 2 分钟
提示
JPA使用的hibernate暂时没有提供postgresql数组, 枚举等类型. 通过引入包支持
1. 添加依赖
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>2.7.1</version>
</dependency>
2. 基础类上添加注解
import com.vladmihalcea.hibernate.type.array.IntArrayType;
import com.vladmihalcea.hibernate.type.array.LongArrayType;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import com.vladmihalcea.hibernate.type.array.UUIDArrayType;
import com.vladmihalcea.hibernate.type.basic.PostgreSQLEnumType;
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
@Data
@NoArgsConstructor
@MappedSuperclass
@Inheritance(strategy = InheritanceType.JOINED)
@Audited
@TypeDefs({
// 下面的支持数组, json, enum
@TypeDef(name = "int-array", typeClass = IntArrayType.class),
@TypeDef(name = "long-array", typeClass = LongArrayType.class),
@TypeDef(name = "uuid-array", typeClass = UUIDArrayType.class),
@TypeDef(name = "string-array", typeClass = StringArrayType.class),
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class),
@TypeDef(name = "pgsql_enum", typeClass = PostgreSQLEnumType.class)
})
@ApiModel(value = "基础领域类", description = "基础领域类")
public class BaseDomain {
@Enumerated(EnumType.STRING)
@Column(columnDefinition = "ut_state") // 设置为创建的enum类型名称
@Type(type = "pgsql_enum")
@ColumnDefault("'EFFECT'::ut_state") // 设置默认值
private State state;
}
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@Entity
@DynamicInsert
@DynamicUpdate
@Audited
@EntityListeners(AuditingEntityListener.class)
@Table(name = "tbl_client", schema = "oauth")
@GenericGenerator(name = "jpa-uuid", strategy = "uuid")
@ApiModel(value = "客户端类", description = "客户端类")
public class Client extends BaseDomain implements ClientDetails {
@Id
@GeneratedValue(generator = "jpa-uuid")
@Column(length = 32)
@ApiModelProperty(value = "客户端id")
private String clientId;
@Type(type = "string-array")
@Column(columnDefinition = "character varying(2048)[]") // 使用postgres数组类型
@StringArrayLength(max = 2048) // 自定义数组类型检查
private String[] authorizedGrantType;
@Type(type = "jsonb")
@Column(columnDefinition = "jsonb") //定义为json
@ColumnDefault("'{}'") // 默认为{}
@ApiModelProperty(value = "附加信息")
private Map<String, Object> additionalInformation = new LinkedHashMap<>();
}
3. validate自定义String数组内容长度检查
@Documented
@Constraint(validatedBy = {})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Repeatable(StringArrayLength.List.class)
public @interface StringArrayLength {
int length() default Integer.MAX_VALUE;
int min() default 0;
int max() default Integer.MAX_VALUE;
String message() default "{org.hibernate.validator.constraints.Length.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* Defines several {@code @Length} annotations on the same element.
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@interface List {
StringArrayLength[] value();
}
}
public class StringArrayValidator implements ConstraintValidator<StringArrayLength, String[]> {
private StringArrayLength validator;
@Override
public void initialize(StringArrayLength constraintAnnotation) {
this.validator = constraintAnnotation;
}
@Override
public boolean isValid(String[] value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
// 判断数组个数
if (validator.length() < value.length) {
return false;
}
// 判断数组内部string长度
return Stream.of(value)
.allMatch(str -> {
int length = StringUtils.length(str);
return length >= validator.min() && length <= validator.max();
});
}
}