r2891 - in trunk: src/site/rst topia-persistence/src/main/java/org/nuiton/topia topia-persistence/src/main/java/org/nuiton/topia/framework
Author: tchemit Date: 2013-11-22 22:50:19 +0100 (Fri, 22 Nov 2013) New Revision: 2891 Url: http://nuiton.org/projects/topia/repository/revisions/2891 Log: fixes #2926: Improve Sql APIs update migration guide Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlQuery.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlWork.java Removed: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java Modified: trunk/src/site/rst/migrate_to_3.0.rst trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaSqlSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlSupport.java trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java Modified: trunk/src/site/rst/migrate_to_3.0.rst =================================================================== --- trunk/src/site/rst/migrate_to_3.0.rst 2013-11-22 21:20:24 UTC (rev 2890) +++ trunk/src/site/rst/migrate_to_3.0.rst 2013-11-22 21:50:19 UTC (rev 2891) @@ -49,6 +49,8 @@ Gérer les impacts n'est pas *nécessaire* pour passer à ToPIA 3.0, mais c'est fortement recommandé. En effet, ce code deviendra incompatible avec ToPIA 3.1, gérer les impacts au plus tôt permettra une migration en douceur. +Pas vrai, à partir de la 3.0-alpha-6, on casse la rétro-compatibilité car sinon +c'est trop compliqué à gérer. Propriétés TOPIA_* ------------------ @@ -218,9 +220,31 @@ méthodes les remplacer. S'il n'y pas de documentation, il faut remplacer le code appellant par le corps de la méthode dépréciée (fonctionnalité « inline » dans l'IDE). +Utilisation des templates de générations +---------------------------------------- +Les templates sont contenues dans un modules à part, il faut désormais utiliser +cette dépendance dans le plugin eugene. +:: + <dependency> + <groupId>org.nuiton.topia</groupId> + <artifactId>topia-templates</artifactId> + <version>3.0</version> + </dependency> +De plus les templates ont changé de paquetage, le nouveau paquetage est le suivant : + +:: + + org.nuiton.topia.templates + +Amélioration du code sql +------------------------ + +Voir TopiaSqlQuery, TopiaSqlWork et TopiaSqlSupport. + + .. |RECOMMENDED| image:: recommended.png .. |MANDATORY| image:: mandatory.png Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaSqlSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaSqlSupport.java 2013-11-22 21:20:24 UTC (rev 2890) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/HibernateTopiaSqlSupport.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -24,13 +24,16 @@ * #L% */ +import org.hibernate.HibernateException; +import org.hibernate.jdbc.Work; + import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; -import org.hibernate.HibernateException; -import org.hibernate.jdbc.Work; - /** * @author Arnaud Thimel <thimel@codelutin.com> */ @@ -42,16 +45,6 @@ this.hibernateSupport = hibernateSupport; } - @Override - public void executeSQL(String sqlScript) { - SQLWork sqlWork = new SQLWork(sqlScript); - try { - hibernateSupport.getHibernateSession().doWork(sqlWork); - } catch (HibernateException e) { - throw new TopiaException("Could not execute sql code", e); - } - } - public static class SQLWork implements Work { private final String script; @@ -70,4 +63,105 @@ } } + public static class TopiaSQLWorkWork implements Work { + + final TopiaSqlWork work; + + public TopiaSQLWorkWork(TopiaSqlWork work) { + this.work = work; + } + + @Override + public void execute(Connection connection) throws SQLException { + work.execute(connection); + } + } + + public static class TopiaSQLQueryWork<O> implements Work { + + final TopiaSqlQuery<O> query; + + final boolean multipleResult; + + final List<O> result = new ArrayList<O>(); + + public TopiaSQLQueryWork(TopiaSqlQuery<O> query, boolean multipleResult) { + this.query = query; + this.multipleResult = multipleResult; + } + + @Override + public void execute(Connection connection) throws SQLException { + + PreparedStatement ps = query.prepareQuery(connection); + try { + ResultSet set = ps.executeQuery(); + + query.afterExecuteQuery(set); + + if (set.next()) { + O singleResult = query.prepareResult(set); + if (singleResult != null) { + result.add(singleResult); + } + if (multipleResult) { + while (set.next()) { + singleResult = query.prepareResult(set); + if (singleResult != null) { + result.add(singleResult); + } + } + } + } + + } catch (Exception e) { + throw new TopiaException("Could not execute query", e); + } finally { + ps.close(); + } + } + + public List<O> getResult() { + return result; + } + } + + @Override + public void executeSQL(String sqlScript) { + SQLWork work = new SQLWork(sqlScript); + try { + hibernateSupport.getHibernateSession().doWork(work); + } catch (HibernateException e) { + throw new TopiaException("Could not execute sql code", e); + } + } + + @Override + public void doSQLWork(TopiaSqlWork sqlWork) { + TopiaSQLWorkWork work = new TopiaSQLWorkWork(sqlWork); + try { + hibernateSupport.getHibernateSession().doWork(work); + } catch (HibernateException e) { + throw new TopiaException("Could not execute sql code", e); + } + } + + @Override + public <O> O findSingleResult(final TopiaSqlQuery<O> query) throws TopiaException { + + TopiaSQLQueryWork<O> work = new TopiaSQLQueryWork<O>(query, false); + hibernateSupport.getHibernateSession().doWork(work); + final List<O> result = work.getResult(); + return result.isEmpty() ? null : result.get(0); + } + + @Override + public <O> List<O> findMultipleResult(final TopiaSqlQuery<O> query) throws TopiaException { + + TopiaSQLQueryWork<O> work = new TopiaSQLQueryWork<O>(query, true); + hibernateSupport.getHibernateSession().doWork(work); + final List<O> result = work.getResult(); + return result; + } + } Copied: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlQuery.java (from rev 2886, trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java) =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlQuery.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlQuery.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -0,0 +1,142 @@ +/* + * #%L + * ToPIA :: Persistence + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ +package org.nuiton.topia; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Wrap a Sql query some object. + * + * Implements the {@link #prepareResult(ResultSet)} to transforma result set + * row to an object. + * + * You can also do some stuff on the result set just after the query was + * executed using method {@link #afterExecuteQuery(ResultSet)}. + * + * @param <O> the type of result data + * @since 2.5 + */ +public abstract class TopiaSqlQuery<O> { + + /** + * Prepare the statement used to do the sql query. + * + * @param connection jdbc connection to use + * @return the statement containing the query to execute + * @throws SQLException if any problem + */ + protected abstract PreparedStatement prepareQuery(Connection connection) throws SQLException; + + /** + * given a result set, extract the data. + * + * @param set the result set + * @return the data extracted from the current set, or {@code null} + * @throws SQLException if any prob + */ + protected abstract O prepareResult(ResultSet set) throws SQLException; + + /** + * A hook to obtain the result set just after the query execute. + * + * @param set the result set just obtained + * @throws SQLException if any prob + * @since 2.6.4 + */ + protected void afterExecuteQuery(ResultSet set) throws SQLException { + // by default do nothing + } + + /** + * Obtain the column names of a given result set using his metadata. + * + * @param set the result set to inspect + * @return the column names of the result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected String[] getColumnNames(ResultSet set) throws SQLException { + ResultSetMetaData metaData = set.getMetaData(); + int columnCount = metaData.getColumnCount(); + String[] result = new String[columnCount]; + for (int i = 0; i < columnCount; i++) { + result[i] = metaData.getColumnName(i + 1); + } + return result; + } + + /** + * From a given result set, let's count his number of row. + * <p/> + * <strong>Note:</strong> the result set must be scrollable to go back to + * before first row. + * + * @param set the result set to inspect + * @return the number of row of the given result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected long getNbRows(ResultSet set) throws SQLException { + + //FIXME tchemit-2012-11-22 use set.last() + long nbRows = 0; + while (set.next()) { + nbRows++; + } + // go back before first row (be ware the resultset must be scrollable) + set.beforeFirst(); + return nbRows; + } + + /** + * Given the column names of the result set, transform the row of the + * result set to a map with column name as key. + * + * @param columnNames column names of the result set + * @param set the set to inspect + * @return the map for the given row of the result set + * @throws SQLException if any pb + * @since 2.6.4 + */ + protected Map<String, Object> getRowAsMap(String[] columnNames, + ResultSet set) throws SQLException { + + Map<String, Object> result = new LinkedHashMap<String, Object>(); + int length = columnNames.length; + for (int i = 0; i < length; i++) { + String name = columnNames[i]; + Object value = set.getObject(i + 1); + result.put(name, value); + } + return result; + } + +} Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlSupport.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlSupport.java 2013-11-22 21:20:24 UTC (rev 2890) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlSupport.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -24,6 +24,8 @@ * #L% */ +import java.util.List; + /** * This API provides methods to run SQL queries * @@ -33,12 +35,35 @@ public interface TopiaSqlSupport { /** - * Execute a given sql code inside this transaction. + * Execute a given SQL code inside this transaction. * * @param sqlScript the sql script to execute */ void executeSQL(String sqlScript); - // TODO AThimel 20/07/13 Copy "void doSQLWork(TopiaSQLWork sqlWork);" from topia-3.0-jpa + /** + * Runs the given SQL work on the current context + * + * @param sqlWork the SQL work instance to execute + */ + void doSQLWork(TopiaSqlWork sqlWork); + /** + * Runs the given SQL query and return its first result if there is some. + * + * @param query query to play + * @return the single result or {@code null} if none found. + * @throws TopiaException for any pb + */ + <O> O findSingleResult(TopiaSqlQuery<O> query) throws TopiaException; + + /** + * Runs the given SQL query and return all his result if there is some. + * + * @param query query to play + * @return the list of results (the list is empty if query returns no result). + * @throws TopiaException for any pb + */ + <O> List<O> findMultipleResult(TopiaSqlQuery<O> query) throws TopiaException; + } Added: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlWork.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlWork.java (rev 0) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlWork.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -0,0 +1,25 @@ +package org.nuiton.topia; + +import java.sql.Connection; +import java.sql.SQLException; + +/** + * Interface used for any native SQL batch. This interface is highly inspired + * of org.hibernate.jdbc.Work. + * + * @author Arnaud Thimel <thimel@codelutin.com> + * @since 3.0 + */ +public interface TopiaSqlWork { + + /** + * Execute the discrete work encapsulated by this work instance using the + * supplied connection. + * + * @param connection The connection on which to perform the work. + * @throws SQLException Thrown during execution of the underlying JDBC + * interaction. + */ + void execute(Connection connection) throws SQLException; + +} \ No newline at end of file Property changes on: trunk/topia-persistence/src/main/java/org/nuiton/topia/TopiaSqlWork.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java 2013-11-22 21:20:24 UTC (rev 2890) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/AbstractTopiaContext.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -40,18 +40,20 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; -import org.hibernate.jdbc.Work; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.jdbc.connections.spi.ConnectionProvider; import org.hibernate.service.spi.Stoppable; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.tool.hbm2ddl.SchemaUpdate; +import org.nuiton.topia.HibernateTopiaSqlSupport; import org.nuiton.topia.TopiaContext; import org.nuiton.topia.TopiaContextFactory; import org.nuiton.topia.TopiaException; import org.nuiton.topia.TopiaNotFoundException; import org.nuiton.topia.TopiaReplicationDestination; +import org.nuiton.topia.TopiaSqlQuery; +import org.nuiton.topia.TopiaSqlWork; import org.nuiton.topia.event.TopiaContextListener; import org.nuiton.topia.event.TopiaEntitiesVetoable; import org.nuiton.topia.event.TopiaEntityListener; @@ -72,9 +74,6 @@ import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Field; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -89,6 +88,9 @@ import java.util.WeakHashMap; import java.util.zip.GZIPInputStream; +import static org.nuiton.topia.HibernateTopiaSqlSupport.SQLWork; +import static org.nuiton.topia.HibernateTopiaSqlSupport.TopiaSQLQueryWork; + /** * Le AbstractTopiaContext est le point d'entre pour acceder aux donnees. Il est * configurer par un fichier de propriete @@ -971,6 +973,32 @@ } } + @Override + public void doSQLWork(TopiaSqlWork sqlWork) { + HibernateTopiaSqlSupport.TopiaSQLWorkWork work = new HibernateTopiaSqlSupport.TopiaSQLWorkWork(sqlWork); + try { + getHibernate().doWork(work); + } catch (HibernateException e) { + throw new TopiaException("Could not execute sql code", e); + } + } + + @Override + public <O> O findSingleResult(TopiaSqlQuery<O> query) throws TopiaException { + TopiaSQLQueryWork<O> work = new TopiaSQLQueryWork<O>(query, false); + hibernate.doWork(work); + List<O> result = work.getResult(); + return result.isEmpty() ? null : result.get(0); + } + + @Override + public <O> List<O> findMultipleResult(TopiaSqlQuery<O> query) throws TopiaException { + TopiaSQLQueryWork<O> work = new TopiaSQLQueryWork<O>(query, true); + hibernate.doWork(work); + final List<O> result = work.getResult(); + return result; + } + protected void checkClosed(String message) throws TopiaException { if (closed) { throw new TopiaException(message); @@ -1581,24 +1609,6 @@ } } - public static class SQLWork implements Work { - private final String script; - - public SQLWork(String script) { - this.script = script; - } - - @Override - public void execute(Connection connection) throws SQLException { - PreparedStatement sta = connection.prepareStatement(script); - try { - sta.execute(); - } finally { - sta.close(); - } - } - } - @Override public Session getHibernateSession() throws TopiaException { if (hibernate == null) { Deleted: trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java =================================================================== --- trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java 2013-11-22 21:20:24 UTC (rev 2890) +++ trunk/topia-persistence/src/main/java/org/nuiton/topia/framework/TopiaSQLQuery.java 2013-11-22 21:50:19 UTC (rev 2891) @@ -1,275 +0,0 @@ -/* - * #%L - * ToPIA :: Persistence - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2004 - 2010 CodeLutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Lesser Public License for more details. - * - * You should have received a copy of the GNU General Lesser Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.topia.framework; - -import org.hibernate.jdbc.Work; -import org.nuiton.topia.TopiaContext; -import org.nuiton.topia.TopiaException; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * An executor of sql query which permits to obtain a single result via - * the method {@link #findSingleResult(TopiaContext)} - * or a multiple result with method {@link #findMultipleResult(TopiaContext)}. - * - * @param <O> the type of result data - * @since 2.5 - */ -public abstract class TopiaSQLQuery<O> { - - /** - * Prepare the statement used to do the sql query. - * - * @param connection jdbc connection to use - * @return the statement containing the query to execute - * @throws SQLException if any problem - */ - protected abstract PreparedStatement prepareQuery(Connection connection) throws SQLException; - - /** - * given a result set, extract the data. - * - * @param set the result set - * @return the data extracted from the current set, or {@code null} - * @throws SQLException if any prob - */ - protected abstract O prepareResult(ResultSet set) throws SQLException; - - /** - * Obtain a single result from the builded sql query. - * - * @param tx the transaction used to execute the query. - * @return the single result or {@code null} if none found. - * @throws TopiaException for any pb - * @deprecated since 3.0, use now {@link #findSingleResult(TopiaContext)}. - */ - @Deprecated - public O findSingleResult(TopiaContextImplementor tx) throws TopiaException { - return findSingleResult((TopiaContext) tx); - } - - /** - * Obtain a single result from the builded sql query. - * - * @param tx the transaction used to execute the query. - * @return the single result or {@code null} if none found. - * @throws TopiaException for any pb - */ - public O findSingleResult(TopiaContext tx) throws TopiaException { - final List<O> result = new ArrayList<O>(); - - tx.getHibernateSession().doWork(new Work() { - - @Override - public void execute(Connection connection) throws SQLException { - - PreparedStatement ps = prepareQuery(connection); - - try { - ResultSet set = ps.executeQuery(); - - findSingleResult(result, set); - - } catch (Exception e) { - throw new TopiaException("Could not execute query", e); - } finally { - ps.close(); - } - } - }); - return result.isEmpty() ? null : result.get(0); - } - - /** - * Obtain a multiple results fro the builded sql query. - * - * @param tx the transaction used to execute the query. - * @return the list of results (the list is empty if non result is found). - * @throws TopiaException for any pb - * @deprecated since 3.0, use now {@link #findMultipleResult(TopiaContext)}. - */ - @Deprecated - public List<O> findMultipleResult(TopiaContextImplementor tx) throws TopiaException { - return findMultipleResult((TopiaContext) tx); - } - - /** - * Obtain a multiple results fro the builded sql query. - * - * @param tx the transaction used to execute the query. - * @return the list of results (the list is empty if non result is found). - * @throws TopiaException for any pb - */ - public List<O> findMultipleResult(TopiaContext tx) throws TopiaException { - final List<O> result = new ArrayList<O>(); - - tx.getHibernateSession().doWork(new Work() { - - @Override - public void execute(Connection connection) throws SQLException { - - PreparedStatement ps = prepareQuery(connection); - try { - ResultSet set = ps.executeQuery(); - - findMultipleResult(result, set); - - } catch (Exception e) { - throw new TopiaException("Could not execute query", e); - } finally { - ps.close(); - } - } - }); - return result; - } - - /** - * A hook to obtain the result set just after the query execute. - * - * @param set the result set just obtained - * @throws SQLException if any prob - * @since 2.6.4 - */ - protected void afterExecuteQuery(ResultSet set) throws SQLException { - // by default do nothing - } - - /** - * Obtain a single result given the result set and push in in the result list. - * - * @param result the result list - * @param set the set of the executed sql query - * @throws SQLException if any pb - * @since 2.6.4 - */ - protected void findSingleResult(List<O> result, - ResultSet set) throws SQLException { - - afterExecuteQuery(set); - - if (set.next()) { - O singleResult = prepareResult(set); - if (singleResult != null) { - result.add(singleResult); - } - } - } - - /** - * Obtain a multi result given the result set and push in in the result list. - * - * @param result the result list - * @param set the set of the executed sql query - * @throws SQLException if any pb - * @since 2.6.4 - */ - protected void findMultipleResult(List<O> result, - ResultSet set) throws SQLException { - - afterExecuteQuery(set); - - while (set.next()) { - O singleResult = prepareResult(set); - - if (singleResult != null) { - result.add(singleResult); - } - } - } - - /** - * Obtain the column names of a given result set using his metadata. - * - * @param set the result set to inspect - * @return the column names of the result set - * @throws SQLException if any pb - * @since 2.6.4 - */ - protected String[] getColumnNames(ResultSet set) throws SQLException { - ResultSetMetaData metaData = set.getMetaData(); - int columnCount = metaData.getColumnCount(); - String[] result = new String[columnCount]; - for (int i = 0; i < columnCount; i++) { - result[i] = metaData.getColumnName(i + 1); - } - return result; - } - - /** - * From a given result set, let's count his number of row. - * <p/> - * <strong>Note:</strong> the result set must be scrollable to go back to - * before first row. - * - * @param set the result set to inspect - * @return the number of row of the given result set - * @throws SQLException if any pb - * @since 2.6.4 - */ - protected long getNbRows(ResultSet set) throws SQLException { - - long nbRows = 0; - while (set.next()) { - nbRows++; - } - // go back before first row (be ware the resultset must be scrollable) - set.beforeFirst(); - return nbRows; - } - - /** - * Given the column names of the result set, transform the row of the - * result set to a map with column name as key. - * - * @param columnNames column names of the result set - * @param set the set to inspect - * @return the map for the given row of the result set - * @throws SQLException if any pb - * @since 2.6.4 - */ - protected Map<String, Object> getRowAsMap(String[] columnNames, - ResultSet set) throws SQLException { - - Map<String, Object> result = new LinkedHashMap<String, Object>(); - int length = columnNames.length; - for (int i = 0; i < length; i++) { - String name = columnNames[i]; - Object value = set.getObject(i + 1); - result.put(name, value); - } - return result; - } - -}
participants (1)
-
tchemit@users.nuiton.org