Как сбросить массив байтов в скрипт INSERT INTO SQL (Java + PostgreSQL)

Как я могу заполнить базу Postgres SQL INSERT INTO SQL script следующей коллекцией данных на основе класса Java Entity. Проблема заключается в том, как я могу записать содержимое массива байтов как значение INSERT INTO («содержимое байта []») в сценарии SQL.

Это означает, что он не может передать эти данные через java-приложение, в соответствии с требованием ему требуется некоторый скрипт строки SQL для заполнения существующей базы данных в производственной среде. Спасибо.

Класс объекта

@Entity 
@Table(name="image_table")
public class ImageData implements Serializable {

  @Id
  @GeneratedValue 
  @Column(name = "id")
  private Integer id;

  @Column(name = "content")
  private byte[] content;
} 

Формат строки SQL, которую необходимо сгенерировать скрипту

 INSERT INTO image_table (id, content) VALUES ('1', '<content of the byte[]>');
 INSERT INTO image_table (id, content) VALUES ('2', '<content of the byte[]>');

person Channa    schedule 28.10.2014    source источник
comment
content.toCharArray или что-то в этом роде?   -  person Ashalynd    schedule 28.10.2014
comment
использовать JPA и setParameter   -  person Scary Wombat    schedule 28.10.2014


Ответы (2)


Чтобы ответить на ваш вопрос буквально: вы можете написать сценарий SQL INSERT для целого числа и значения большого двоичного объекта, но это было бы довольно ужасно с шестнадцатеричными экранированными строками для байтов, и вы могли бы легко столкнуться с проблемами с длинными операторами для больших больших двоичных объектов; Сам PostgreSQL не имеет практических ограничений, но они есть у большинства обычных текстовых редакторов.

Начиная с PostgreSQL 9.0 вы можете использовать формат hex (документация здесь). По сути, шестнадцатеричное значение в текстовом представлении выглядит как E'\x3FB5419C' и т. д. Таким образом, вы выводите из своего метода E'\x, затем byte[] в виде шестнадцатеричной строки, затем закрывающую '. Написание шестнадцатеричной строки из byte[] content можно выполнить с помощью org.apache.commons.codec.binary.Hex.encodeHexString(content) или использовать этот ответ SO для простого решения Java. В зависимости от вашей производственной среды вам, возможно, придется экранировать обратную косую черту \\ и возиться с символом новой строки. Я предлагаю вам попробовать это с небольшой каплей, чтобы увидеть, что работает для вас.

Лучшим подходом является прямая вставка. Предполагая, что вы используете драйвер JDBC PostgreSQL, в документации есть проработанный пример< /а>. Учитывая, что у вас есть член класса byte[], вы должны использовать метод setBytes() вместо setBinaryStream() (который ожидает экземпляр InputStream):

PreparedStatement ps = conn.prepareStatement("INSERT INTO image_table (id, content) VALUES (?, ?)");
ps.setInteger(1, 1);
ps.setBytes(2, content);
ps.executeUpdate();
ps.setInteger(1, 2);
ps.executeUpdate();
ps.close();
person Patrick    schedule 28.10.2014
comment
Привет Патрик! Спасибо за достойный полный отзыв. Да, как вы упомянули, это плохая практика - записывать значение Blob в сценарий SQL строки, но в соответствии с требованием для использования в производственной среде требуется некоторый сценарий SQL строки. Поэтому я хочу знать, как я могу записать значение Blob в файл сценария строки SQL? Каков формат данных? - person Channa; 29.10.2014
comment
Привет Патрик! Спасибо за достойный полный ответ. Как вы упомянули, я преобразовал массив байтов в шестнадцатеричный (с простым решением Java) и добавил это значение в сценарий SQL, как показано ниже; String hexVal = '\\x + bytesToHex(content) + '; INSERT INTO image_table (id, content) VALUES ('1', hexVal); - person Channa; 30.10.2014

Вы должны поместить аннотацию @Lob поверх столбца контента. Ваш окончательный результат будет примерно таким:

import javax.persistence.Lob;
.
.
.
@Lob
@Column(name = "content")
private byte[] content;
person zaerymoghaddam    schedule 28.10.2014