001: // Copyright (c) 2003-2007, Jodd Team (jodd.sf.net). All Rights Reserved.
002:
003: package jodd.db.orm;
004:
005: import jodd.db.DbQuery;
006: import jodd.db.DbQueryMode;
007: import jodd.db.DbSession;
008: import jodd.db.orm.sqlgen.DbSqlGenerator;
009: import jodd.db.orm.mapper.DefaultResultSetMapper;
010: import jodd.db.orm.mapper.ResultSetMapper;
011:
012: import java.sql.Connection;
013: import java.util.ArrayList;
014: import java.util.Iterator;
015: import java.util.LinkedHashSet;
016: import java.util.List;
017: import java.util.Set;
018:
019: /**
020: * A simple ORM extension for {@link DbQuery}.
021: * <p>
022: * ORM extension may map results to objects in two ways:
023: * <ul>
024: * <li><i>auto</i> mode - when result set is mapped to provided types, and</li>
025: * <li><i>mapped</i> mode - requires explicit mapping definitions.</li>
026: * </ul>
027: *
028: * <p>
029: * By default, after invocation of listXxx() methods, query are not closed.
030: *
031: */
032: public class DbOrmQuery extends DbQuery {
033:
034: protected DbOrm orm;
035:
036: // ---------------------------------------------------------------- default ctors
037:
038: public DbOrmQuery(Connection conn, String sqlString) {
039: super (conn, sqlString);
040: }
041:
042: public DbOrmQuery(Connection conn, String sqlString,
043: DbQueryMode mode) {
044: super (conn, sqlString, mode);
045: }
046:
047: public DbOrmQuery(DbSession session, String sqlString,
048: DbQueryMode mode) {
049: super (session, sqlString, mode);
050: }
051:
052: public DbOrmQuery(DbSession session, String sqlString) {
053: super (session, sqlString);
054: }
055:
056: public DbOrmQuery(String sqlString, DbQueryMode mode) {
057: super (sqlString, mode);
058: }
059:
060: public DbOrmQuery(String sqlString) {
061: super (sqlString);
062: }
063:
064: @Override
065: protected void init(Connection conn, String sqlString,
066: DbQueryMode mode) {
067: this .orm = DbOrm.getInstance();
068: super .init(conn, sqlString, mode);
069: }
070:
071: // ---------------------------------------------------------------- sqlgen ctors
072:
073: protected DbSqlGenerator sqlgen;
074:
075: public DbOrmQuery(Connection conn, DbSqlGenerator sqlgen) {
076: super (conn, null);
077: this .sqlgen = sqlgen;
078: initDbSqlGen();
079: }
080:
081: public DbOrmQuery(Connection conn, DbSqlGenerator sqlgen,
082: DbQueryMode mode) {
083: super (conn, null, mode);
084: this .sqlgen = sqlgen;
085: initDbSqlGen();
086: }
087:
088: public DbOrmQuery(DbSession session, DbSqlGenerator sqlgen,
089: DbQueryMode mode) {
090: super (session, null, mode);
091: this .sqlgen = sqlgen;
092: initDbSqlGen();
093: }
094:
095: public DbOrmQuery(DbSession session, DbSqlGenerator sqlgen) {
096: super (session, null);
097: this .sqlgen = sqlgen;
098: initDbSqlGen();
099: }
100:
101: public DbOrmQuery(DbSqlGenerator sqlgen, DbQueryMode mode) {
102: super (null, mode);
103: this .sqlgen = sqlgen;
104: initDbSqlGen();
105: }
106:
107: public DbOrmQuery(DbSqlGenerator sqlgen) {
108: super (null);
109: this .sqlgen = sqlgen;
110: initDbSqlGen();
111: }
112:
113: /**
114: * Initializes class when {@link DbSqlGenerator} is used.
115: */
116: protected void initDbSqlGen() {
117: super .init(sqlgen.generateQuery());
118: setParameters(sqlgen.getQueryParameters());
119: }
120:
121: @Override
122: public void reset() {
123: if (isActive()) {
124: closeQuery();
125: }
126: if (this .sqlgen != null) {
127: initDbSqlGen();
128: return;
129: }
130: super .init(connection, sqlString, mode);
131: }
132:
133: // ---------------------------------------------------------------- result set
134:
135: /**
136: * Builds new ResultSet mapper. This method acts as a factory.
137: */
138: public ResultSetMapper buildResultSetMapper() {
139: if (sqlgen != null) {
140: return new DefaultResultSetMapper(execute(), sqlgen
141: .getColumnData(), orm);
142: }
143: return new DefaultResultSetMapper(execute(), orm);
144: }
145:
146: // ---------------------------------------------------------------- iterator
147:
148: public <T> Iterator<T> iterateOne(Class<T> type) {
149: return iterateOne(type, false);
150: }
151:
152: public <T> Iterator<T> iterateOneAndClose(Class<T> type) {
153: return iterateOne(type, true);
154: }
155:
156: protected <T> Iterator<T> iterateOne(Class<T> type, boolean close) {
157: return new DbListOneIterator<T>(this , type, close);
158: }
159:
160: public Iterator<Object[]> iterate(Class... types) {
161: return iterate(types, false);
162: }
163:
164: public Iterator<Object[]> iterateAndClose(Class... types) {
165: return iterate(types, true);
166: }
167:
168: protected Iterator<Object[]> iterate(Class[] types, boolean close) {
169: return new DbListIterator(this , types, close);
170: }
171:
172: // ---------------------------------------------------------------- list
173:
174: public <T> List<T> listOne(Class<T> type) {
175: return listOne(type, false);
176: }
177:
178: public <T> List<T> listOneAndClose(Class<T> type) {
179: return listOne(type, true);
180: }
181:
182: @SuppressWarnings({"unchecked"})
183: protected <T> List<T> listOne(Class<T> type, boolean close) {
184: List<T> result = new ArrayList<T>();
185: ResultSetMapper rsm = buildResultSetMapper();
186: Class[] types = new Class[] { type };
187: while (rsm.next()) {
188: result.add((T) rsm.parseOneObject(types));
189: }
190: close(rsm, close);
191: return result;
192: }
193:
194: public <T> List<T> listOne(DbOrmRelation rel) {
195: List<T> result = new ArrayList<T>();
196: rel.packCollectionOne(this , result);
197: return result;
198: }
199:
200: public List<Object[]> list(Class... types) {
201: return list(types, false);
202: }
203:
204: public List<Object[]> listAndClose(Class... types) {
205: return list(types, true);
206: }
207:
208: protected List<Object[]> list(Class[] types, boolean close) {
209: List<Object[]> result = new ArrayList<Object[]>();
210: ResultSetMapper rsm = buildResultSetMapper();
211: while (rsm.next()) {
212: result.add(rsm.parseObjects(types));
213: }
214: close(rsm, close);
215: return result;
216: }
217:
218: public List<Object[]> list(DbOrmRelation rel) {
219: List<Object[]> result = new ArrayList<Object[]>();
220: rel.packCollectionAll(this , result);
221: return result;
222: }
223:
224: // ---------------------------------------------------------------- set
225:
226: public <T> Set<T> listSetOne(Class<T> type) {
227: return listSetOne(type, false);
228: }
229:
230: public <T> Set<T> listSetOneAndClose(Class<T> type) {
231: return listSetOne(type, true);
232: }
233:
234: @SuppressWarnings({"unchecked"})
235: protected <T> Set<T> listSetOne(Class<T> type, boolean close) {
236: Set<T> result = new LinkedHashSet<T>();
237: ResultSetMapper rsm = buildResultSetMapper();
238: Class[] types = new Class[] { type };
239: while (rsm.next()) {
240: result.add((T) rsm.parseOneObject(types));
241: }
242: close(rsm, close);
243: return result;
244: }
245:
246: public <T> Set<T> listSetOne(DbOrmRelation rel) {
247: Set<T> result = new LinkedHashSet<T>();
248: rel.packCollectionOne(this , result);
249: return result;
250: }
251:
252: public Set<Object[]> listSet(Class... types) {
253: return listSet(types, false);
254: }
255:
256: public Set<Object[]> listSetAndClose(Class... types) {
257: return listSet(types, true);
258: }
259:
260: protected Set<Object[]> listSet(Class[] types, boolean close) {
261: Set<Object[]> result = new LinkedHashSet<Object[]>();
262: ResultSetMapper rsm = buildResultSetMapper();
263: while (rsm.next()) {
264: result.add(rsm.parseObjects(types));
265: }
266: close(rsm, close);
267: return result;
268: }
269:
270: public Set<Object[]> listSet(DbOrmRelation rel) {
271: Set<Object[]> result = new LinkedHashSet<Object[]>();
272: rel.packCollectionAll(this , result);
273: return result;
274: }
275:
276: // ---------------------------------------------------------------- find
277:
278: @SuppressWarnings({"unchecked"})
279: public <T> T findOne(Class<T> type) {
280: return findOne(type, false);
281: }
282:
283: public <T> T findOneAndClose(Class<T> type) {
284: return findOne(type, true);
285: }
286:
287: @SuppressWarnings({"unchecked"})
288: protected <T> T findOne(Class<T> type, boolean close) {
289: setFetchSize(1);
290: ResultSetMapper rsm = buildResultSetMapper();
291: if (rsm.next() == false) {
292: return null;
293: }
294: Class[] types = new Class[] { type };
295: Object result = rsm.parseOneObject(types);
296: close(rsm, close);
297: return (T) result;
298: }
299:
300: @SuppressWarnings({"unchecked"})
301: public <T> T findOne(DbOrmRelation rel) {
302: return (T) rel.packOne(this );
303: }
304:
305: public Object[] find(Class... types) {
306: return find(types, false);
307: }
308:
309: public Object[] findAndClose(Class... types) {
310: return find(types, true);
311: }
312:
313: protected Object[] find(Class[] types, boolean close) {
314: setFetchSize(1);
315: ResultSetMapper rsm = buildResultSetMapper();
316: if (rsm.next() == false) {
317: return null;
318: }
319: Object[] result = rsm.parseObjects(types);
320: close(rsm, close);
321: return result;
322: }
323:
324: @SuppressWarnings({"unchecked"})
325: public Object[] find(DbOrmRelation rel) {
326: return rel.packAll(this );
327: }
328:
329: // ---------------------------------------------------------------- util
330:
331: /**
332: * Closes results set or whole query.
333: */
334: protected void close(ResultSetMapper rsm, boolean closeQuery) {
335: if (closeQuery == true) {
336: close();
337: } else {
338: close(rsm.getResultSet());
339: }
340: }
341:
342: }
|