列表中字符串值的 CrudRepository 过滤器<String> 属性

CrudRepository filter for String value in List<String> property

基本上我得到了以下实体(由 Lombok 扩展)

@Getter
@Setter
@Entity("FOO")
public class Foo{

     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "ID", unique = true, nullable = false)
     private long id;

     @ManyToOne
     @JoinColumn(name = "FK_FEE", nullable = false)
     private Fee fee;

     @Column(name = "CCCS")
     @Convert(converter = StringListConverter.class)
     private List<String> cccs;
}

和 StringListConverter:

@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
    @Override
    public String convertToDatabaseColumn(final List<String> list) {
        String returnValue = null;
        if (list != null) {
            final List<String> trimmedList = new ArrayList<>();
            for (final String strg : list) {
                if (strg != null && !strg.isEmpty()) {
                    trimmedList.add(strg.trim());
                }
            }
            returnValue = String.join(",", trimmedList);
        }
        return returnValue;
    }

    @Override
    public List<String> convertToEntityAttribute(final String joined) {
        List<String> returnValue = null;
        if (joined != null) {
            returnValue = new ArrayList<>();
            final String[] splitted = joined.split(",");
            for (final String strg : splitted) {
                if (strg != null && !strg.isEmpty()) {
                    returnValue.add(strg.trim());
                }
            }
        }
        return returnValue;
    }
}

现在我想获取 Foo 的列表,其中 Fee.Id= 123 和 Foo.cccs 包含特定的字符串值。

@Repository
public interface FooRepository extends CrudRepository<Foo, Long> {
    List<Foo> findByFeeIdAndCccsIn(Long feeId,  String ccc);
}

但这不起作用。是通过编写自己的查询来解决这个问题的唯一方法吗?

目前看来唯一的解决方案是使用 @Query 并编写 JPQL 或本机 SQL 查询来获取数据。

String SELECT_BY_FEE_AND_CCC = "Select foo FROM Foo foo "
        + " WHERE foo.fee.id = :feeId AND foo.cccs LIKE CONCAT(CONCAT('%', :ccc) ,'%')";

并附上 @Query 注释,例如:

@Query(SELECT_BY_FEE_AND_CCC)
List<Foo> findByFeeIdAndCccsContains(@Param("feeId") Long feeId, @Param("ccc") String ccc);

NOTE/EDIT: 有时您必须加入外国 table 才能访问其属性。

String SELECT_BY_FEE_AND_CCC = "Select foo FROM Foo foo "
        + " JOIN foo.fee fee "
        + " WHERE fee.id = :feeId AND foo.cccs LIKE CONCAT(CONCAT('%', :ccc) ,'%')";

And now I want to fetch a List of Foo where Fee.Id= 123 and Foo.cccs contains a specific string value.

您有具体要求。根据 Spring Data JPA doc 不支持您尝试执行的操作。

所以您应该使用 @Query 来满足您的要求。

@Repository
public interface FooRepository extends CrudRepository<Foo, Long> {
        @Query( "Select foo FROM Foo foo WHERE foo.fee.id = :feeId AND foo.cccs LIKE CONCAT(CONCAT('%', :cccs) ,'%')")
        List<Foo> findByFeeIdAndCccsIn(@Param("feeId") Long feeId,@Param("cccs") String ccc);
    }