Java 在postgresql中将列表另存为JSON数组
我有一个清单Java 在postgresql中将列表另存为JSON数组,java,json,postgresql,hibernate,Java,Json,Postgresql,Hibernate,我有一个清单私人清单课程
私人清单课程我需要将此列表保存到PostgreSQL数据库列中,数据类型为\u json
或json[]
(json数组)。但我有一个错误:
错误:“课程”列的类型为json[],但表达式的类型为
类型字符变化或错误:数组文字格式错误:
“[{“id”:17,“标题”:“第1课”,“第1部分”:1.0}]
如何正确序列化列表
以获得Postgresql JSON数组的正确格式?您可能需要使用com.vladmin:hibernate types
库中的JsonBinaryType
类,并将JSON
(或jsonb
)应用于列定义:
// LessonList.java
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
@Entity
@Table(name = "lessons")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TypeDef(name = "json", typeClass = JsonBinaryType.class)
public class LessonList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Type(type = "json")
@Column(columnDefinition = "json")
private List<Lesson> lessons;
}
其余课程将提供工作示例:
// Lesson.java
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Lesson {
private int id;
private String title;
private double part;
}
扩展Springcrudepository
接口和DAO类的存储库非常简单
运行测试的命令行运行程序:
@Slf4j
@Component
public class TestJson implements CommandLineRunner {
@Autowired
private LessonListDao dao;
@Override
public void run(String[] args) {
List<Lesson> lessons = Arrays.asList(
Lesson.builder().id(11).title("Physics").part(1.0).build(),
Lesson.builder().id(12).title("Chemistry").part(2.0).build(),
Lesson.builder().id(13).title("Biology").part(3.0).build()
);
LessonList list = LessonList.builder().lessons(lessons).build();
LessonList result = dao.save(list);
LOGGER.info("result: " + result);
List<LessonList> all = dao.findAll();
all.forEach(a -> LOGGER.info("item #" + a.getId() + "; lessons=" + a.getLessons()));
}
}
数据库数据:从“公共”中选择*课程
:
**id** **lessons** **created_at**
[PK] Integer json timestamp without timezone
1 [{"id":1,"title":"Math","part":1.0}, 2020-06-03 18:08:55.948007
{"id":2,"title":"English","part":2.0},
{"id":3,"title":"Informatics","part":3.0}]
2 [{"id":11,"title":"Physics","part":1.0}, 2020-06-03 18:27:06.565191
{"id":12,"title":"Chemistry","part":2.0},
{"id":13,"title":"Biology","part":3.0}]
更新
此库不支持json[]
类型,因为它可能非常冗余
下面的示例使用普通的JDBC+ObjectMapper
来处理json
要点是您需要使用ResultSet
的getArray
方法,然后将PGobject
中的字符串值转换为您的对象
ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getEnvironment();
DataSource ds = DataSourceBuilder.create()
.username(environment.getProperty("ds.pgsql.username"))
.password(environment.getProperty("ds.pgsql.password"))
.url(environment.getProperty("ds.pgsql.url")).build();
try (Connection connection = ds.getConnection();
PreparedStatement ps = connection.prepareStatement("SELECT id, lessons FROM lesson");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
Object[] arrLessons = (Object[]) rs.getArray("lessons").getArray();
List<Lesson> jsonLessons = Arrays.stream(arrLessons)
.map(PGobject.class::cast)
.map(lesson -> convert(lesson.getValue()))
.collect(Collectors.toList());
System.out.println(id + "; converted: " + jsonLessons);
}
}
//...
private Lesson convert(String value) {
try {
return mapper.readValue(value, Lesson.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
您可能需要使用com.vladmichalcea:hibernate types
库中的JsonBinaryType
类,并将json
(或jsonb
)应用于列定义:
// LessonList.java
import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
@Entity
@Table(name = "lessons")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TypeDef(name = "json", typeClass = JsonBinaryType.class)
public class LessonList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Type(type = "json")
@Column(columnDefinition = "json")
private List<Lesson> lessons;
}
其余课程将提供工作示例:
// Lesson.java
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Lesson {
private int id;
private String title;
private double part;
}
扩展Springcrudepository
接口和DAO类的存储库非常简单
运行测试的命令行运行程序:
@Slf4j
@Component
public class TestJson implements CommandLineRunner {
@Autowired
private LessonListDao dao;
@Override
public void run(String[] args) {
List<Lesson> lessons = Arrays.asList(
Lesson.builder().id(11).title("Physics").part(1.0).build(),
Lesson.builder().id(12).title("Chemistry").part(2.0).build(),
Lesson.builder().id(13).title("Biology").part(3.0).build()
);
LessonList list = LessonList.builder().lessons(lessons).build();
LessonList result = dao.save(list);
LOGGER.info("result: " + result);
List<LessonList> all = dao.findAll();
all.forEach(a -> LOGGER.info("item #" + a.getId() + "; lessons=" + a.getLessons()));
}
}
数据库数据:从“公共”中选择*课程
:
**id** **lessons** **created_at**
[PK] Integer json timestamp without timezone
1 [{"id":1,"title":"Math","part":1.0}, 2020-06-03 18:08:55.948007
{"id":2,"title":"English","part":2.0},
{"id":3,"title":"Informatics","part":3.0}]
2 [{"id":11,"title":"Physics","part":1.0}, 2020-06-03 18:27:06.565191
{"id":12,"title":"Chemistry","part":2.0},
{"id":13,"title":"Biology","part":3.0}]
更新
此库不支持json[]
类型,因为它可能非常冗余
下面的示例使用普通的JDBC+ObjectMapper
来处理json
要点是您需要使用ResultSet
的getArray
方法,然后将PGobject
中的字符串值转换为您的对象
ConfigurableEnvironment environment = (ConfigurableEnvironment) applicationContext.getEnvironment();
DataSource ds = DataSourceBuilder.create()
.username(environment.getProperty("ds.pgsql.username"))
.password(environment.getProperty("ds.pgsql.password"))
.url(environment.getProperty("ds.pgsql.url")).build();
try (Connection connection = ds.getConnection();
PreparedStatement ps = connection.prepareStatement("SELECT id, lessons FROM lesson");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
Object[] arrLessons = (Object[]) rs.getArray("lessons").getArray();
List<Lesson> jsonLessons = Arrays.stream(arrLessons)
.map(PGobject.class::cast)
.map(lesson -> convert(lesson.getValue()))
.collect(Collectors.toList());
System.out.println(id + "; converted: " + jsonLessons);
}
}
//...
private Lesson convert(String value) {
try {
return mapper.readValue(value, Lesson.class);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
你能更新你到目前为止尝试过的问题吗?@DumiduUdayanga我尝试过使用ObjectMapper和Gson Library你能更新你到目前为止尝试过的问题吗?@DumiduUdayanga我尝试过使用ObjectMapper和Gson Library谢谢你的回答,但我尝试过这个解决方案,但不适用于列类型JSON数组(PostgreJSON[])。您的解决方案可以应用于列JSON,而不是JSON数组。此库不支持JSON数组JSON[]
。您可以使用特定的修复程序检查更新。感谢您的回答,但我尝试了此解决方案,但不适用于列类型JSON数组(Postgresql JSON[])。您的解决方案可以应用于列JSON,而不是JSON数组。此库不支持JSON数组JSON[]
。您可以使用特定的修复程序检查更新。