2010-05-20 44 views
7

我想在我的Java應用程序中生成一些sql文件。 應用程序將而不是執行任何sql語句,只需用sql語句生成一個文件並保存它。Java:準備沒有連接的語句

我想使用java.sql.PreparedStatement來創建我的語句,這樣我就不必使用自己的方法來驗證每個字符串等。

有沒有辦法使用PreparedStatement沒有調用java.sql.Connection.prepareStatement(String)函數,因爲我沒有java.sql.Connection

回答

3
+0

這個庫導入不包括在內的包「com.healthmarketscience.common.util」... – r3zn1k 2010-05-20 14:02:25

+0

你必須有一點點:http://openhms.sourceforge.net/common-util/ – PeterMmm 2010-05-20 14:32:41

+0

最佳解決方案非常感謝! – r3zn1k 2010-05-25 07:10:13

3

我猜測,直到你已經有了一個SQL連接,解析器會不知道如何應用規則。我猜測它實際上是SQL驅動程序,甚至是編譯sql語句的服務器。

假設你的sql很簡單,那麼如何使用廉價的連接,比如說一個sqlite連接。

如果您試圖連接的數據庫不存在,SQLite將立即創建一個新的數據庫。

public Connection connectToDatabase() { 

// connect to the database (creates new if not found) 
try { 
    Class.forName("org.sqlite.JDBC"); 
    conn = DriverManager.getConnection("jdbc:sqlite:mydatabase.db"); 

    // initialise the tables if necessary 
    this.createDatabase(conn); 
} 
catch (java.lang.ClassNotFoundException e) { 
    System.out.println(e.getMessage()); 
} 
catch (java.sql.SQLException e) { 
    System.out.println(e.getMessage()); 
} 

return conn; 

} 
+0

那麼,如何創建一個沒有連接的連接? – r3zn1k 2010-05-20 12:42:38

+0

sqlite會爲你創建一個新的數據庫,如果它不存在 - 增加了概念證明代碼片段 – blissapp 2010-05-20 13:43:27

+0

更新,剛剛得知SQLite數據庫可以在內存中創建只有連接字符串「jdbc:sqlite :: memory:」 – blissapp 2010-06-02 18:51:37

0

嘗試實施PreparedStatement。

實施例:類YourOwnClass實現的PreparedStatement {

// 1.不要執行所有方法, 2.獲取最小邏輯從OraclePreparedStatement(classes12.jar)或 sun.jdbc.odbc.JdbcOdbcCallableStatement實施

}

+0

使用正則表達式或類似的東西會容易得多... – r3zn1k 2010-05-20 12:44:11

+0

@ r3zn1k:實現這一點的優點是代碼可以重用:它可以生成文本SQL或直接執行SQL。不過,如果你不需要這種靈活性,我不會感到驚訝。 :) – 2010-05-20 12:58:03

0

這是一個卑鄙狡猾的問題,謝謝完全它很容易應付:

public class PreparedStatementBuilder 
{ 
    private String sql; // the sql to be executed 

    public PreparedStatementBuilder(final String sql) { this.sql = sql; } 

    protected void preparePrepared(final PreparedStatement preparedStatement) 
      throws SQLException 
    { 
     // this virtual method lets us declare how, when we do generate our 
     // PreparedStatement, we want it to be setup. 

     // note that at the time this method is overridden, the 
     // PreparedStatement has not yet been created. 
    } 

    public PreparedStatement build(final Connection conn) 
      throws SQLException 
    { 
     // fetch the PreparedStatement 
     final PreparedStatement returnable = conn.prepareStatement(sql); 
     // perform our setup directives 
     preparePrepared(returnable); 
     return returnable; 
    } 
} 

要使用,只寫一個匿名類中的覆蓋空洞preparePrepared(PreparedStatement的):

final String sql = "SELECT * FROM FOO WHERE USER = ?"; 
    PreparedStatementBuilder psBuilder = new PreparedStatementBuilder(sql){ 
     @Override 
     protected void preparePrepared(PreparedStatement preparedStatement) 
      throws SQLException 
     { 
      preparedStatement.setString(1, "randal"); 
     }}; 
    return obtainResultSet(psBuilder); 

的Presto!您現在可以使用PreparedStatement進行工作,但尚未構建它。下面是顯示的最小樣板,否則你不得不復制粘貼到國降臨爲例,每次你需要時間來寫不同的說法:

public ResultSet obtainResultSet(final PreparedStatementBuilder builder) 
     throws SQLException { 
    final Connection conn = this.connectionSource.getConnection(); 
    try 
    { 
     // your "virtual" preparePrepared is called here, doing the work 
     // you've laid out for your PreparedStatement now that it's time 
     // to actually build it. 
     return builder.build(conn).executeQuery(); 
    } 
    finally 
    { 
     try { conn.close(); } 
     catch (SQLException e) { log.error("f7u12!", e); } 
    } 
} 

你真的真的不希望複製粘貼到處都有,你做?