2012-03-22 29 views
3

我需要一些指導,圍繞使用哪種方法將文件夾中的二進制文件加載到使用駱駝的MySQL數據庫中。基本上我想將來自我們的PBX系統的語音記錄存儲到數據庫中。與語音日誌的目錄將是遠程目錄二進制文件到SQL數據庫Apache駱駝

我設計了一個原型,但我不知道這是不是真的有效,它的工作原理,但我不開心的設計。讓我解釋我在做什麼。駱駝路線如下:

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

好了簡短的解釋我得到的文件組件消耗的文件,然後我建立使用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豆創建一個準備好的聲明,並把它傳遞給我的JDBC組件? 或者我如何建立一個沒有LOAD_FILE()函數的INSERT語句?

因爲我必須使用LOAD_FILE()函數,我現在不得不迎合UNIX和Windows文件路徑。雖然這不應該是困難的,但我不喜歡將操作系統特定代碼放入我的應用程序的想法(感覺像是一種工作)。這裏

有人不斷上傳的二進制文件使用駱駝MySQL數據庫誰可以給我上了上述幾點一些指導。雖然我可以解決這些問題,但我只想確保不會錯過顯而易見的做事方式。

我看看在這裏,只發現人大多是文本文件的工作。夥計們,請不要在我將文件存儲到文件系統並將其鏈接到數據庫的路線上走下坡路。我們有一些非常具體的災難恢復要求和法律要求,這些要求強制我需要將其存儲在數據庫中。

+0

我對駝峯一無所知,但會將消息內容添加到base64字符串中並插入到數據庫中工作嗎?然後你可以做你的正常插入。 – Icarus 2012-03-22 14:29:38

+0

這當然是一種可能性。我正在做一些研究,似乎我可以訪問文件的字節[]。我一直無法找到一個可靠的例子是如何將這個byte []插入到mysql中。大多數例子等使用JDBC準備語句,雖然這很容易使用,但我不知道我將如何與駱駝做到這一點。另一種可能性是完全繞過JDBC組件,只是在bean內使用普通的舊jdbc。隨着事情的發展,將進行實驗和報告。 – Namphibian 2012-03-22 18:57:07

回答

2

對,所以我設法找到了一種方法,並沒有那麼困難。我基本上做的是擺脫路由中的JDBC Camel組件。然後我將數據源bean注入到我的fileToSQL 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; 
} 
} 

來自駱駝的傢伙做得很好。特別是當你將它與Spring結合起來時,駱駝真的很靈活。

真是太棒了!

+0

是的,我喜歡在一個bean中使用Spring的JdbcTemplate進行JDBC訪問。它讓我控制。如果做大量的SQL工作,那麼MyBatis也是一個很酷的框架。對於小的SQL工作,然後使用Java Bean和Spring JdbcTemplate或者純JDBC代碼。 – 2012-03-23 16:47:03

+0

順便問一下,你是否將這個問題標記爲答案。 – 2012-03-23 16:48:06

+0

我已經採取了一步,並添加了一個池數據源,允許我有效地重用我的jdbc連接。我還向fileToSQL bean添加了一個線程池,允許我執行併發插入。我每秒鐘處理大約9X 5MB的文件到MySQL數據庫中。這是令人印象深刻的,因爲它運行在我的筆記本電腦上,甚至還沒有服務器。不能相信這是多麼容易。 – Namphibian 2012-03-25 08:03:00