JPA:将值列表另存为逗号分隔的值

iqih9akk  于 2022-11-14  发布在  其他
关注(0)|答案(3)|浏览(190)

我正在接收JSON请求的简单值列表部分,希望将其另保存为逗号分隔的值。尝试使用以下内容,但不起作用。

@Column(nullable = true)
@GeneratedValue(strategy = GenerationType.AUTO)
private ArrayList<String> services = new ArrayList<String>() ;

@Column(nullable = true)
@ElementCollection(targetClass = String.class)
private List<String> services = new ArrayList<String>() ;

@ElementCollection掷回例外状况,表示table services does not exist

svmlkihl

svmlkihl1#

@ElementCollection需要一个表来存储多行值,
因此,您可以定义为String列,并在getter和setter中进行联接/分解,如下所示

private String services;

public setServices(String services[]) //Can be Array or List
{
     // this.services = Iterate services[] and create a comma separated string or Use ArrayUtils
}

public String[] getServices() //Can be Array or List
{
    // services.split(",") to get a list of Strings, then typecast/parse them to Strings before returning or use Arrays.asList(arguments.split(","));
}
nkkqxpd9

nkkqxpd92#

正如其他人在评论中提到的,AttributeConverter工作得很好。这个使用Jackson序列化为JSON数组。我推荐JSON,因为它可以干净地处理分隔符转义、空值、引号等:

@Converter
public class StringListAttributeConverter implements AttributeConverter<List<String>, String> {

    private static final TypeReference<List<String>> TypeRef = new TypeReference<List<String>>(){};

    @Override
    public String convertToDatabaseColumn (List<String> attribute) {
        if (attribute == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().writeValueAsString(attribute);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }

    @Override
    public List<String> convertToEntityAttribute (String dbData) {
        if (dbData == null) {
            return null;
        }
        try {
            return ObjectMapperFactory.getInstance().readValue(dbData, TypeRef);
        }
        catch (IOException ex) {
            throw new UncheckedIOException(ex);
        }
    }
}

我使用过这个类,它在大多数情况下都能很好地工作。我发现的一个警告是,使用这个转换器可能会混淆一些JPA条件查询,因为它在实体上期望类型List,但在数据库中却找到String。

ha5z0ras

ha5z0ras3#

一个更简单的变体对我来说很有用,没有Jackson,但修剪字符串:

public class CsvTrimmedStringsConverter implements AttributeConverter<List<String>, String> {
  @Override
  public String convertToDatabaseColumn(List<String> attribute) {
    return attribute == null
        ? null
        : attribute.stream().map(String::trim).collect(Collectors.joining(","));
  }

  @Override
  public List<String> convertToEntityAttribute(String dbData) {
    return dbData == null
        ? null
        : Arrays.stream(dbData.split(",")).map(String::trim).collect(Collectors.toList());
  }
}

相关问题