Author: dfabulich
Date: Tue Feb 10 07:20:16 2009
New Revision: 742870
URL: http://svn.apache.org/viewvc?rev=742870&view=rev
Log:
[DBUTILS-29] Support bean property to SQL IN parameter mapping
Defines new fillStatementWithBean functions, and makes fillStatement public
Modified:
commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java
Modified: commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java
URL: http://svn.apache.org/viewvc/commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java?rev=742870&r1=742869&r2=742870&view=diff
==============================================================================
--- commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java
(original)
+++ commons/sandbox/dbutils/bugfixing/src/java/org/apache/commons/dbutils/QueryRunner.java
Tue Feb 10 07:20:16 2009
@@ -16,6 +16,9 @@
*/
package org.apache.commons.dbutils;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
@@ -157,7 +160,7 @@
* value to pass in.
* @throws SQLException if a database access error occurs
*/
- protected void fillStatement(PreparedStatement stmt, Object[] params)
+ public void fillStatement(PreparedStatement stmt, Object[] params)
throws SQLException {
if (params == null) {
@@ -190,6 +193,87 @@
}
/**
+ * Fill the <code>PreparedStatement</code> replacement parameters with the
+ * given object's bean property values.
+ *
+ * @param stmt
+ * PreparedStatement to fill
+ * @param bean
+ * a JavaBean object
+ * @param properties
+ * an ordered array of properties; this gives the order to insert
+ * values in the statement
+ * @throws SQLException
+ * if a database access error occurs
+ */
+ public void fillStatementWithBean(PreparedStatement stmt, Object bean,
+ PropertyDescriptor[] properties) throws SQLException {
+ Object[] params = new Object[properties.length];
+ for (int i = 0; i < properties.length; i++) {
+ PropertyDescriptor property = properties[i];
+ Object value = null;
+ try {
+ if (property.getReadMethod().getParameterTypes().length > 0) {
+ throw new SQLException(
+ "Can't use an indexed bean property as a SQL parameter: "
+ + property.getName());
+ }
+ value = property.getReadMethod().invoke(bean, new Object[0]);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ params[i] = value;
+ }
+ fillStatement(stmt, params);
+ }
+
+ /**
+ * Fill the <code>PreparedStatement</code> replacement parameters with the
+ * given object's bean property values.
+ *
+ * @param stmt
+ * PreparedStatement to fill
+ * @param bean
+ * a JavaBean object
+ * @param propertyNames
+ * an ordered array of property names (these should match the
+ * getters/setters); this gives the order to insert values in the
+ * statement
+ * @throws SQLException
+ * if a database access error occurs
+ */
+ public void fillStatementWithBean(PreparedStatement stmt, Object bean,
+ String[] propertyNames) throws SQLException {
+ PropertyDescriptor[] descriptors;
+ try {
+ descriptors = Introspector.getBeanInfo(bean.getClass())
+ .getPropertyDescriptors();
+ } catch (IntrospectionException e) {
+ throw new RuntimeException(e);
+ }
+ PropertyDescriptor[] sorted = new PropertyDescriptor[propertyNames.length];
+ for (int i = 0; i < propertyNames.length; i++) {
+ String propertyName = propertyNames[i];
+ if (propertyName == null)
+ throw new NullPointerException("propertyName can't be null: "
+ + i);
+ boolean found = false;
+ for (int j = 0; j < descriptors.length; j++) {
+ PropertyDescriptor descriptor = descriptors[j];
+ if (propertyName.equals(descriptor.getName())) {
+ sorted[i] = descriptor;
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ throw new RuntimeException("Couldn't find bean property: "
+ + bean.getClass() + " " + propertyName);
+ }
+ fillStatementWithBean(stmt, bean, sorted);
+ }
+
+ /**
* Returns the <code>DataSource</code> this runner is using.
* <code>QueryRunner</code> methods always call this method to get the
* <code>DataSource</code> so subclasses can provide specialized
|