Двоичный файл в базу данных SQL Apache Camel - PullRequest
3 голосов
/ 22 марта 2012

Мне нужно несколько советов о том, какой подход использовать для загрузки бинарных файлов из папки в базу данных MySQL с использованием Camel. По сути, я хочу хранить голосовые журналы нашей АТС в базе данных. Каталог с голосовыми журналами будет удаленным каталогом

Я разработал прототип, но я не уверен, что это действительно эффективно, он работает, но я не доволен дизайном. Позвольте мне объяснить, что я делаю. Верблюжий маршрут выглядит следующим образом:

    <camelContext xmlns="http://camel.apache.org/schema/spring">
    <package>com.hia.camelone</package>
      <route>
            <from uri="file://c:/CTest/Inbox?noop=true&amp;recursive=true&amp;delay=3000"/>
            <to uri="bean://fileToSQL"/>
            <to uri="jdbc://timlogdb"/>

       </route>

</camelContext>

<bean id="timlogdb" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value=" com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/TimLog" />
    <property name="username" value="root" />
    <property name="password" value="blahblah" />
</bean>
<bean id="fileToSQL" class="com.hia.camelone.fileToSQL"/>

А код для bean-компонента fileToSQL:

public class fileToSQL {

public String toString(@Headers Map<String,Object> header, @Body Object body){
    StringBuilder sb = new StringBuilder();
    String filename =(String)header.get("CamelFileNameOnly");
    String escapedFileName = StringEscapeUtils.escapeJava(filename).replace("\'", "");
    String filePath = StringEscapeUtils.escapeJava((String)header.get("CamelFilePath"));

    sb.append("insert into FileLog ");
    sb.append("(FileName,FileData) values (");
    sb.append("'").append(escapedFileName).append("',").append("LOAD_FILE(\"").append(filePath).append("\")");
    sb.append(")");
    System.out.println(sb.toString());
    System.out.println(body);
    System.out.println(header.toString());
    return sb.toString();
}
}

Хорошо, короткое объяснение Я получаю файловый компонент для использования файлов, затем строю строку SQL, используя функцию MySQL LOAD_FILE () для загрузки файла.

Мои мысли об этом:

Функция LOAD_FILE работает только на локальном компьютере, и поэтому этот маршрут будет работать только с файлами, находящимися на локальном компьютере. Я мог бы использовать производителя файлов, чтобы скопировать файлы из некоторого удаленного каталога в локальный каталог, а затем использовать маршрут. Мой маршрут будет примерно таким:

<route>
            <from uri="file://c:/CTest/Inbox?noop=true&amp;recursive=true&amp;delay=3000"/>
            <to uri="file://c:/outbox"/>
            <to uri="bean://fileToSQL"/>
            <to uri="jdbc://timlogdb"/>

</route>

Однако, поскольку у меня есть доступ к содержимому файлов в сообщении от потребителя файлов, у меня должна быть теоретическая возможность получить доступ к телу / содержимому строки и создать команду SQL, которая НЕ использует функцию LOAD_FILE () ,

Единственный способ, которым я знаю, как построить такую ​​строку, - использовать подготовленный оператор JDBC. Это было бы первым призом, если бы я мог как-то создать оператор вставки с содержимым от потребителя файла.

Могу ли я создать подготовленный оператор в моем bean-компоненте fileToSQL и передать его моему компоненту jdbc? Или как мне создать оператор INSERT без функции LOAD_FILE ()?

Поскольку я должен использовать функцию LOAD_FILE (), мне теперь придется обслуживать как UNIX, так и Windows FilePath. Хотя это не должно быть сложным, мне просто не нравится идея вставлять специфический для ОС код в мои приложения (похоже на обходной путь).

Кто-нибудь здесь загружал двоичные файлы в базу данных MySQL, используя Camel, который может дать мне несколько советов по вышеуказанным пунктам. Хотя я мог бы обойти проблемы, я просто хочу убедиться, что я не пропускаю очевидный способ делать вещи.

Я осмотрелся здесь и нашел только людей, работающих в основном с текстовыми файлами. Ребята, пожалуйста, даже не идите по пути, когда я храню файл в файловой системе и связываю его с базой данных. У нас есть очень специфические требования к аварийному восстановлению и юридические требования, которые заставляют меня хранить его в базе данных.

1 Ответ

2 голосов
/ 23 марта 2012

Правильно, так что мне удалось найти способ, и это было не так сложно.По сути, я избавился от верблюжьего компонента JDBC на маршруте.Затем я внедрил компонент источника данных в мой компонент fileToSQL.Затем я использовал простой подготовленный оператор для вставки файла и его имени в MySQL.

Как всегда, код гораздо более явный, чем мой английский.

 <camelContext xmlns="http://camel.apache.org/schema/spring">
    <package>com.hia.camelone</package>

      <route>
            <from uri="file://c:/CTest/Inbox?noop=true&amp;recursive=true&amp;delay=3000"/>
            <to uri="bean://fileToSQL"/>
            <!--<to uri="jdbc://timlogdb"/>-->

       </route>

</camelContext>

<bean id="timlogdb" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value=" com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/TimLog" />
    <property name="username" value="root" />
    <property name="password" value="lalala" />
</bean>
<bean id="fileToSQL" class="com.hia.camelone.fileToSQL">
    <property name="dataSource" ref="timlogdb"/>
</bean>

Как видите, я ввожу свойbean-компонент timlogdb в мой bean-компонент fileToSQL.Spring ROCKS!

Вот мой бин fileToSQL.

public class fileToSQL {
private DriverManagerDataSource dataSource;
private static final String SQL_INSERT="insert into FileLog(FileName,FileData)values(?,?)";
@Handler
public void toString(@Headers Map<String,Object> header,Exchange exchange){
    Connection conn = null;
    PreparedStatement stmt=null;
    String filename =StringEscapeUtils.escapeJava(((String)header.get("CamelFileNameOnly")).replace("\'", ""));

    try {
        conn= dataSource.getConnection();
        stmt =conn.prepareStatement(SQL_INSERT);
        stmt.setString(1, filename);
        byte[] filedata = exchange.getIn().getBody(byte[].class);
        stmt.setBytes(2,filedata );
        int s = stmt.executeUpdate();

    }
    catch (Exception e)
    {
        System.out.println(e.getMessage());
    }
    finally{
        try
        {
                if (stmt!=null)
                {
                    stmt.close();
                }
                if (conn!=null)
                {
                    conn.close();
                }
        }
        catch(SQLException e)
        {
            System.out.println(e.getMessage());
        }
    }


}

/**
 * @param dataSource the dataSource to set
 */
public void setDataSource(DriverManagerDataSource dataSource) {
    this.dataSource = dataSource;
}
}

Ребята из Camel проделали отличную работу.Верблюд действительно гибкий, особенно когда вы сочетаете его с Spring.

Какая поездка!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...