Show
Ignore:
Timestamp:
02/25/10 20:57:30 (2 years ago)
Author:
martijn
Message:

refactor LazyPst? to also handle resultset and connection

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/org.bridgedb.rdb/src/org/bridgedb/rdb/SimpleGdb.java

    r308 r316  
    1717package org.bridgedb.rdb; 
    1818 
     19import java.io.PrintWriter; 
    1920import java.sql.Connection; 
    2021import java.sql.PreparedStatement; 
     
    6162        } 
    6263         
    63         /** 
    64          * helper class that handles lazy initialization of all prepared statements used by SimpleGdb 
    65          * Non-static, because it needs the con database connection field. 
    66          */ 
    67         protected final class LazyPst 
     64        private boolean keepConnection = true; 
     65 
     66        /** 
     67         * helper class that handles the life cycle of a connection, query and resultset. 
     68         * <p> 
     69         * The sql for a query is passed in at construction time. 
     70         * Before each query, call init(). This will lead to lazy initialization of the 
     71         * connection and preparedstatement objects, if necessary. Set the query parameters 
     72         * using setString(int, String). Get the resultSet using  
     73         * Do not close the resultset! This will be closed for you when you call cleanup(). 
     74         * Always call cleanup() in a finally block. 
     75         * <p> 
     76         * The advantages of using QueryLifeCycle are: 
     77         * <ul> 
     78         * <li>guarantee to close preparedstatement, resultset and connection if necessary. 
     79         * <li>in case of connection pooling, preparedstatement and connection are kept together as long 
     80         *   as possible. 
     81         * <li>lazy initialization of prepared statement 
     82         * <li>always uses preparedstatement, so safe from SQL injection. 
     83         * </ul>  
     84         * <p> 
     85         * This class is not static because it needs SimpleGdb.getConnection(). 
     86         */ 
     87        final class QueryLifeCycle 
    6888        { 
    6989                /** 
     
    7292                 * @param aSql SQL query 
    7393                 */ 
    74                 public LazyPst(String aSql) 
     94                public QueryLifeCycle(String aSql) 
    7595                { 
    7696                        sql = aSql; 
    7797                } 
    7898                 
     99                private Connection con = null; 
     100                private ResultSet rs = null; 
    79101                private PreparedStatement pst = null; 
    80102                private final String sql; 
     103                private boolean inited = false; 
     104 
     105                public static final int QUERY_TIMEOUT = 20; //seconds 
     106                public static final int NO_LIMIT = 0; 
     107                public static final int NO_TIMEOUT = 0; 
     108 
     109                public void init(int limit) throws SQLException 
     110                { 
     111                        init(); 
     112                        pst.setQueryTimeout(QUERY_TIMEOUT);                      
     113                        if(limit > NO_LIMIT)  
     114                        { 
     115                                pst.setMaxRows(limit); 
     116                        } 
     117                } 
    81118                 
    82119                /** 
    83                  * Get a PreparedStatement using lazy initialization. 
     120                 * Initialize connection and PreparedStatement lazily. 
    84121                 * <p> 
    85                  * Assumes SimpleGdbImpl2.con is already valid 
    86                  * @return a prepared statement for the given query. 
    87122                 * @throws SQLException when a PreparedStatement could not be created 
    88123                 */ 
    89                 public PreparedStatement getPreparedStatement() throws SQLException 
    90                 { 
    91                         if (pst == null) 
     124                public void init() throws SQLException 
     125                { 
     126                        if (inited) throw new IllegalStateException("Must call cleanup() between two init() calls"); 
     127                        try 
    92128                        { 
    93                                 pst = con.prepareStatement(sql); 
     129                                if (con == null) con = getConnection(); 
     130                                if (pst == null) 
     131                                { 
     132                                        pst = con.prepareStatement(sql); 
     133                                } 
    94134                        } 
    95                         return pst; 
    96                 } 
    97         } 
    98  
     135                        finally { inited = true; } 
     136                } 
     137                 
     138                public void setString (int index, String val) throws SQLException 
     139                { 
     140                        if (!inited) throw new IllegalStateException("Must call init() before setString()"); 
     141                        pst.setString(index, val); 
     142                } 
     143                 
     144                public ResultSet executeQuery() throws SQLException 
     145                { 
     146                        if (!inited) throw new IllegalStateException("Must call init() before executeQuery()"); 
     147                        rs = pst.executeQuery(); 
     148                        return rs; 
     149                } 
     150 
     151                /**  
     152                 * Clean up resultset. If keepConnection is false, preparedstatement 
     153                 * and connection are cached. If keepConnection is true, they are closed as well. 
     154                 * The later is useful when using connection pooling. 
     155                 * <p> 
     156                 * Always call this in a finally block!  
     157                 * */ 
     158                public void cleanup() 
     159                { 
     160                        if (!inited) throw new IllegalStateException("Must call init() before cleanup()"); 
     161                        inited = false; 
     162                        if (rs != null) try { rs.close(); } catch (SQLException ignore) {} 
     163                        if (keepConnection) return; 
     164                        if (pst != null) try { pst.close(); } catch (SQLException ignore) {} 
     165                        if (con != null) try { con.close(); } catch (SQLException ignore) {} 
     166                } 
     167        } 
     168         
     169        protected Connection getConnection() throws SQLException 
     170        { 
     171                return con; 
     172        } 
     173         
    99174        /** 
    100175         * The {@link Connection} to the Gene Database.