Hello All - I've been following this thread and have been doing some similar work. In the code that was given here, there is really no regard for type. I've put together a couple of methods that would enable us to build the dynabean with the appropriate type. These methods work well in the tests that I've done but it would be great if others would use them so that we could perfect them. The code in the two methods is a little redundant and I'm open to suggestions on the appropriate way to reduce that. Enjoy!
Michael Connor /** * This method will return an appropriate java class for a given * sql type. This method really should check the size and precision * for numerics and return an appropriate number. For now, it pretty * much always returns BigDecimal's for numbers. That isn't bad though * because BigDecimal covers any possible number without loss of precision * or worry about space to hold the number. by [EMAIL PROTECTED] * * @param sqlType The sql type of the ResultSet column as defined by Types.java * @return Class The appropriate Java Class to use for the column * @throws Exception If the sqlType is not supported by this method */ public static Class getJavaType (int sqlType) throws Exception { Class javaType = null; switch (sqlType) { case (java.sql.Types.CHAR) : javaType = java.lang.String.class; break; case (java.sql.Types.BIGINT) : javaType = BigDecimal.class; break; case (java.sql.Types.DECIMAL) : javaType = BigDecimal.class; break; case (java.sql.Types.NUMERIC) : javaType = BigDecimal.class; break; case (java.sql.Types.DATE) : javaType = java.sql.Date.class; break; case (java.sql.Types.TIME) : javaType = java.sql.Time.class; break; case (java.sql.Types.TIMESTAMP) : javaType = java.sql.Timestamp.class; break; case (java.sql.Types.CLOB) : javaType = java.sql.Clob.class; break; case (java.sql.Types.BLOB) : javaType = java.sql.Blob.class; break; case (java.sql.Types.REF) : javaType = java.sql.Ref.class; break; case (java.sql.Types.JAVA_OBJECT) : javaType = Object.class; break; case (java.sql.Types.OTHER ) : javaType = Object.class; break; case (java.sql.Types.VARCHAR) : javaType = String.class; break; case (java.sql.Types.LONGVARCHAR) : javaType = String.class; break; case (java.sql.Types.BIT) : javaType = Boolean.class; break; case (java.sql.Types.TINYINT) : javaType = Byte.class; break; case (java.sql.Types.SMALLINT) : javaType = Short.class; break; case (java.sql.Types.INTEGER) : javaType = Integer.class; break; case (java.sql.Types.REAL) : javaType = Float.class; break; case (java.sql.Types.DOUBLE) : javaType = Double.class; break; default : throw new Exception ("SQL Type : " + sqlType + " not supported"); } return javaType; } /** * This method will return an appropriate java object from a ResultSet * sql type. This method really should check the size and precision * for numerics and return an appropriate number type. For now it * always returns BigDecimal's for numbers. That isn't bad though * because BigDecimal covers any possible number without loss of precision * or worry about space to hold the number. by [EMAIL PROTECTED] * * @param resultSet The resultSet to use * @param column The column number to fetch, 1 based * @param sqlType The sql type of the ResultSet column as defined by Types.java * @return Object The value for the column in the appropriate Java type * @throws Exception If the sqlType is not supported by this method */ public static Object getColumnValue (ResultSet resultSet, int column, int type) throws Exception { Object object = null; switch (type) { case (java.sql.Types.CHAR) : object = resultSet.getString (column); break; case (java.sql.Types.BIGINT) : object = resultSet.getBigDecimal(column); break; case (java.sql.Types.DECIMAL) : object = resultSet.getBigDecimal(column); break; case (java.sql.Types.NUMERIC) : object = resultSet.getBigDecimal(column); break; case (java.sql.Types.DATE) : object = resultSet.getDate(column); break; case (java.sql.Types.TIME) : object = resultSet.getTime(column); break; case (java.sql.Types.TIMESTAMP) : object = resultSet.getTimestamp(column); break; case (java.sql.Types.CLOB) : object = resultSet.getClob(column); break; case (java.sql.Types.BLOB) : object = resultSet.getBlob(column); break; case (java.sql.Types.REF) : object = resultSet.getRef(column); break; case (java.sql.Types.JAVA_OBJECT) : object = resultSet.getObject(column); break; case (java.sql.Types.OTHER ) : object = resultSet.getObject(column); break; case (java.sql.Types.VARCHAR) : object = resultSet.getString(column); break; case (java.sql.Types.LONGVARCHAR) : object = resultSet.getString(column); break; // the rest of these are primitives, they are handled differently case (java.sql.Types.BIT) : object = new Boolean (resultSet.getBoolean(column)); break; case (java.sql.Types.TINYINT) : object = new Byte (resultSet.getByte(column)); break; case (java.sql.Types.SMALLINT) : object = new Short (resultSet.getShort(column)); break; case (java.sql.Types.INTEGER) : object = new Integer (resultSet.getInt(column)); break; case (java.sql.Types.REAL) : object = new Float (resultSet.getFloat(column)); break; case (java.sql.Types.DOUBLE) : object = new Double (resultSet.getDouble(column)); break; default : throw new Exception ("SQL Type : " + type + " not supported"); } if ( resultSet.wasNull() ) object = null; return object; } -----Original Message----- From: Craig R. McClanahan [mailto:[EMAIL PROTECTED]] Sent: Friday, July 12, 2002 6:45 PM To: Struts Users Mailing List Subject: RE: DynaBeans, DynaClass, DynaMen I implemented something a little more memory-efficient than this (doesn't require the entire result set to be in memory) in tonight's nightly build of commons-beanutils, which will therefore be available in the 20020713 nightly build of Struts. You use it something like this: Connection conn = ...; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select * from customers"); Iterator rows = (new ResultSetDynaClass(rs)).iterator(); while (rows.hasNext()) { DynaBean row = (DynaBean) rows.next(); System.out.println("Processing customer " + row.get("account_id")); ... access this row as a DynaBean ... } rs.close(); stmt.close(); I elected to avoid doing the type conversions, so the properties you get back will correspond to their types in the database. Craig On Fri, 12 Jul 2002 [EMAIL PROTECTED] wrote: > Date: Fri, 12 Jul 2002 13:56:38 -0400 > From: [EMAIL PROTECTED] > Reply-To: Struts Users Mailing List <[EMAIL PROTECTED]> > To: [EMAIL PROTECTED] > Subject: RE: DynaBeans, DynaClass, DynaMen > > > > Here is what I am using... Very simple and only returns strings... > > > /** > * Converts a resultset into an ArrayList of DynaBeans > * > * @param resultSet SQL result set to be converted > * @return ArrayList of DynaBeans with all columnnames converted to > * lowercase > * @throws SQLException DOCUMENT ME! > */ > private static ArrayList getDynaBeanArrayList(ResultSet resultSet) > throws SQLException { > > ResultSetMetaData metaData = resultSet.getMetaData(); > int cols = metaData.getColumnCount(); > ArrayList list = new ArrayList(); > DynaProperty[] props = new DynaProperty[cols]; > BasicDynaClass dClass = null; > > for (int i = 1; i <= cols; i++) { > props[i - 1] = new > DynaProperty(metaData.getColumnName(i).toLowerCase()); > } > > try { > dClass = new BasicDynaClass("test", > Class.forName( > > "org.apache.commons.beanutils.BasicDynaBean"), > props); > } catch (Exception e) { > e.printStackTrace(); > } > > while (resultSet.next()) { > > HashMap map = new HashMap(cols, 1); > > for (int i = 1; i <= cols; i++) { > map.put(metaData.getColumnName(i).toLowerCase(), > resultSet.getString(i)); > } > > try { > > DynaBean dbean = dClass.newInstance(); > BeanUtils.populate(dbean, map); > list.add(dbean); > } catch (Exception e) { > e.printStackTrace(); > throw new SQLException("RequestUtils.getArrayList: " > + e.toString()); > } > } // End While > > return (list); > } > > > -----Original Message----- > From: craigmcc [mailto:[EMAIL PROTECTED]] > Sent: Friday, July 12, 2002 12:07 PM > To: struts-user > Subject: Re: DynaBeans, DynaClass, DynaMen > > > > > On Fri, 12 Jul 2002, Thorbjoern Ravn Andersen wrote: > > > Date: Fri, 12 Jul 2002 07:02:57 +0200 > > From: Thorbjoern Ravn Andersen <[EMAIL PROTECTED]> > > Reply-To: Struts Users Mailing List <[EMAIL PROTECTED]> > > To: Struts Users Mailing List <[EMAIL PROTECTED]> > > Subject: Re: DynaBeans, DynaClass, DynaMen > > > > [EMAIL PROTECTED] skrev: > > > > >...anyone remember DynaMen? > > > > > >Anyhow... I got a Dynabean mechanism working that builds a DynaBean > > >based on the metadata of a SQL result set, populates and array of the > > >little buggers and passes it back to me. For displaying I have a tag > > >library that does not like a call to get('name') as the field name. > > >What is the best way to get around this? > > > > > I wrote an AnonyBeans package which uses BCEL to generate beans on the > > fly based on a ResultSet. It is alpha code but works for me, and is > > usable anywhere where you need a real traditional bean, but where you > do > > not want to serialize it or use its type in Java source. > > > > Is this interesting? > > > > I think it would be interestesting, even though it might not be > universally useful (some containers won't let you introduce new classes > at > runtime). > > I'd also be interested in a mechanism that converted a ResultSet into a > custom DynaClass, with a corresponding DynaBean for each row. This > would > be trivially simple to do -- so simple that it probably makes a > worthwhile > addition to commons-beanutils itself if someone wanted to take this on. > > This wouldn't help you create dynamic input forms, but it would make a > completely flexible bean-like wrapper around a result set so you can use > Struts tags to display stuff. > > > -- > > Thorbjørn Ravn Andersen http://biobase.dk/~tra > > Craig > > > -- > To unsubscribe, e-mail: > <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: > <mailto:[EMAIL PROTECTED]> > > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > >