2010-05-20 15 views
7

Sto provando a generare alcuni file sql nella mia applicazione java. L'applicazione sarà non eseguire qualsiasi istruzione SQL, solo generare un file con istruzioni SQL e salvarlo.Java: preparazione di una dichiarazione senza connessione

Mi piacerebbe utilizzare lo java.sql.PreparedStatement per creare le mie istruzioni in modo che non debba convalidare ogni stringa ecc. Con i miei metodi.

C'è un modo per utilizzare il PreparedStatement senza la chiamata java.sql.Connection.prepareStatement(String), perché non ho un java.sql.Connection?

risposta

3

Sto indovinando che fino a quando non hai una connessione SQL, il parser non si sa cosa si applicano le regole. Sto indovinando che in realtà è il driver SQL o anche il server che sta compilando la dichiarazione SQL.

Supponendo che il tuo sql sia abbastanza semplice, allora che ne dici di utilizzare una connessione a basso costo, come ad esempio una connessione sqlite.

SQLite creerà immediatamente un nuovo database se il database a cui si sta tentando di connettersi non esiste.

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

Quindi, come posso creare una connessione senza qualcosa a cui connettermi? – r3zn1k

+0

sqlite creerà un nuovo database per te se non esiste - ha aggiunto un frammento di codice prova – blissapp

+0

, appena appreso che i database SQLite possono essere creati solo con la stringa di connessione "jdbc: sqlite :: memoria:" – blissapp

0

Provare a implementare PreparedStatement.

Esempio: class YourOwnClass implementa PreparedStatement {

// 1. Non implementare tutti i metodi, 2. Ottenere la logica minima di implementare da OraclePreparedStatement (classes12.jar) o sun.jdbc.odbc.JdbcOdbcCallableStatement

}

+0

Usare semplicemente espressioni regolari o qualcosa del genere sarebbe molto più semplice ... – r3zn1k

+0

@ r3zn1k: Il vantaggio di implementare questo è che il codice è quindi riutilizzabile: può generare testo SQL o eseguire direttamente l'SQL. Tuttavia non sarei sorpreso se non avessi bisogno di quella flessibilità. :) –

0

questo è un problema subdolo vile, grazie completamente è abbastanza facile da affrontare:

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

da usare, basta scrivere una classe anonima che sostituisce vuoto 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! Ora hai un modo di lavorare con un PreparedStatement senza averlo ancora creato. Ecco un esempio che mostra il testo standard minimo si sarebbe altrimenti necessario copiare incollare al regno, ogni volta che si voleva scrivere una dichiarazione diversa:

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

Davvero davvero non si vuole essere la copia incolla che ovunque, Fai?