Repository: empire-db Updated Branches: refs/heads/master c6f638498 -> 11ff2d595
- custom DBReader and DBRecord classes added to EmpireTemplate - EmpireDaoSupport now extends DaoSupport - comments added to EmpireTemplate and callback classes - corrected example spring config Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/11ff2d59 Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/11ff2d59 Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/11ff2d59 Branch: refs/heads/master Commit: 11ff2d595cf47842bcd078b7ba0e3219243a99e3 Parents: c6f6384 Author: inemeth <[email protected]> Authored: Sun Oct 25 09:12:28 2015 +0100 Committer: inemeth <[email protected]> Committed: Sun Oct 25 09:12:28 2015 +0100 ---------------------------------------------------------------------- .../apache/empire/spring/DBReaderExtractor.java | 19 + .../empire/spring/DBRecordCallbackHandler.java | 18 +- .../apache/empire/spring/DBRecordMapper.java | 2 + .../apache/empire/spring/EmpireDaoSupport.java | 82 ++- .../apache/empire/spring/EmpireTemplate.java | 504 ++++++++++++++++++- .../resources/example1/applicationContext.xml | 15 +- .../example2/applicationContext-employee.xml | 6 +- 7 files changed, 586 insertions(+), 60 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/java/org/apache/empire/spring/DBReaderExtractor.java ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/DBReaderExtractor.java b/empire-db-spring/src/main/java/org/apache/empire/spring/DBReaderExtractor.java index 03626ae..78e9154 100644 --- a/empire-db-spring/src/main/java/org/apache/empire/spring/DBReaderExtractor.java +++ b/empire-db-spring/src/main/java/org/apache/empire/spring/DBReaderExtractor.java @@ -20,8 +20,27 @@ package org.apache.empire.spring; import org.apache.empire.db.DBReader; +/** + * Callback interface to use with {@link EmpireTemplate}'s query methods. + * Implementations of this interface perform the actual work of extracting + * results from a {@link DBReader}. + * + * This class is the Empire equivalent of Spring's + * {@link org.springframework.jdbc.core.ResultSetExtractor}. + */ + public interface DBReaderExtractor<K> { + /** + * Implementations must implement this method to process the entire + * DBReader. Unlike DBRecordMapper and DBRecordCallbackHandler it's the + * developer's response to iterate through the reader calling reader.next(); + * + * @param reader + * to process + * @return the result object, can be null + */ + K process(DBReader reader); } http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordCallbackHandler.java ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordCallbackHandler.java b/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordCallbackHandler.java index ec51d1f..aa0a318 100644 --- a/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordCallbackHandler.java +++ b/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordCallbackHandler.java @@ -22,27 +22,23 @@ import org.apache.empire.db.DBRecordData; /** * An interface used by {@link EmpireTemplate} for processing a DBRecordData or - * rows of a DBReader on a per-row basis. + * rows of a DBReader on a per-row basis. DbRecordCallbackHandler object is + * typically stateful: It keeps the result state within the object, to be + * available for later inspection. * + * This class is the Empire equivalent of Spring's + * {@link org.springframework.jdbc.core.RowCallbackHandler}. * - * - * DbRecordCallbackHandler object is typically stateful: It keeps the result - * state within the object, to be available for later inspection. - * - * If you need to map exactly one object to each row from a DBReader consider - * using a {@link DbRecordDataMapper}. - * - * */ public interface DBRecordCallbackHandler { /** * Implementations must implement this method to process a DBRecordData. - * + * * @param record */ - + void processRow(DBRecordData record); } http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordMapper.java ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordMapper.java b/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordMapper.java index 4d96434..1a58bc6 100644 --- a/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordMapper.java +++ b/empire-db-spring/src/main/java/org/apache/empire/spring/DBRecordMapper.java @@ -27,6 +27,8 @@ import org.apache.empire.db.DBRecordData; * Typically it can be used to extract data from a DBReader, but without * iterating over it, it is handled by EmpireTemplate. * + * This class is the Empire equivalent of Spring's + * {@link org.springframework.jdbc.core.RowMapper}. * */ http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java index 387d004..a1f9079 100644 --- a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java +++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java @@ -21,30 +21,42 @@ package org.apache.empire.spring; import java.sql.Connection; import java.sql.SQLException; +import javax.sql.DataSource; + import org.apache.empire.db.DBDatabase; import org.apache.empire.db.DBDatabaseDriver; import org.springframework.dao.DataAccessException; +import org.springframework.dao.support.DaoSupport; +import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.ConnectionCallback; -import org.springframework.jdbc.core.support.JdbcDaoSupport; -import org.springframework.util.Assert; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.DataSourceUtils; -public abstract class EmpireDaoSupport extends JdbcDaoSupport { +public abstract class EmpireDaoSupport extends DaoSupport { private EmpireTemplate empireTemplate; private DBDatabase database; private DBDatabaseDriver driver; - - public void setDriver(DBDatabaseDriver driver) { this.driver = driver; } - protected EmpireTemplate getEmpireTemplate() { + @Override + protected final void checkDaoConfig() throws IllegalArgumentException { if (this.empireTemplate == null) { - this.empireTemplate = new EmpireTemplate(); - this.empireTemplate.setJdbcTemplate(getJdbcTemplate()); + throw new IllegalArgumentException( + "Either empireTemplate or jdbcTemplate or dataSource must be set"); + } + if (this.database == null) { + throw new IllegalArgumentException("DBDatabase must be set"); } + if (!this.database.isOpen() && this.driver == null) { + throw new RuntimeException("Database isn't open and no driver set."); + } + } + + protected EmpireTemplate getEmpireTemplate() { return this.empireTemplate; } @@ -52,40 +64,68 @@ public abstract class EmpireDaoSupport extends JdbcDaoSupport { this.empireTemplate = empireTemplate; } - protected void initEmpireDao(){ + public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { + this.empireTemplate = new EmpireTemplate(); + this.empireTemplate.setJdbcTemplate(jdbcTemplate); + this.empireTemplate.afterPropertiesSet(); + } + + public void setDataSource(DataSource dataSource) { + this.empireTemplate = new EmpireTemplate(); + this.empireTemplate.setDataSource(dataSource); + this.empireTemplate.afterPropertiesSet(); + } + + protected JdbcTemplate getJdbcTemplate() { + return this.empireTemplate.getJdbcTemplate(); + } + + protected void initEmpireDao() { } @Override protected final void initDao() throws Exception { super.initDao(); - if (!this.database.isOpen() && this.driver == null){ - throw new RuntimeException("Database isn't open and no driver set."); - } this.initEmpireDao(); - } - public void setDatabase(DBDatabase database){ - if (this.database != null){ - Assert.isTrue(this.database == database, "setting different database not allowed"); + public void setDatabase(DBDatabase database) { + if (this.database != null && this.database != database) { + throw new IllegalArgumentException( + "setting different database not allowed"); } this.database = database; } - + @SuppressWarnings("unchecked") - public <T extends DBDatabase> T getDatabase(){ - if (!this.database.isOpen()){ + public <T extends DBDatabase> T getDatabase() { + if (!this.database.isOpen()) { getJdbcTemplate().execute(new ConnectionCallback<Object>() { public Object doInConnection(Connection con) throws SQLException, DataAccessException { - EmpireDaoSupport.this.database.open(driver, getConnection()); + EmpireDaoSupport.this.database.open(driver, con); return null; } }); - + } return (T) this.database; } + public final DataSource getDataSource() { + + return (this.empireTemplate != null ? this.empireTemplate + .getJdbcTemplate().getDataSource() : null); + } + + protected final Connection getConnection() + throws CannotGetJdbcConnectionException { + return DataSourceUtils.getConnection(getDataSource()); + } + + protected final void releaseConnection(Connection con) { + DataSourceUtils.releaseConnection(con, getDataSource()); + } + } http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java index 5bc96d1..a0fac01 100644 --- a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java +++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java @@ -34,17 +34,129 @@ import org.apache.empire.db.DBRecordData; import org.apache.empire.db.DBRowSet; import org.apache.empire.db.DBTable; import org.apache.empire.db.exceptions.RecordNotFoundException; +import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.ObjectFactory; import org.springframework.dao.DataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.Assert; +/** + * This class simplifies database access methods with Empire. Database queries + * are executed with the help of callback interfaces, while hides connection + * handling from the developer. Only the query logic has to be implemented and + * leave getting and releasing the connection to the template. + * + * Some methods (delete, update) delegates to DBRecord, DBDatabase and DBCommand + * methods while hiding connection handling from developers. + * + * This class is working with a wrapped JdbcTemplate, so either jdbcTemplate or + * dataSource must be set. + * + * Allows customization of creating DBReader and DBRecord instances through + * ObjectFactories. + * + * This class is based on {@link org.springframework.jdbc.core.JdbcTemplate}. + * + * + */ + public class EmpireTemplate implements InitializingBean { + /** Wrapped JdbcTemplate instance */ private JdbcTemplate jdbcTemplate; + /** Factory to create a new DBReader instance, by default returns DBReader */ + private ObjectFactory<DBReader> readerFactory = new ObjectFactory<DBReader>() { + + @Override + public DBReader getObject() throws BeansException { + return new DBReader(); + } + + }; + + /** Factory to create a new DBRecord instance, by default returns DBRecord */ + private ObjectFactory<DBRecord> recordFactory = new ObjectFactory<DBRecord>() { + + @Override + public DBRecord getObject() throws BeansException { + return new DBRecord(); + } + + }; + + /** Default constructor */ + public EmpireTemplate() { + super(); + } + + /** + * Setting a custom ObjectFactory to allow custom DBRecord create with + * newRecord(). + * + * @param recordFactory + */ + + public void setDBRecordFactory(ObjectFactory<DBRecord> recordFactory) { + this.recordFactory = recordFactory; + } + + /** + * Setting a custom DBRecord class to use in newRecord(). + * + * @param recordClass + * the class which extends DBRecord.class + */ + public void setDBRecordClass(final Class<? extends DBRecord> recordClass) { + this.recordFactory = new ObjectFactory<DBRecord>() { + + @Override + public DBRecord getObject() throws BeansException { + try { + return recordClass.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }; + } + + /** + * Setting a custom ObjectFactory to allow custom DBReaders to use in + * queries. + * + * @param readerFactory + */ + + public void setDBReaderFactory(ObjectFactory<DBReader> readerFactory) { + this.readerFactory = readerFactory; + } + + /** + * Setting a custom DBReader class to use in queries. + * + * @param readerClass + * the class which extends DBReader.class + */ + public void setDBReaderClass(final Class<? extends DBReader> readerClass) { + this.readerFactory = new ObjectFactory<DBReader>() { + + @Override + public DBReader getObject() throws BeansException { + try { + return readerClass.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }; + } + + /** Setting the wrapped JdbcTemplate */ public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @@ -53,6 +165,7 @@ public class EmpireTemplate implements InitializingBean { return this.jdbcTemplate; } + /** Setting the datasource */ public final void setDataSource(DataSource dataSource) { if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) { @@ -61,20 +174,59 @@ public class EmpireTemplate implements InitializingBean { } } - public void afterPropertiesSet() throws Exception { + public void afterPropertiesSet() { if (getJdbcTemplate() == null) { throw new IllegalArgumentException( - "Property 'jdbcTemplate' is required"); + "Property 'jdbcTemplate' is required, either jdbcTemplate or dataSource must be set."); } } + /** + * Executes a given DBCommand, mapping each row to a Java object via a + * DBRecordMapper. + * + * @param cmd + * the DBCommand to execute + * @param recordMapper + * the mapper which maps each DBRecordData to a Java object + * @return the extracted list + */ public <K> List<K> query(final DBCommand cmd, - final DBRecordMapper<K> dataReader) { - return query(cmd, new DbRecordMapperExtractor<K>(dataReader)); + final DBRecordMapper<K> recordMapper) { + return query(cmd, new DbRecordMapperExtractor<K>(recordMapper)); + + } + + /** + * Executes a given DBCommand, mapping a single row to a Java object using + * the provided DBRecordMapper. + * + * @param cmd + * the DBCommand to execute + * @param recordMapper + * the DBRecordMapper to map + * @return the single Object + * @throws IncorrectResultSizeDataAccessException + * if more than one result object has been found + */ + public <K> K queryForObject(final DBCommand cmd, + final DBRecordMapper<K> recordMapper) { + + return DataAccessUtils.uniqueResult(query(cmd, recordMapper)); } + /** + * Executes a given DBCommand, mapping a single column to a Java object + * using on DBRecordData.getValue() method. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @return the extracted list + */ public List<Object> queryForList(final DBCommand cmd, final DBColumnExpr col) { class SingleValueMapper implements DBRecordMapper<Object> { @@ -88,12 +240,38 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes a given DBCommand, mapping a single column to a single Long. If + * the value in the database is null, defaultValue is returned. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @param defaultValue + * the value to return in case of the database value is null + * @return the single Long value + * @throws IncorrectResultSizeDataAccessException + * if more than one result object has been found + */ public Long queryForLong(final DBCommand cmd, final DBColumnExpr col, Long defaultValue) { return DataAccessUtils.uniqueResult(queryForLongList(cmd, col, defaultValue)); } + /** + * Executes a given DBCommand, extracting a single column to a List of Long. + * If the value in the database is null, defaultValue is added to the list. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @param defaultValue + * the value to return in case of the database value is null + * @return the extracted list + */ public List<Long> queryForLongList(final DBCommand cmd, final DBColumnExpr col, final Long defaultValue) { class SingleLongMapper implements DBRecordMapper<Long> { @@ -108,12 +286,39 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes a given DBCommand, mapping a single column to a single Integer. + * If the value in the database is null, defaultValue is returned. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @param defaultValue + * the value to return in case of the database value is null + * @return the single Integer value + * @throws IncorrectResultSizeDataAccessException + * if more than one result object has been found + */ public Integer queryForInteger(final DBCommand cmd, final DBColumnExpr col, Integer defaultValue) { return DataAccessUtils.uniqueResult(queryForIntegerList(cmd, col, defaultValue)); } + /** + * Executes a given DBCommand, extracting a single column to a List of + * Integers. If the value in the database is null, defaultValue is added to + * the list. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @param defaultValue + * the value to return in case of the database value is null + * @return the extracted list + */ public List<Integer> queryForIntegerList(final DBCommand cmd, final DBColumnExpr col, final Integer defaultValue) { class SingleIntegerMapper implements DBRecordMapper<Integer> { @@ -127,10 +332,31 @@ public class EmpireTemplate implements InitializingBean { return query(cmd, new SingleIntegerMapper()); } + /** + * Executes a given DBCommand, mapping a single column to a single String. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @return the single String value + * @throws IncorrectResultSizeDataAccessException + * if more than one result object has been found + */ public String queryForString(final DBCommand cmd, final DBColumnExpr col) { return DataAccessUtils.uniqueResult(queryForStringList(cmd, col)); } + /** + * Executes a given DBCommand, extracting a single column to a List of + * Strings. + * + * @param cmd + * the DBCommand to execute + * @param col + * the column to map + * @return the extracted list + */ public List<String> queryForStringList(final DBCommand cmd, final DBColumnExpr col) { class SingleStringMapper implements DBRecordMapper<String> { @@ -144,31 +370,49 @@ public class EmpireTemplate implements InitializingBean { return query(cmd, new SingleStringMapper()); } + /** + * Executes a given DBCommand and handles the DBReader with the provided + * DBReaderExtractor. + * + * @param cmd + * the DBCommand to execute + * @param readerExtractor + * @return the result returned by the readerExtractor + */ public <K> K query(final DBCommand cmd, - final DBReaderExtractor<K> readerHandler) { + final DBReaderExtractor<K> readerExtractor) { class QueryCallback implements ConnectionCallback<K> { public K doInConnection(Connection connection) throws SQLException, DataAccessException { - return query(connection, cmd, readerHandler); + return query(connection, cmd, readerExtractor); } } return getJdbcTemplate().execute(new QueryCallback()); } + /** + * Executes a given DBCommand and handles each row of the DBReader with the + * provided DBRecordCallbackHandler. + * + * @param cmd + * the DBCommand to execute + * @param recordCallbackHandler + */ public void query(final DBCommand cmd, - final DBRecordCallbackHandler rowCallbackHandler) { - query(cmd, new DbRecordCallbackHandlerExtractor(rowCallbackHandler)); - } - - public <K> K queryForObject(final DBCommand cmd, - final DBRecordMapper<K> dataReader) { - - return DataAccessUtils.uniqueResult(query(cmd, dataReader)); - - } - + final DBRecordCallbackHandler recordCallbackHandler) { + query(cmd, new DbRecordCallbackHandlerExtractor(recordCallbackHandler)); + } + + /** + * Deletes a given record from the database. Calls + * DBRecord.delete(connection). + * + * @see org.apache.empire.db.DBRecord#delete(Connection) + * @param record + * to delete + */ public void deleteRecord(final DBRecord record) { class DeleteRecordCallback implements ConnectionCallback<Object> { @@ -182,18 +426,35 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Deletes a record from a table with a given single primary key. + * + * @param table + * the table to delete from + * @param key + * the primary key + */ + public void deleteRecord(final DBTable table, final Object key) { deleteRecord(table, new Object[] { key }); } + /** + * Deletes a record from a table with a given multiple primary key. Calls + * DBTable.deleteRecord(Object[], Connection). + * + * @see org.apache.empire.db.DBTable.deleteRecord(Object[], Connection) + * @param table + * the table to delete from + * @param keys + * the primary keys array + */ public void deleteRecord(final DBTable table, final Object[] keys) { class DeleteRecordCallback implements ConnectionCallback<Object> { public Object doInConnection(Connection connection) throws SQLException, DataAccessException { - DBRecord record = new EmpireRecord(); - record.read(table, keys, connection); - record.delete(connection); + table.deleteRecord(keys, connection); return null; } } @@ -201,6 +462,15 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Updates the record and saves all changes in the database. Calls + * DBRecord.update(connection). + * + * @see org.apache.empire.db.DBRecord#update(Connection) + * @param record + * to update + * @return the updated record + */ public DBRecord updateRecord(final DBRecord record) { class UpdateRecordCallback implements ConnectionCallback<DBRecord> { @@ -215,6 +485,18 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes an Update statement from a command object. This method delegates + * to DBDatabase.executeUpdate(cmd, connection), getting the DBDatabase + * instance from the DBCOmmand object. + * + * @see org.apache.empire.db.DBDatabase#executeUpdate(DBCommand, Connection) + * + * @param cmd + * the command object containing the update command + * @return the number of records that have been updated with the supplied + * statement + */ public int executeUpdate(final DBCommand cmd) { class UpdateRecordCallback implements ConnectionCallback<Integer> { @@ -228,6 +510,18 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes a Delete statement from a command object. This method delegates + * to DBDatabase.executeDelete(cmd, connection), getting the DBDatabase + * instance from the DBCOmmand object. + * + * @see org.apache.empire.db.DBDatabase#executeDelete(DBCommand, Connection) + * + * @param cmd + * the command object containing the delete command + * @return the number of records that have been deleted with the supplied + * statement + */ public int executeDelete(final DBTable table, final DBCommand cmd) { class DeleteRecordCallback implements ConnectionCallback<Integer> { @@ -241,6 +535,18 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes an Insert statement from a command object. This method delegates + * to DBDatabase.executeInsert(cmd, connection), getting the DBDatabase + * instance from the DBCOmmand object. + * + * @see org.apache.empire.db.DBDatabase#executeInsert(DBCommand, Connection) + * + * @param cmd + * the command object containing the insert command + * @return the number of records that have been inserted with the supplied + * statement + */ public int executeInsert(final DBCommand cmd) { class InsertRecordCallback implements ConnectionCallback<Integer> { @@ -254,22 +560,97 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Helper method to an create a DBRecord instance. Can be customized through + * setRecordFactory or setRecordClass methods. + * + * @param table + * the table + * @return the new DBRecord instance + */ public DBRecord newRecord(final DBRowSet table) { - DBRecord record = new EmpireRecord(); + DBRecord record = this.recordFactory.getObject(); record.create(table); return record; } + /** + * Opens a DBRecord instance with the given multiple primary keys. In + * contrast of getRecord(DBRowSet, Object) this method throws + * RecordNotFoundExpcetion if matching record exists. + * + * @param table + * the table to read the record from + * @param key + * the primary key + * @return the DBRecord instance, never null + * @throws org.apache.empire.db.exceptions.RecordNotFoundException + * in case of the record not found + */ public DBRecord openRecord(final DBRowSet table, final Object key) { return openRecord(table, new Object[] { key }); } + /** + * Opens a DBRecord instance with the given multiple primary keys. In + * contrast of getRecord(DBRowSet, Object[]) this method throws + * RecordNotFoundExpcetion if matching record exists. + * + * @param table + * the table to read the record from + * @param keys + * the primary key array + * @return the DBRecord instance, never null + * @throws org.apache.empire.db.exceptions.RecordNotFoundException + * in case of the record not found + */ public DBRecord openRecord(final DBRowSet table, final Object[] keys) { class ReadRecordCallback implements ConnectionCallback<DBRecord> { public DBRecord doInConnection(Connection connection) throws SQLException, DataAccessException { DBRecord record = new EmpireRecord(); + record.read(table, keys, connection); + return record; + } + } + + return getJdbcTemplate().execute(new ReadRecordCallback()); + + } + + /** + * Opens a DBRecord instance with the given single primary key. In contrast + * of openRecord(DBRowSet, Object) this method returns null if no matching + * record exists. + * + * @param table + * the table to read the record from + * @param key + * the primary key + * @return the DBRecord instance, can be null + */ + public DBRecord getRecord(final DBRowSet table, final Object key) { + return openRecord(table, new Object[] { key }); + } + + /** + * Opens a DBRecord instance with the given multiple primary keys. In + * contrast of openRecord(DBRowSet, Object[]) this method returns null if no + * matching record exists. + * + * @param table + * the table to read the record from + * @param keys + * the primary keys array + * @return the DBRecord instance, can be null + */ + public DBRecord getRecord(final DBRowSet table, final Object[] keys) { + + class ReadRecordCallback implements ConnectionCallback<DBRecord> { + public DBRecord doInConnection(Connection connection) + throws SQLException, DataAccessException { + DBRecord record = new EmpireRecord(); try { record.read(table, keys, connection); } catch (RecordNotFoundException e) { @@ -283,6 +664,23 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes a given DBCommand query and maps each row to Class<T> object + * using DBReader.getBeanList method. + * + * @see org.apache.empire.db.DBReader.getBeanList(C, Class<T>, int) + * + * @param cmd + * the query command + * @param c + * the collection to add the objects to + * @param t + * the class type of the objects in the list + * @param maxCount + * the maximum number of objects + * + * @return the list of T + */ public <C extends Collection<T>, T> C queryForBeanList(final DBCommand cmd, final C c, final Class<T> t, final int maxCount) { @@ -298,19 +696,70 @@ public class EmpireTemplate implements InitializingBean { } + /** + * Executes a given DBCommand query and maps each row to Class<T> object + * using DBReader.getBeanList method. + * + * @see org.apache.empire.db.DBReader.getBeanList(Class<T>, int) + * + * @param cmd + * the query command + * @param t + * the class type of the objects in the list + * @param maxCount + * the maximum number of objects + * + * @return the list of T + */ public <T> List<T> queryForBeanList(DBCommand cmd, Class<T> t, int maxItems) { return queryForBeanList(cmd, new ArrayList<T>(), t, maxItems); } + /** + * Executes a given DBCommand query and maps each row to Class<T> object + * using DBReader.getBeanList method. + * + * @see org.apache.empire.db.DBReader.getBeanList(Class<T>) + * + * @param cmd + * the query command + * @param t + * the class type of the objects in the list + * + * @return the list of T + */ + public <T> List<T> queryForBeanList(DBCommand cmd, Class<T> t) { return queryForBeanList(cmd, t, -1); } - + + /** + * Executes a given DBCommand query and maps a single row to Class<T> object + * using DBReader.getBeanList method. + * + * @param cmd + * the query command + * @param t + * the class type of the object to return + * + * @return the list of T + * @throws IncorrectResultSizeDataAccessException + * if more than one result object has been found + */ public <T> T queryForBean(DBCommand cmd, Class<T> t) { return DataAccessUtils.uniqueResult(queryForBeanList(cmd, t, -1)); } - + /** + * Executes a ConnectionCallback. Delegates to the underlying JdbcTemplate. + * + * @see + * org.springframework.jdbc.core.JdbcTemplate.execute(ConnectionCallback + * <K>) + * + * @param connectionCallback + * @return arbitrary object + */ public <K> K execute(ConnectionCallback<K> connectionCallback) { return getJdbcTemplate().execute(connectionCallback); } @@ -328,8 +777,15 @@ public class EmpireTemplate implements InitializingBean { } } + /** + * Creates a new DBReader instance from the readerFactory; + * + * @return DBReader instance + */ + private DBReader newDBReader() { - return new EmpireReader(); + + return this.readerFactory.getObject(); } private static class DbRecordCallbackHandlerExtractor implements http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/resources/example1/applicationContext.xml ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/resources/example1/applicationContext.xml b/empire-db-spring/src/main/resources/example1/applicationContext.xml index 56b0699..648b4b2 100644 --- a/empire-db-spring/src/main/resources/example1/applicationContext.xml +++ b/empire-db-spring/src/main/resources/example1/applicationContext.xml @@ -60,15 +60,22 @@ <bean id="empireApp" class="org.apache.empire.spring.example1.EmpireAppImpl" parent="empireDao"/> - <bean id="empireDb" class="org.apache.empire.spring.DbDatabaseFactoryBean"> + <bean id="empireDb" class="org.apache.empire.spring.DBDatabaseFactoryBean"> <property name="driverClass" value="${empire.driver}"/> <property name="schema" value="${empire.schemaname}"/> <property name="databaseClass" value="org.apache.empire.spring.example1.SampleDB"/> </bean> <bean id="empireDao" abstract="true"> - <property name="database" ref="empireDb"/> + <property name="database" ref="sampleDb"/> + <property name="empireTemplate" ref="empireTemplate"/> + </bean> + + + <bean id="empireTemplate" class="org.apache.empire.spring.EmpireTemplate"> <property name="dataSource" ref="dataSource"/> + <property name="dBRecordClass" value="org.apache.empire.spring.EmpireRecord"/> + <property name="dBReaderClass" value="org.apache.empire.spring.EmpireReader"/> </bean> @@ -80,4 +87,8 @@ + + + + </beans> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/empire-db/blob/11ff2d59/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml ---------------------------------------------------------------------- diff --git a/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml b/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml index 349122d..79799a7 100644 --- a/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml +++ b/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml @@ -60,7 +60,7 @@ <bean id="employeeDao" class="org.apache.empire.spring.example2.EmployeeDaoImpl" parent="empireDao"/> - <bean id="sampleDb" class="org.apache.empire.spring.DbDatabaseFactoryBean"> + <bean id="sampleDb" class="org.apache.empire.spring.DBDatabaseFactoryBean"> <property name="driverClass" value="${empire.driver}"/> <property name="schema" value="${empire.schemaname}"/> <property name="databaseClass" value="org.apache.empire.spring.example1.SampleDB"/> @@ -68,12 +68,14 @@ <bean id="empireDao" abstract="true"> <property name="database" ref="sampleDb"/> - <property name="dataSource" ref="dataSource"/> + <property name="empireTemplate" ref="empireTemplate"/> </bean> <bean id="empireTemplate" class="org.apache.empire.spring.EmpireTemplate"> <property name="dataSource" ref="dataSource"/> + <property name="dBRecordClass" value="org.apache.empire.spring.EmpireRecord"/> + <property name="dBReaderClass" value="org.apache.empire.spring.EmpireReader"/> </bean>
