Как сохранить изображение в формате BLOB-объектов в MySQL на Java

Для выполнения задачи мне нужно сохранить изображение в MySQL в формате большого двоичного объекта (хотя было бы лучше и идеально хранить путь к изображению в базе данных и хранить изображение в папке в локальной копии).

До сих пор я исследовал и не смог найти ответа, который мог бы мне помочь, это то, что я сделал до сих пор.

Вскоре после нажатия кнопки это будет запущено:

empdao.insertImage(fis);

Изображение заполняется другим четным слушателем следующим образом:

static FileInputStream fis = null;
static String path = null;
path = filechooser.getSelectedFile().getAbsolutePath();
File image = new File(path);
fis = new FileInputStream (image);

Этот код ниже заботится о добавлении его в базу данных.

public void insertImage(FileInputStream fis) throws SQLException {



Connection c = getConnection();     

    String query = "INSERT INTO Picture (picture) VALUES (?)";

    System.out.println(query);

    PreparedStatement pstmt = c.prepareStatement(query);

    pstmt.setBinaryStream(1, fis);

    pstmt.executeUpdate();

    c.close();
}

Однако проблема в том, что мне нужно было преобразовать его в большой двоичный объект, и я не знаю, как это сделать, может ли кто-нибудь помочь мне или подсказать, как сохранить выбранное изображение в качестве поля большого двоичного объекта в MySQL.

В настоящее время, когда он добавляет его в базу данных, я получаю ввод файла java.io в столбце изображений.


person dark_illusion_909099    schedule 28.12.2016    source источник
comment
stackoverflow.com/a/41235395/267540   -  person e4c5    schedule 29.12.2016


Ответы (2)


Предположим, у вас есть таблица my_picures в MySQL с id INT PRIMARY KEY, name VARCHAR(255), и photo BLOB.

Затем вы можете использовать следующий код Java, чтобы вставить новое изображение как BLOB:

public class InsertPictureAsBlob {
    public static void main(String[] args) throws Exception, IOException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager
             .getConnection("jdbc:mysql://localhost/databaseName", "username", "password");
        String INSERT_PICTURE = "INSERT INTO my_picures(id, name, photo) VALUES (?, ?, ?)";

        conn.setAutoCommit(false);
        File file = new File("myPhoto.png");
        try (FileInputStream fis = new FileInputStream(file);
                    PreparedStatement ps = conn.prepareStatement(INSERT_PICTURE)) {
            ps.setString(1, "001");
            ps.setString(2, "name");
            ps.setBinaryStream(3, fis, (int) file.length());
            ps.executeUpdate();
            conn.commit();
        }
    }
}
person DimaSan    schedule 28.12.2016
comment
Я внес предложенные вами изменения, но изображение по-прежнему не добавляется в базу данных даже с использованием PreparedStatement. - person dark_illusion_909099; 29.12.2016

1) Во-первых, вам нужно убедиться, что у вас есть таблица, созданная в вашей схеме MySQL с определенным типом столбца BLOB (BLOB, MEDIUMBLOB, LONGBLOB). Просмотрите типы столбцов BLOB, доступные в MySQL, и выберите подходящий размер.

2) Вы захотите переключиться с использования оператора на PreparedStatement.

String query = "INSERT INTO Pictures (Picture) VALUES (?)";
PreparedStatement pstmt = conn.prepareStatement(query);

3) В настоящее время вы передаете FileInputStream в свой метод, поэтому вам просто нужно использовать метод setBinaryStream для PreparedStatement.

pstmt.setBinaryStream(1, fis);

4) Затем выполните executeUpdate() для PreparedStatement.

pstmt.executeUpdate();

Используйте обработку исключений, которую вы имеете в своем исходном коде, и выполните соответствующую очистку объектов (подключение к базе данных, подготовленные операторы), аналогично тому, что у вас есть в исходном коде.

person M. Rizzo    schedule 28.12.2016
comment
Могу ли я в любом случае использовать обычный оператор вместо PreparedStatement, поскольку это задача, и я должен следовать спецификации??? - person dark_illusion_909099; 28.12.2016
comment
@jomin_george94 Приведенный выше код - это то, как вы должны это делать, ваш текущий код, и я не могу иначе выразиться, небезопасный мусор, а не то, как хороший код доступа к базе данных написан на Java. Я не уверен, что вы имеете в виду под необходимостью следовать спецификации, но спецификации обычно описывают, что нужно сделать, а не как это должно быть реализовано. - person Mark Rotteveel; 28.12.2016
comment
Когда я делаю так, как вы предложили, я получаю NullPointerException и терплю неудачу в этой строке: - person dark_illusion_909099; 29.12.2016
comment
pstmt.setBinaryStream(1, fis); - person dark_illusion_909099; 29.12.2016
comment
@ jomin_george94 Есть способ использовать обычный оператор с MySQL, но я бы не рекомендовал его. Вам нужно будет включить двоичный литерал SQL в качестве значения в операторе. Если у вас в настоящее время есть NPE, повторно опубликуйте структуру своего кода сейчас. - person M. Rizzo; 29.12.2016
comment
Я внес предложенные вами изменения, но изображение по-прежнему не добавляется в базу данных даже с использованием PreparedStatement. - person dark_illusion_909099; 29.12.2016
comment
Ваша таблица называется Picture или Pictures? До того, как вы указали это как «Изображения». Где-то в коде должно быть что-то не так. - person M. Rizzo; 29.12.2016