美文网首页
JPA遇到枚举类型

JPA遇到枚举类型

作者: 猫尾草 | 来源:发表于2019-12-22 15:43 被阅读0次

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

      findByOwnerAndWatermarkTemplateStateOwnerWatermarkTemplateState就是属性名并改为首字母大写。

    2.2 继承JpaRepository接口,使用@Query注解编写hql语句

    @Query("from WatermarkTemplate where owner=?1 and watermarkTemplateState=?2")
    List<WatermarkTemplate> findByOwnerAndWatermarkTemplateState(String owner, DataStatusEnum watermarkTemplateState);
    

      其中ownerwatermarkTemplateState是实体类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和字段名ownerwatermark_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()。

    相关文章

      网友评论

          本文标题:JPA遇到枚举类型

          本文链接:https://www.haomeiwen.com/subject/benznctx.html