KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > teamkonzept > db > TKPrepQuery


1 package com.teamkonzept.db;
2
3 import java.sql.*;
4 import java.io.StringReader JavaDoc;
5 import com.teamkonzept.lib.*;
6
7 /** Abstrakte Klasse, zur Erstellung präparierter Queries.
8  * Eine solche Query zeichnet sich durch eine feste Anzahl von
9  * Query-Parametern und deren Reihenfolge aus.
10  *
11  * @see java.sql.PreparedStatement
12  * @author $Author: alex $
13  * @version $Revision: 1.20 $
14  */

15 public abstract class TKPrepQuery extends TKQuery implements QueryConstants {
16
17     /**
18         If true, queries are cached untill they are closeed.
19         This can be neccessary for teansactions.
20         It can cause "memory-leak" if queries are not closed.
21
22         @see TKDBManager.closeNonsensitiveQueries(), to close all the cached queries.
23     */

24     public static boolean REGISTER_QUERY = false;
25
26     /**
27         If true, queries are cached for reuse.
28     */

29     public static boolean REUSE_QUERY = false;
30
31         /** Reihenfole der Queryparameter
32          */

33     protected String JavaDoc[] paramOrder;
34
35
36     /** Name der Query Klasse, erleichtert die Wiederverwendung von PrepQueries ( wird nicht verwendet )
37      */

38     private Object JavaDoc queryID;
39
40
41     /** Methode zur Initialisierung der Query.
42      * Diese Methode wird üblicherweise vom DB-Manager aufgerufen,
43      * um die Query zu initialisieren.
44      *
45      * @param tkConn - Verbindung zu der DB
46      * @param conv - Der der DB zugeordnete Typ-Konverter
47      * @param queryID Name der Query Klasse, erleichtert die Wiederverwendung des Objektes ( wird nicht verwendet )
48      *
49      * @see com.teamkonzept.db.TKDBManager
50      * @see com.teamkonzept.db.TKDBManager#newQuery
51      */

52     public void initQuery( final TKSQLTypeConverter conv, final TKDBConnection tkConn, Object JavaDoc queryID)
53     {
54         this.queryID = queryID;
55         this.aTKDBConnection = tkConn;
56         initQuery( tkConn.getConnection() );
57     }
58
59     /** Methode zur Initialisierung des Queryobjektes
60      *
61      * @param conn - Verbindung zur DB
62      * @param isPrepared - wird nicht mehr benötigt
63      * @param paramOrder - Liste mit Parameternamen, welche die
64      * Reihenfolge der Parameter im SQL-String
65      * angibt.
66      * @param paramTypes - Liste von Parametername, Parametertyp Paaren
67      * @param setRelevants - geordnete Liste, welche angibt, welche
68      * SQl(Teil)Queries relevante ResultSets liefern.
69      * @param sqlString - Dem der Query zugrundeliegende SQL-String.
70      *
71      */

72     public void initQuery( final Connection conn,
73                            final boolean isPrepared, /* wird nicht mehr benˆtigt */
74                            final String JavaDoc[] paramOrder,
75                            final Object JavaDoc[][] paramTypes,
76                            final boolean[] setRelevants,
77                            final String JavaDoc sqlString )
78     {
79         super.initQuery( conn, paramTypes, setRelevants );
80
81         this.paramOrder = paramOrder;
82         this.sqlString = sqlString;
83
84         if ( sqlString == null ) {
85             return;
86         }
87
88         try {
89             stmt = conn.prepareStatement(sqlString);
90         } catch (SQLException sqle) {
91             printSqlException(sqle, "Create Statement");
92         }
93     }
94
95     /** Methode, um die Query auszuführen
96      *
97      * @return true, falls die Query ein java.sql.ResultSet geliefert hat,
98      * false, falls das Resultat der Query ein "Update Count" ist
99      * oder leer ist.
100      *
101      * @exception com.teamkonzept.db.TKSQLError
102      */

103
104
105     /**
106      * @return ob ResultSet vorhanden
107      */

108     public boolean execute() throws SQLException
109     {
110         if(REGISTER_QUERY)deregisterIndex = registerQuery();
111         final PreparedStatement pstmt = (PreparedStatement) stmt;
112         boolean isAuto = aTKDBConnection.isAutoCommit(); // (isAuto == true) <=> Multistatement Transaction
113

114         if (CAT.isDebugEnabled() ) {
115             CAT.debug("isaAuto Value during execute: "+ isAuto );
116             CAT.debug("executing " + this );
117             CAT.debug("<BR>SQL:" + sqlString + "<BR>");
118             CAT.debug("PARAMS:" + queryParams + "<BR>");
119             CAT.debug("paramOrder" + paramOrder);
120         }
121
122         try {
123             pstmt.clearParameters();
124         } catch (SQLException sqle) {
125             if( isAuto) TKDBManager.closeConnection();
126             printSqlException(sqle, "clear Parameters");
127
128         }
129
130         try {
131             if (paramOrder != null) {
132                 for(int i=0; i < paramOrder.length; i++) {
133                     final Object JavaDoc h = queryParams.get(paramOrder[i]);
134                     if ((h==null) || (h instanceof TKNull)) {
135                         int ht;
136                         Object JavaDoc paramType = null;
137                         if( paramTypes != null ){
138                             paramType = paramTypes.get(paramOrder[i]);
139                         }
140                         if ( paramType != null ){
141                             ht = ((Integer JavaDoc)paramType).intValue();
142                         } else {
143                             ht = Types.INTEGER;
144                         }
145                         pstmt.setNull(i+1, ht);
146                     } else {
147                         if (paramTypes !=null)
148                         {
149                             Integer JavaDoc type = (Integer JavaDoc)paramTypes.get(paramOrder[i]);
150                             if (type != null && type.intValue() == Types.CLOB && TKDBManager.getDBVendor() == QueryConstants.ORACLE)
151                             {
152                                 // wir setzen hier ein DUMMY Objekt !!!
153
// der CLOB MUSS spaeter manuell nachgepflegt werden !!!!!
154
// System.out.println("Setze CLOB ! Laenge : " + ((String)h).length());
155
pstmt.setObject(i+1," ");
156                             }
157                             else
158                                 pstmt.setObject(i+1,h);
159                         }
160                         else
161                             pstmt.setObject(i+1,h);
162                     }
163                 }
164             }
165         } catch(SQLException sqle) {
166             if (isAuto) TKDBManager.closeConnection();
167             printSqlException(sqle, "setObject");
168
169         }
170
171         try {
172             currIsResultSet = pstmt.execute();
173         } catch (SQLException sqle) {
174              if (isAuto) TKDBManager.closeConnection();
175             printSqlException(sqle, "Execute Prepared Statement");
176         }
177         queryParams.clear();
178         currPos = 0;
179
180
181         return currIsResultSet;
182     }
183
184
185
186
187
188     /** Das PreparedStatement wird nicht geschlossen!
189      * Es werden lediglich die Results "abgeholt",
190      * damit das Statement vollst‰ndig abgearbeitet ist.
191      * Ausserdem wird das Objekt zum Wiederverwenden
192      * abgelegt.
193      *
194      * @exception java.sql.SQLException
195      */

196     public void specClose() throws SQLException{
197         if(REGISTER_QUERY)deregisterQuery();
198
199         if ( stmt != null ) {
200             throwawayResults();
201         }
202         if(REUSE_QUERY)
203         {
204             aTKDBConnection.storePrepQuery(this, queryID);
205         }
206         else // explicitly close statement
207
{
208             if (stmt != null)
209             {
210                 stmt.close();
211             }
212         }
213     }
214
215     /**
216         for debugging
217     */

218     public Statement getStatement(){
219         return stmt;
220     }
221
222     /**
223         @author marwan 14. 5. 01
224
225         This is a hack!
226
227         Calling this method assures two things:
228
229         1. All subsequently instantiated TKQuery objects of this Connection, will be cached until
230         TKDBConnection.closeNonsensitiveQueries() is called.
231         The call of closeNonsensitiveQueries() closes the Statement of each of these TKQueries,
232         and empties the cache.
233
234         2. These TKQuery objects will not be reused.
235
236         It is a hack, as the caching mechanism was originally designed to keep track of queries
237         that are executed togeather in a transaction.
238
239     */

240     public static void enableCleanup(){
241         REGISTER_QUERY = true;
242         REUSE_QUERY = true;
243
244     }
245
246
247     /**
248         @see enableCleanup(), disableCleanup()
249     */

250     public static void enableCleanup(boolean yes){
251         if(yes){
252             enableCleanup();
253         }
254         else{
255             disableCleanup();
256         }
257     }
258
259     /**
260         @see enableCleanup()
261
262         Restores the default conditions after a call to enableCleanup()
263         (E.g. in the Webman Generation process, where no periodical calls to closeNonsensitiveQueries()
264         are possible)
265     */

266     public static void disableCleanup(){
267         REGISTER_QUERY = false;
268         REUSE_QUERY = true;
269
270     }
271
272 }
273
274
Popular Tags