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