KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > jdbc > StatementCache


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package scriptella.jdbc;
17
18 import scriptella.util.IOUtils;
19 import scriptella.util.LRUMap;
20
21 import java.io.Closeable JavaDoc;
22 import java.sql.Connection JavaDoc;
23 import java.sql.SQLException JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27 /**
28  * Statements cache for {@link JdbcConnection}.
29  *
30  * @author Fyodor Kupolov
31  * @version 1.0
32  */

33 class StatementCache implements Closeable JavaDoc {
34     private Map<String JavaDoc, StatementWrapper> map;
35     private final Connection JavaDoc connection;
36
37     /**
38      * Creates a statement cache for specified connection.
39      * @param connection connection to create cache for.
40      * @param size cache size, 0 or negative means disable cache.
41      */

42     public StatementCache(Connection JavaDoc connection, final int size) {
43         this.connection = connection;
44         if (size > 0) { //if cache is enabled
45
map = new LRUMap<String JavaDoc, StatementWrapper>(size) {
46                 protected void onEldestEntryRemove(Map.Entry<String JavaDoc, StatementWrapper> eldest) {
47                     eldest.getValue().close();
48                 }
49             };
50         }
51     }
52
53     /**
54      * Prepares a statement.
55      * <p>The sql is used as a key to lookup a {@link StatementWrapper},
56      * if cache miss the statement is created and put to cache.
57      *
58      * @param sql statement SQL.
59      * @param params parameters for SQL.
60      * @param converter types converter to use.
61      * @return a wrapper for specified SQL.
62      * @throws SQLException
63      * @see StatementWrapper
64      */

65     public StatementWrapper prepare(final String JavaDoc sql, final List JavaDoc<Object JavaDoc> params, final JdbcTypesConverter converter) throws SQLException JavaDoc {
66         StatementWrapper sw = map == null ? null : map.get(sql);
67
68         if (sw == null) { //If not cached
69
if (params==null || params.isEmpty()) {
70                 sw = create(sql, converter);
71             } else {
72                 sw = prepare(sql, converter);
73             }
74             put(sql, sw);
75         } else if (sw instanceof StatementWrapper.Simple) {
76             //If simple statement is obtained second time - use prepared to improve performance
77
sw.close(); //closing unused statement
78
put(sql, sw = prepare(sql, converter));
79         }
80         sw.setParameters(params);
81         return sw;
82     }
83
84     /**
85      * Testable template method to create simple statement
86      */

87     protected StatementWrapper.Simple create(final String JavaDoc sql, final JdbcTypesConverter converter) throws SQLException JavaDoc {
88         return new StatementWrapper.Simple(connection.createStatement(), sql, converter);
89     }
90
91     /**
92      * Testable template method to create prepared statement
93      */

94     protected StatementWrapper.Prepared prepare(final String JavaDoc sql, final JdbcTypesConverter converter) throws SQLException JavaDoc {
95         return new StatementWrapper.Prepared(connection.prepareStatement(sql), converter);
96     }
97
98
99     private void put(String JavaDoc key, StatementWrapper entry) {
100         if (map != null) {
101             map.put(key, entry);
102         }
103     }
104
105     /**
106      * Notifies cache that specified statement is no longer in use.
107      * Close method is invoked on statements pending release after removing from cache.
108      *
109      * @param sw released statement.
110      */

111     public void releaseStatement(StatementWrapper sw) {
112         if (sw == null) {
113             throw new IllegalArgumentException JavaDoc("Released statement cannot be null");
114         }
115         //if caching disabled or simple statement - close it
116
if (map == null) {
117             sw.close();
118         } else {
119             sw.clear();
120         }
121     }
122
123     public void close() {
124         if (map != null) {
125             //closing statements
126
IOUtils.closeSilently(map.values());
127             map = null;
128         }
129     }
130
131 }
132
Popular Tags