programing

Java prepared Statement를 사용하여 Postgres에 JSON 개체를 삽입하려면 어떻게 해야 합니까?

newsource 2023. 4. 5. 21:59

Java prepared Statement를 사용하여 Postgres에 JSON 개체를 삽입하려면 어떻게 해야 합니까?

데 을 겪고 . "을 postgres v9.4 DB JSON 했습니다. 에브티손json)jsonb를 참조해 주세요.

Java(jdk1.8)에서 준비된 문을 사용하여 JSON 오브젝트(JE javax.json 라이브러리를 사용하여 빌드)를 컬럼에 삽입하려고 하는데 SQLException 오류가 계속 발생합니다.

다음을 사용하여 JSON 개체를 만듭니다.

JsonObject mbrLogRec = Json.createObjectBuilder().build();
…
mbrLogRec = Json.createObjectBuilder()
                .add("New MbrID", newId)
                .build();

그런 다음 이 오브젝트를 파라미터로 다른 메서드에 전달하여 준비된 스테이트먼트를 사용하여 DB에 씁니다.(다른 여러 필드와 함께) As:

pStmt.setObject(11, dtlRec);

이 방법을 사용하면, 다음의 에러가 표시됩니다.

org.postgresql.displays.displayPSQLException:설치된 hstore 확장이 없습니다.org.postgresql.jdbc로 이동합니다.PgPrepared 스테이트먼트org.postgresql.jdbc의 setMap(PgPreparedStatement.java:553)을 참조해 주세요.PgPreparedStatement.setObject(PgPreparedStatement.java:1036)

나도 시도해봤어:

pStmt.setString(11, dtlRec.toString());
pStmt.setObject(11, dtlRec.toString());

이로 인해 다른 오류가 발생합니다.

이벤트 JSON: {"새로운 MBRID":29}

SQLException: ERROR: 열 "evtjson"은 json 형식이지만 식이 다양한 문자 형식입니다.

힌트: 식을 다시 쓰거나 캐스팅해야 합니다.

그러나 적어도 DB가 열을 JSON 유형으로 인식하고 있음을 알 수 있습니다.hstore 확장을 설치하려고 했는데 hstore 객체가 아닌 것으로 나타났습니다.

OracleDocs는 preparedStatement에 파라미터 값을 설정하기 위한 다양한 방법을 보여 주지만 답을 알고 있는 사람이 있다면 모두 시도하지 않는 것이 좋습니다.(http://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html) 추가 파라미터인 SQLType도 참조하지만 참조할 수 없습니다.

setAsciiStream무슨 일입니까?CharacterStream 클로브?

SQL 명령에서 리터럴 문자열로 사용할 경우 JSON 문자열이 문제없이 허용되므로 이 동작은 매우 번거롭습니다.

postgres 드라이버 Github 저장소에 이미 문제가 있습니다(서버측 처리에 문제가 있다고 생각되는 경우에도).

문제 작성자는 SQL 문자열에 캐스트(@a_horse_with_no_name의 답변 참조)를 사용하는 것 외에 다음 두 가지 추가 해결책을 제공합니다.

  1. " " " 를 합니다.stringtype=unspecifiedJDBC URL/URL/URL/URL-URL-URL-URL-URL-URL-URL-URL-URL-URL-URL-U

이것이 Postgre에게 알려준다.모든 텍스트 또는 varchar 매개 변수가 실제로 알 수 없는 유형인 SQL을 통해 보다 자유롭게 유형을 추론할 수 있습니다.

  1. 매개 변수를 에 줄 바꿈org.postgresql.util.PGobject:

 PGobject jsonObject = new PGobject();
 jsonObject.setType("json");
 jsonObject.setValue(yourJsonString);
 pstmt.setObject(11, jsonObject);

다음과 같이 할 수 있으며 json 문자열만 있으면 됩니다.

쿼리를 다음으로 변경합니다.

String query = "INSERT INTO table (json_field) VALUES (to_json(?::json))"

그리고 파라미터를 String으로 설정합니다.

pStmt.setString(1, json);

두 가지 옵션이 있습니다.

  1. 스테이트먼트를 사용합니다.setString(jsonStr) 후 sql 문에서 변환을 처리합니다.

    PreparedStatement statement = con.prepareStatement(
      "insert into table (jsonColumn) values (?::json)");
    statement.setString(1, jsonStr);
    
  2. 다른 옵션은 PG 개체를 사용하여 사용자 지정 값 래퍼를 만드는 것입니다.

    PGobject jsonObject = new PGobject();
    PreparedStatement statement = con.prepareStatement(
      "insert into table (jsonColumn) values (?)");
    jsonObject.setType("json");
    jsonObject.setValue(jsonStr);
    statement.setObject(1, jsonObject);
    

저는 개인적으로 후자를 선호합니다. 왜냐하면 질문이 더 깨끗하기 때문입니다.

JSON을 String으로 전달하는 것이 올바른 방법이지만 오류 메시지에 나타나듯이 에러 메시지에서 알 수 있듯이INSERT에 대한 진술JSON값:

insert into the_table
   (.., evtjson, ..) 
values 
   (.., cast(? as json), ..)

그럼, 을 사용할 수 있습니다.pStmt.setString(11, dtlRec.toString())값을 넘기다

대부분의 답변은 jdbc를 사용하여 postgres json 필드에 비표준적인 방법으로 삽입하는 방법을 정의합니다(db 구현에 고유).postgres json 필드에 순수 jdbc 및 순수 sql을 사용하여 Java 문자열을 삽입해야 하는 경우:

preparedStatement.setObject(1, "{}", java.sql.Types.OTHER)

그러면 postgres jdbc 드라이버(org.postgresql:postgresql:42.2.19)가 Java 문자열을 json 유형으로 변환합니다.또한 이 문자열이 유효한 json 표현임을 검증합니다.이는 암묵적인 문자열 캐스트를 사용하여 다양한 답변이 수행되지 않으므로 영구적인 json 데이터가 손상될 수 있습니다.

다른 사용자가 언급했듯이 SQL 문자열은 바인드 값을 Postgre에 명시적으로 캐스팅해야 합니다.SQLjson또는jsonb입력:

insert into t (id, j) values (?, ?::json)

이제 문자열 값을 바인딩할 수 있습니다.또는 이를 실행할 수 있는 라이브러리를 사용할 수 있습니다(예: jOOQ(초기 사용 가능) 또는 휴지 상태(서드파티 사용)UserType등록).이 방법의 장점은 이러한 변수를 바인딩(또는 읽을 때)할 때마다 이 문제를 고려할 필요가 없다는 것입니다.jOOQ의 예를 다음에 나타냅니다.

ctx.insertInto(T)
   .columns(T.ID, T.J)
   .values(1, JSON.valueOf("[1, 2, 3]"))
   .execute();

이(또는 ) 데이터 유형으로 작업할 때마다 위와 동일한 캐스트가 항상 생성됩니다.

(면책자:jOOQ의 배후에 있는 회사에 근무하고 있습니다.)

스프링 부트를 사용하는 경우: application.properties에 다음 행을 추가하면 도움이 됩니다.

spring.datasource.hikari.data-source-properties.stringtype=unspecified

Wero가 쓴 대로:

이것이 Postgre에게 알려준다.모든 텍스트 또는 varchar 매개 변수가 실제로 알 수 없는 유형인 SQL

json 개체를 전달하는 대신 문자열 값을 전달하고 쿼리의 json에 캐스트합니다.예:

JSONObject someJsonObject=..........

String yourJsonString = someJsonObject.toString();

String query = "INSERT INTO table (json_field) VALUES (to_json(yourJsonString::json))";

이건 나한테 효과가 있었어요.

언급URL : https://stackoverflow.com/questions/35844138/how-can-i-insert-json-object-into-postgres-using-java-preparedstatement