1. 枚举类存入MySQL使用的数据库字段类型
因为一些问题(这里不谈),java的entity中如果有使用枚举类,在存入MySQL时,MySQL对应的数据类型使用String
或者int
,而不是enum
。
这时最简单的方法就是在java的entity中对应的字段加上@Enumerated
注解,例如:
@Enumerated(EnumType.STRING)
private DataStatusEnum templateState;
上面的EnumType.STRING
表示存到MySQL中的是String类型,即templateState.name();如果要存数字,则使用EnumType.ORDINAL
,存入的就是templateState.ordinal(),表示的是枚举类型在枚举类中的先后顺序,从0开始。
如果这两种都不满足要求,复杂一点的也可以自定义Converter(这里不谈,想了解可以参考https://www.cnblogs.com/xiaoq/p/7885775.html)。
2. JPA查询使用枚举类作为参数的方法
我们知道JPA的一大特点就是不用写SQL语句,JPA会帮你将java查询代码转换为SQL去查询数据库(其中最重要的entity的属性与表字段的映射关系,对于枚举类来说就是1中提到的)。
JPA查询方法有四种:
2.1 继承JpaRepository接口,查询方法名中拼接查询条件
List<WatermarkTemplate> findByOwnerAndWatermarkTemplateState(String owner, DataStatusEnum watermarkTemplateState);
findByOwnerAndWatermarkTemplateState
中Owner
和WatermarkTemplateState
就是属性名并改为首字母大写。
2.2 继承JpaRepository接口,使用@Query注解编写hql语句
@Query("from WatermarkTemplate where owner=?1 and watermarkTemplateState=?2")
List<WatermarkTemplate> findByOwnerAndWatermarkTemplateState(String owner, DataStatusEnum watermarkTemplateState);
其中owner
和watermarkTemplateState
是实体类WatermarkTemplate
的两个属性,而不是MySQL表中字段名称,JPA会帮你做映射。
如果属性名是watermarkTemplateState
,字段名是watermark_template_state
,这样驼峰和下划线对应,JPA会自动做映射;如果不对应,就要在属性上加注解@Column("watermark_template_state")
,括号中是表的字段名,这样来告诉JPA映射关系。
2.3 继承JpaRepository接口,使用@Query注解编写SQL语句
@Query(nativeQuery = true, value="select * from watermark_template where owner=:owner and watermark_template_state=:watermarkTemplateState")
List<WatermarkTemplate> findByOwnerAndWatermarkTemplateState(String owner, String watermarkTemplateState);
这里nativeQuery = true
就是表示使用原生SQL语句,SQL语句就不解释了,区别就在于使用的是MySQL表名watermark_template
和字段名owner
、watermark_template_state
(注意和2中对比)。
2.4 继承JpaSpecification接口,使用Java代码编写查询条件
public Specification<WatermarkTemplate> getWatermarkTemplateSpec(final String owner, final DataStatusEnum templateState) {
return (root, query, cb) -> {
Predicate res = cb.equal(root.get("owner"), owner);
res = cb.and(res, cb.equal(root.get("watermarkTemplateState"), templateState));
return res;
};
}
List<WatermarkTemplate> res = watermarkTemplateDao.findAll(getWatermarkTemplateSpec);
其中watermarkTemplateDao继承JpaSpecification接口。
2.5 这四种方法在枚举类使用上的区别
这其中1、2、4都跟MySQL的表名、字段名没有什么关系,是JPA映射实体类和数据库表;查询参数中枚举类和String或者int的转换也是JPA自动完成的(但是要记得加@Enumerated
注解,否则不起作用)。
只有3,因为是写原生SQl,不仅是自己写表名和字段名,参数也不能直接传入枚举类型,如果使用@Enumerated(EnumType.STRING)
就要手动转换传入templateState.name(),如果使用@EnumType.ORDINAL
就要手动转换传入templateState.ordinal()。
网友评论