Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 将实体中的列表转换为数据库中的单个字符串列_String_Hibernate_Arraylist - Fatal编程技术网

String 将实体中的列表转换为数据库中的单个字符串列

String 将实体中的列表转换为数据库中的单个字符串列,string,hibernate,arraylist,String,Hibernate,Arraylist,我的数据库中有一个VARCHAR字段,该字段的值是val1、val2、val3 是否可以将其设置为使用逗号作为拆分分隔符的实体的ArrayList属性?如果使用JPA 2.1,则可以创建AttributeConverter: @Converter public class StringListConverter implements AttributeConverter<List<String>, String> { @Override public Strin

我的数据库中有一个
VARCHAR
字段,该字段的值是
val1、val2、val3


是否可以将其设置为使用逗号作为拆分分隔符的实体的
ArrayList
属性?

如果使用JPA 2.1,则可以创建
AttributeConverter

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

  @Override
  public String convertToDatabaseColumn(List<String> list) {
    // Java 8
    return String.join(",", list); 
    // Guava
    return Joiner.on(',').join(list); 
  }

  @Override
  public List<String> convertToEntityAttribute(String joined) {
    return new ArrayList<>(Arrays.asList(joined.split(",")));
  }

}
@转换器
公共类StringListConverter实现AttributeConverter{
@凌驾
公共字符串convertToDatabaseColumn(列表){
//爪哇8
返回字符串。join(“,”列表);
//番石榴
返回Joiner.on(',').join(列表);
}
@凌驾
公共列表convertToEntityAttribute(字符串连接){
返回新的ArrayList(Arrays.asList(joined.split(“,”));
}
}
您可以在实体中使用此转换器:

@Column
@Convert(converter = StringListConverter.class)
private List<String> strings;
@列
@Convert(converter=StringListConverter.class)
私有列表字符串;
对于JPA 2.1之前的版本,您可以手动执行此操作:

@Entity
private MyEntity {
  ...
  private String strings;

  public List<String> getStrings() {
    return Arrays.asList(strings.split(","));
  }

  public void setStrings(List<String> list) {
    strings = String.join(",", list);
  }
}
@实体
私人医院{
...
私有字符串;
公共列表getStrings(){
返回Arrays.asList(strings.split(“,”);
}
公共无效设置字符串(列表){
strings=String.join(“,”列表);
}
}
我将
Arrays.asList
包装在转换器的
ArrayList
中,因为结果存储在属性中,对该列表的任何更改都将写回数据库-因此我需要一个可更改的列表(我无法向
Arrays.asList
的结果添加任何内容)。在before 2.1解决方案中,结果与属性没有连接,并且可变列表不会与属性同步

要查询在此类属性中包含特定项的实体,请参阅我的回答“是”,这是可能的

使用Hibernate 4.3.x+可以定义一个
AttributeConverter
,尽管我很确定这对于早期的Hibernate版本不起作用,因为它是
列表
类型。请参见以下示例:

另一种方法是实现自定义的
UserType
,并使用
org.hibernate.annotations.Type
注释字段/getter。下面是一个很好的例子:


JPA兼容的另一种方式是有两个字段,用
javax.persistence.Transient
注释的
列表和
字符串
,但是您必须自己在
PrePersist
PreUpdate
侦听器中管理这两个字段之间的状态同步。这里有一个使用侦听器的示例:

尝试使用@ElementCollection和@CollectionTable注释

如果您希望字符串中有逗号
split()
/
join()
就不够了。对于那些寻找更好/不同解决方案的人来说,这里是通过序列化为JSON并从JSON反序列化来实现的。缺点是数据库中使用了更多的字符,但它适用于大部分文本。


你救了我一天,但这不是问题所要求的。的确如此。这将创建另一个表。不正确 package ...;

import java.io.Serializable;
import javax.persistence.AttributeConverter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class StringArrayConverter implements AttributeConverter<String[], String>, Serializable {

    private static final long serialVersionUID = -2744576922911393664L;

    @Override
    public String convertToDatabaseColumn(final String[] attribute) {
        try {
            return new ObjectMapper().writeValueAsString(attribute);
        }
        catch (@SuppressWarnings("unused") final JsonProcessingException e) {
            // ignore
        }
        return null;
    }

    @Override
    public String[] convertToEntityAttribute(final String dbData) {
        try {
            return new ObjectMapper().readValue(dbData, String[].class);
        }
        catch (@SuppressWarnings("unused") final JsonProcessingException e) {
            // ignore
        }
        return null;
    }

}
package ...;

import ....StringArrayConverter;

import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Getter @Setter @NoArgsConstructor
public class PersonWithCars {

    @Id @NotNull @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer id;
    
    private String name;

    @Convert(converter = StringArrayConverter.class)
    private String[] cars = new String[0];

}