Author: wspeirs Date: Wed Nov 23 16:31:09 2011 New Revision: 1205485 URL: http://svn.apache.org/viewvc?rev=1205485&view=rev Log: - Added BeanMapHandler and associated test case (DBUTILS-67) - Updated pom.xml; moved myself from contrib to dev - Updated changes in changes.xml file
Added: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java Modified: commons/proper/dbutils/trunk/pom.xml commons/proper/dbutils/trunk/src/changes/changes.xml Modified: commons/proper/dbutils/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/pom.xml?rev=1205485&r1=1205484&r2=1205485&view=diff ============================================================================== --- commons/proper/dbutils/trunk/pom.xml [utf-8] (original) +++ commons/proper/dbutils/trunk/pom.xml [utf-8] Wed Nov 23 16:31:09 2011 @@ -64,6 +64,15 @@ </roles> </developer> <developer> + <name>Dan Fabulich</name> + <id>dfabulich</id> + <email>d...@fabulich.com</email> + <organization /> + <roles> + <role>Java Developer</role> + </roles> + </developer> + <developer> <name>David Graham</name> <id>dgraham</id> <email>dgra...@apache.org</email> @@ -82,28 +91,27 @@ </roles> </developer> <developer> - <name>Henri Yandell</name> - <id>bayard</id> - <email>bay...@apache.org</email> - <organization /> + <name>William Speirs</name> + <id>wspeirs</id> + <email>wspe...@apache.org</email> <roles> <role>Java Developer</role> </roles> </developer> <developer> - <name>Dan Fabulich</name> - <id>dfabulich</id> - <email>d...@fabulich.com</email> + <name>Simone Tripodi</name> + <id>simonetripodi</id> + <email>simonetripodi at apache dot org</email> + </developer> + <developer> + <name>Henri Yandell</name> + <id>bayard</id> + <email>bay...@apache.org</email> <organization /> <roles> <role>Java Developer</role> </roles> </developer> - <developer> - <name>Simone Tripodi</name> - <id>simonetripodi</id> - <email>simonetripodi at apache dot org</email> - </developer> </developers> <contributors> @@ -173,12 +181,6 @@ <role>Java Developer</role> </roles> </contributor> - <contributor> - <name>Bill Speirs</name> - <roles> - <role>Java Developer</role> - </roles> - </contributor> </contributors> <dependencies> Modified: commons/proper/dbutils/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/changes/changes.xml?rev=1205485&r1=1205484&r2=1205485&view=diff ============================================================================== --- commons/proper/dbutils/trunk/src/changes/changes.xml (original) +++ commons/proper/dbutils/trunk/src/changes/changes.xml Wed Nov 23 16:31:09 2011 @@ -38,6 +38,14 @@ The <action> type attribute can be add,u <title>Release Notes</title> </properties> <body> + <release version="1.5" date="2011-11-25" description="Bugfixes and addition of BeanMapHandler"> + <action dev="wspeirs" type="update" issue="DBUTILS-77"> + Updated documentation to better reflect the use of pmdKnownBroken + </action> + <action due-to="Michael Osipov" type="add" issue="DBUTILS-67"> + Added BeanMapHandler + </action> + </release> <release version="1.4" date="2011-10-23" description="Bugfixes and addition of asynchronous QueryLoader"> <action type="fix" issue="DBUTILS-81"> DbUtils.loadDriver() uses Class.forName() @@ -54,7 +62,7 @@ The <action> type attribute can be add,u <action type="update" issue="DBUTILS-75"> efficient usage from findbugs </action> - <action type="add" issue="DBUTILS-78"> + <action dev="wspeirs" type="add" issue="DBUTILS-78"> Add asynchronous batch, query, and update calls </action> </release> Added: commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java?rev=1205485&view=auto ============================================================================== --- commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java (added) +++ commons/proper/dbutils/trunk/src/main/java/org/apache/commons/dbutils/handlers/BeanMapHandler.java Wed Nov 23 16:31:09 2011 @@ -0,0 +1,170 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.dbutils.handlers; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.apache.commons.dbutils.RowProcessor; + +/** + * <p> + * <code>ResultSetHandler</code> implementation that returns a Map of Beans. + * <code>ResultSet</code> rows are converted into Beans which are then stored in + * a Map under the given key. + * </p> + * <p> + * If you had a Person table with a primary key column called ID, you could + * retrieve rows from the table like this: + * + * <pre> + * ResultSetHandler<Map<Long, Person>> h = new BeanMapdHandler<Long, Person>(Person.class, "id"); + * Map&ltLong, Person> found = queryRunner.query("select id, name, age from person", h); + * Person jane = found.get(1L); // jane's id is 1 + * String janesName = jane.getName(); + * Integer janesAge = jane.getAge(); + * </pre> + * + * Note that the "id" passed to BeanMapHandler can be in any case. The data type + * returned for id is dependent upon how your JDBC driver converts SQL column + * types from the Person table into Java types. The "name" and "age" columns are + * converted according to their property descriptors by DbUtils. + * </p> + * <p> + * This class is thread safe. + * </p> + * + * @param <K> + * the type of keys maintained by the returned map + * @param <V> + * the type of the bean + * @see org.apache.commons.dbutils.ResultSetHandler + * @since DbUtils 1.5 + */ +public class BeanMapHandler<K, V> extends AbstractKeyedHandler<K, V> { + + /** + * The Class of beans produced by this handler. + */ + private Class<V> type; + + /** + * The RowProcessor implementation to use when converting rows into Objects. + */ + private RowProcessor convert; + + /** + * The column index to retrieve key values from. Defaults to 1. + */ + private int columnIndex; + + /** + * The column name to retrieve key values from. Either columnName or + * columnIndex will be used but never both. + */ + private String columnName; + + /** + * Creates a new instance of BeanMapHandler. The value of the first column + * of each row will be a key in the Map. + * + * @param type + * The Class that objects returned from <code>createRow()</code> + * are created from. + */ + public BeanMapHandler(Class<V> type) { + this(type, ArrayHandler.ROW_PROCESSOR, 1, null); + } + + /** + * Creates a new instance of BeanMapHandler. The value of the first column + * of each row will be a key in the Map. + * + * @param type + * The Class that objects returned from <code>createRow()</code> + * are created from. + * @param convert + * The <code>RowProcessor</code> implementation to use when + * converting rows into Beans + */ + public BeanMapHandler(Class<V> type, RowProcessor convert) { + this(type, convert, 1, null); + } + + /** + * Creates a new instance of BeanMapHandler. + * + * @param type + * The Class that objects returned from <code>createRow()</code> + * are created from. + * @param columnIndex + * The values to use as keys in the Map are retrieved from the + * column at this index. + */ + public BeanMapHandler(Class<V> type, int columnIndex) { + this(type, ArrayHandler.ROW_PROCESSOR, columnIndex, null); + } + + /** + * Creates a new instance of BeanMapHandler. + * + * @param type + * The Class that objects returned from <code>createRow()</code> + * are created from. + * @param columnName + * The values to use as keys in the Map are retrieved from the + * column with this name. + */ + public BeanMapHandler(Class<V> type, String columnName) { + this(type, ArrayHandler.ROW_PROCESSOR, 1, columnName); + } + + /** + * Private Helper + * + * @param convert + * The <code>RowProcessor</code> implementation to use when + * converting rows into Beans + * @param columnIndex + * The values to use as keys in the Map are retrieved from the + * column at this index. + * @param columnName + * The values to use as keys in the Map are retrieved from the + * column with this name. + */ + private BeanMapHandler(Class<V> type, RowProcessor convert, + int columnIndex, String columnName) { + super(); + this.type = type; + this.convert = convert; + this.columnIndex = columnIndex; + this.columnName = columnName; + } + + @Override + protected K createKey(ResultSet rs) throws SQLException { + return (columnName == null) ? (K) rs.getObject(columnIndex) : (K) rs + .getObject(columnName); + } + + @Override + protected V createRow(ResultSet rs) throws SQLException { + // TODO Auto-generated method stub + return this.convert.toBean(rs, type); + } + +} Added: commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java URL: http://svn.apache.org/viewvc/commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java?rev=1205485&view=auto ============================================================================== --- commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java (added) +++ commons/proper/dbutils/trunk/src/test/java/org/apache/commons/dbutils/handlers/BeanMapHandlerTest.java Wed Nov 23 16:31:09 2011 @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.dbutils.handlers; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.util.Map; + +import org.apache.commons.dbutils.RowProcessor; +import org.apache.commons.dbutils.TestBean; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +public class BeanMapHandlerTest { + + private BeanMapHandler<Long, TestBean> bmh; + private Map<Long, TestBean> res; + @Mock private ResultSet rs; + @Mock private ResultSetMetaData rsmd; + @Mock private RowProcessor rp; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + when(rs.next()).thenReturn(true, false); + when(rs.getObject(1)).thenReturn(23L); + when(rs.getObject(2)).thenReturn(23L); + when(rs.getObject("id")).thenReturn(23L); + when(rs.getMetaData()).thenReturn(rsmd); + when(rp.toBean(rs, TestBean.class)).thenReturn(new TestBean()); + } + + private void handle() throws Exception { + res = bmh.handle(rs); + assertNotNull(res.get(23L)); + } + + @Test + public void testBeanMapHandlerClassOfV() throws Exception { + bmh = new BeanMapHandler<Long, TestBean>(TestBean.class); + handle(); + } + + @Test + public void testBeanMapHandlerClassOfVRowProcessor() throws Exception { + bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, rp); + handle(); + } + + @Test + public void testBeanMapHandlerClassOfVInt() throws Exception { + bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, 2); + handle(); + } + + @Test + public void testBeanMapHandlerClassOfVString() throws Exception { + bmh = new BeanMapHandler<Long, TestBean>(TestBean.class, "id"); + handle(); + } + + @Test + public void testEmptyResultSet() throws Exception { + when(rs.next()).thenReturn(false); + bmh = new BeanMapHandler<Long, TestBean>(TestBean.class); + res = bmh.handle(rs); + assertNull(res.get(23L)); + } + +}