2012-03-22 15 views
3

私は、Camelを使用してバイナリファイルをフォルダからMySQLデータベースにロードするためのアプローチについていくつかのガイダンスが必要です。基本的には私たちのPBXシステムからの音声ログをデータベースに保存したいのです。音声ログを含むディレクトリはリモートディレクトリになりますSQLデータベースへのバイナリファイルApache 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"/> 

そしてfileToSQL Beanへのコードは次のとおりです。

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(); 
} 
} 

[OK]を、短い説明が私はMySQLのLOAD_FILEを(使用してSQL文字列を構築し、その後、ファイルを消費するファイルのコンポーネントを取得)関数を使用してファイルをロードします。この周り

私の考え:

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> 

とLOAD_FILE()関数を使用しないSQLコマンドを作成します。

このような文字列を作成する方法を知っている唯一の方法は、準備済みのJDBC文を使用することです。これは、ファイルコンシューマからのコンテンツを挿入ステートメントをどういう形で構築することができれば、一番の賞です。

私のfileToSQL beanにprepared statementを作成し、これをjdbcコンポーネントに渡すことはできますか? また、LOAD_FILE()関数を使用せずにINSERT文を作成するにはどうすればよいですか?

私はLOAD_FILE()関数を使用しなければならないので、私は今はunixとwindowsの両方のファイルパスを扱う必要があります。これは難しいことではありませんが、OS固有のコードを自分のアプリケーションに入れるというアイデアは気になりません(回避策のように感じます)。

ここまで誰も私が上記の点についていくつかのガイダンスを与えることができるキャメルを使用してMySQLデータベースにバイナリファイルをアップロードしました。私は問題を回避することができますが、私は物事を行う明確な方法が欠けていないことを確認したいだけです。

私はここを見て、ほとんどがテキストファイルを扱う人しか見つけませんでした。みんなファイルシステムにファイルを保存し、データベースにリンクする私のルートに行ってはいけません。私たちには、データベースに格納する必要性を徹底させる非常に特殊な災害復旧要件と法的要件があります。

+0

私はラクダについては何も知らないけど、メッセージの内容をbase64の文字列でエンコーディングしてデータベースに挿入するのはあなたの仕事ですか?その後、あなたは通常の挿入を行うことができます。 – Icarus

+0

それは確かに一つの可能​​性です。私はそれについていくつかの研究をしており、私はファイルのバイト[]へのアクセス権を持っているようです。私が実例を見つけることができなかったことの1つは、このバイト[]をmysqlに挿入する方法です。ほとんどの例などはJDBCプリペアドステートメントを使用していますが、これは使いやすいものですが、私はキャメルでこれをどうやって行うのか分かりません。もう1つの可能性は、JDBCコンポーネントを完全にバイパスし、単純な古いjdbcをBean内で使用することです。物事が進むにつれて実験し、報告します。 – Namphibian

答えて

2

私は方法を見つけることができたし、それは難しいことではありませんでした。私が本質的にしたことは、ルート上のJDBC Camelコンポーネントを取り除くことでした。その後私は、fileToSQL BeanにデータソースBeanを注入しました。私は単純な準備文を使ってファイルとその名前を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> 

ご覧のとおり、私のtimlogdb beanを私のfileToSQL beanに挿入します。春のロック!

ここに私のfileToSQL beanがあります。

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と組み合わせると本当に柔軟です。

+0

私はJDBCアクセスのためにBean内でSpringのJdbcTemplateを使用することも好きです。それは私に制御を与える。 SQLの作業が大変な場合は、MyBatisもクールなフレームワークです。少しのSQL作業では、Spring BeanをSpring JdbcTemplateまたは単純なJDBCコードとともに使用します。 –

+0

Btwあなたは答えとしてこの質問を記入しますか? –

+0

私はもう一歩前進させ、プールされたデータソースを追加して、jdbc接続を効果的に再利用できるようにしました。また、fileToSQL Beanにスレッドプールを追加して、同時に挿入を実行できるようにしました。私は約9倍の5MBファイルをMySQLデータベースに1秒間保存しています。これは私のラップトップで実行されていて、サーバーでもないので、印象的です。カントはこれがいかに簡単か信じています。 – Namphibian

関連する問題