Die effizienteste Konvertierung von ResultSet in JSON?

109

Der folgende Code konvertiert a ResultSetmit JSONArrayund in eine JSON-Zeichenfolge JSONObject.

import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;

import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

public class ResultSetConverter {
  public static JSONArray convert( ResultSet rs )
    throws SQLException, JSONException
  {
    JSONArray json = new JSONArray();
    ResultSetMetaData rsmd = rs.getMetaData();

    while(rs.next()) {
      int numColumns = rsmd.getColumnCount();
      JSONObject obj = new JSONObject();

      for (int i=1; i<numColumns+1; i++) {
        String column_name = rsmd.getColumnName(i);

        if(rsmd.getColumnType(i)==java.sql.Types.ARRAY){
         obj.put(column_name, rs.getArray(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.BIGINT){
         obj.put(column_name, rs.getInt(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.BOOLEAN){
         obj.put(column_name, rs.getBoolean(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.BLOB){
         obj.put(column_name, rs.getBlob(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.DOUBLE){
         obj.put(column_name, rs.getDouble(column_name)); 
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.FLOAT){
         obj.put(column_name, rs.getFloat(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.INTEGER){
         obj.put(column_name, rs.getInt(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.NVARCHAR){
         obj.put(column_name, rs.getNString(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.VARCHAR){
         obj.put(column_name, rs.getString(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.TINYINT){
         obj.put(column_name, rs.getInt(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.SMALLINT){
         obj.put(column_name, rs.getInt(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.DATE){
         obj.put(column_name, rs.getDate(column_name));
        }
        else if(rsmd.getColumnType(i)==java.sql.Types.TIMESTAMP){
        obj.put(column_name, rs.getTimestamp(column_name));   
        }
        else{
         obj.put(column_name, rs.getObject(column_name));
        }
      }

      json.put(obj);
    }

    return json;
  }
}
  • Gibt es einen schnelleren Weg?
  • Gibt es einen Weg, der weniger Speicher benötigt?
Devin Dixon
quelle
1
Eine andere Implementierung code.google.com/p/bonex-homerunning/source/browse/trunk/…
Leif Gruenwoldt
1
Die Implementierung für java.sql.Types.ARRAY hat bei mir mit postgresql nicht funktioniert (Array wurde mit "{...}" als String eingefügt. Am Ende wurde die Zeile "obj.put (Spaltenname, rs.getArray (Spaltenname)) geändert. ); "to" Array array = rs.getArray (Spaltenname); if (Array! = null) obj.put (Spaltenname, neues JSONArray (array.getArray ())); "
Molecular
Wenn die Leistung ein großes Problem darstellt, sollten Sie diese JSON-API nicht verwenden, sondern eine Streaming-Bibliothek verwenden, die nur JSON schreibt, ohne Speicherobjekte aller Daten erstellen zu müssen (wo Sie in der Baumstruktur zurückblicken / Dinge finden können). Trotzdem würde ich sicherstellen, dass Sie tatsächlich ein Leistungsproblem haben, bevor Sie dies tun.
Sebastiaan van den Broek
3
In Ihrem Snippet ist ein Fehler aufgetreten. java.sql.Types.BIGINTist 8 Bytes groß, also muss es mit rs.getLong()notrs.getInt()
polarfish
3
Vielen Dank für das Laden. Sie haben mir gerade Arbeitsstunden gespart.
DRich

Antworten:

23

Der JIT-Compiler wird dies wahrscheinlich ziemlich schnell machen, da es sich nur um Verzweigungen und grundlegende Tests handelt. Sie könnten es wahrscheinlich eleganter machen, wenn Sie eine HashMap-Suche nach einem Rückruf durchführen, aber ich bezweifle, dass es schneller gehen würde. Das Gedächtnis ist so ziemlich schlank wie es ist.

Irgendwie bezweifle ich, dass dieser Code tatsächlich ein kritischer Flaschenhals für das Gedächtnis oder die Leistung ist. Haben Sie einen wirklichen Grund, es zu optimieren?

Andrew White
quelle
Ich stelle den Quellcode in ein Open-Source-Framework, daher weiß ich nicht, wofür er verwendet wird. Deshalb versuche ich es so effizient wie möglich zu machen.
Devin Dixon
1
@ DevinDixon: Ist das Framework verfügbar? Gibt es so etwas wie den Code in Ihrer Frage, der bereits irgendwo in einem Open-Source-Repo verfügbar ist?
34

Ich denke, es gibt eine Möglichkeit, weniger Speicher zu verwenden (eine feste und nicht lineare Menge, abhängig von der Datenkardinalität), aber dies bedeutet, die Methodensignatur zu ändern. Tatsächlich können wir die Json-Daten direkt in einem Ausgabestream drucken, sobald wir sie aus dem ResultSet abrufen: Die bereits geschriebenen Daten werden durch Müll gesammelt, da wir kein Array benötigen, das sie im Speicher hält.

Ich verwende GSON, das Typadapter akzeptiert. Ich habe einen Typadapter geschrieben, um ResultSet in JsonArray zu konvertieren, und es sieht Ihrem Code sehr ähnlich. Ich warte auf die Version "Gson 2.1: Targeted Dec 31, 2011", die "Unterstützung für benutzerdefinierte Streaming-Typ-Adapter" bietet. Dann werde ich meinen Adapter so ändern, dass er ein Streaming-Adapter ist.


Aktualisieren

Wie versprochen bin ich zurück, aber nicht mit Gson, sondern mit Jackson 2. Tut mir leid, dass ich zu spät komme (von 2 Jahren).

Vorwort: Der Schlüssel, um weniger Speicher für das Ergebnis zu verwenden, befindet sich im "serverseitigen" Cursor. Mit dieser Art von Cursorn (auch als Ergebnismenge für Java-Entwickler bezeichnet) sendet das DBMS Daten inkrementell an den Client (auch als Treiber bezeichnet), während der Client mit dem Lesen fortfährt. Ich denke, Oracle-Cursor sind standardmäßig serverseitig. Suchen Sie für MySQL> 5.0.2 im Verbindungs-URL- Parameter nach useCursorFetch . Überprüfen Sie Ihr Lieblings-DBMS.

1: Um weniger Speicher zu verwenden, müssen wir:

  • Verwenden Sie den serverseitigen Cursor hinter den Kulissen
  • Verwenden Sie die geöffnete Ergebnismenge als schreibgeschützt und natürlich nur als Weiterleitung .
  • Vermeiden Sie es, den gesamten Cursor in eine Liste (oder a JSONArray) zu laden, sondern schreiben Sie jede Zeile direkt in eine Ausgabezeile , wobei ich für die Ausgabezeile einen Ausgabestream oder einen Writer oder auch einen JSON-Generator meine, der einen Ausgabestream oder einen Writer umschließt.

2: Wie Jackson Documentation sagt:

Die Streaming-API bietet die beste Leistung (geringster Overhead, schnellstes Lesen / Schreiben; andere 2 darauf aufbauende Methoden)

3: Ich sehe dich in deinem Code, benutze getInt, getBoolean. getFloat ... von ResultSet ohne wasNull . Ich gehe davon aus, dass dies zu Problemen führen kann.

4: Ich habe Arrays verwendet, um Gedanken zwischenzuspeichern und zu vermeiden, bei jeder Iteration Getter aufzurufen. Obwohl ich kein Fan des Switch / Case-Konstrukts bin, habe ich es für dieses intSQL verwendet Types.

Die Antwort: Noch nicht vollständig getestet, basiert es auf Jackson 2.2 :

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.2.2</version>
</dependency>

Das ResultSetSerializerObjekt weist Jackson an, wie ein ResultSet serialisiert (das Objekt in JSON umgewandelt) wird. Es verwendet die Jackson Streaming API im Inneren. Hier der Code eines Tests:

SimpleModule module = new SimpleModule();
module.addSerializer(new ResultSetSerializer());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);

[ . . . do the query . . . ]
ResultSet resultset = statement.executeQuery(query);

// Use the DataBind Api here
ObjectNode objectNode = objectMapper.createObjectNode();

// put the resultset in a containing structure
objectNode.putPOJO("results", resultset);

// generate all
objectMapper.writeValue(stringWriter, objectNode);

Und natürlich den Code der ResultSetSerializer-Klasse:

public class ResultSetSerializer extends JsonSerializer<ResultSet> {

    public static class ResultSetSerializerException extends JsonProcessingException{
        private static final long serialVersionUID = -914957626413580734L;

        public ResultSetSerializerException(Throwable cause){
            super(cause);
        }
    }

    @Override
    public Class<ResultSet> handledType() {
        return ResultSet.class;
    }

    @Override
    public void serialize(ResultSet rs, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {

        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            int numColumns = rsmd.getColumnCount();
            String[] columnNames = new String[numColumns];
            int[] columnTypes = new int[numColumns];

            for (int i = 0; i < columnNames.length; i++) {
                columnNames[i] = rsmd.getColumnLabel(i + 1);
                columnTypes[i] = rsmd.getColumnType(i + 1);
            }

            jgen.writeStartArray();

            while (rs.next()) {

                boolean b;
                long l;
                double d;

                jgen.writeStartObject();

                for (int i = 0; i < columnNames.length; i++) {

                    jgen.writeFieldName(columnNames[i]);
                    switch (columnTypes[i]) {

                    case Types.INTEGER:
                        l = rs.getInt(i + 1);
                        if (rs.wasNull()) {
                            jgen.writeNull();
                        } else {
                            jgen.writeNumber(l);
                        }
                        break;

                    case Types.BIGINT:
                        l = rs.getLong(i + 1);
                        if (rs.wasNull()) {
                            jgen.writeNull();
                        } else {
                            jgen.writeNumber(l);
                        }
                        break;

                    case Types.DECIMAL:
                    case Types.NUMERIC:
                        jgen.writeNumber(rs.getBigDecimal(i + 1));
                        break;

                    case Types.FLOAT:
                    case Types.REAL:
                    case Types.DOUBLE:
                        d = rs.getDouble(i + 1);
                        if (rs.wasNull()) {
                            jgen.writeNull();
                        } else {
                            jgen.writeNumber(d);
                        }
                        break;

                    case Types.NVARCHAR:
                    case Types.VARCHAR:
                    case Types.LONGNVARCHAR:
                    case Types.LONGVARCHAR:
                        jgen.writeString(rs.getString(i + 1));
                        break;

                    case Types.BOOLEAN:
                    case Types.BIT:
                        b = rs.getBoolean(i + 1);
                        if (rs.wasNull()) {
                            jgen.writeNull();
                        } else {
                            jgen.writeBoolean(b);
                        }
                        break;

                    case Types.BINARY:
                    case Types.VARBINARY:
                    case Types.LONGVARBINARY:
                        jgen.writeBinary(rs.getBytes(i + 1));
                        break;

                    case Types.TINYINT:
                    case Types.SMALLINT:
                        l = rs.getShort(i + 1);
                        if (rs.wasNull()) {
                            jgen.writeNull();
                        } else {
                            jgen.writeNumber(l);
                        }
                        break;

                    case Types.DATE:
                        provider.defaultSerializeDateValue(rs.getDate(i + 1), jgen);
                        break;

                    case Types.TIMESTAMP:
                        provider.defaultSerializeDateValue(rs.getTime(i + 1), jgen);
                        break;

                    case Types.BLOB:
                        Blob blob = rs.getBlob(i);
                        provider.defaultSerializeValue(blob.getBinaryStream(), jgen);
                        blob.free();
                        break;

                    case Types.CLOB:
                        Clob clob = rs.getClob(i);
                        provider.defaultSerializeValue(clob.getCharacterStream(), jgen);
                        clob.free();
                        break;

                    case Types.ARRAY:
                        throw new RuntimeException("ResultSetSerializer not yet implemented for SQL type ARRAY");

                    case Types.STRUCT:
                        throw new RuntimeException("ResultSetSerializer not yet implemented for SQL type STRUCT");

                    case Types.DISTINCT:
                        throw new RuntimeException("ResultSetSerializer not yet implemented for SQL type DISTINCT");

                    case Types.REF:
                        throw new RuntimeException("ResultSetSerializer not yet implemented for SQL type REF");

                    case Types.JAVA_OBJECT:
                    default:
                        provider.defaultSerializeValue(rs.getObject(i + 1), jgen);
                        break;
                    }
                }

                jgen.writeEndObject();
            }

            jgen.writeEndArray();

        } catch (SQLException e) {
            throw new ResultSetSerializerException(e);
        }
    }
}
Plap
quelle
27

Zwei Dinge, die dies beschleunigen, sind:

Verschieben Sie Ihren Anruf rsmd.getColumnCount()aus der while-Schleife. Die Spaltenanzahl sollte nicht zwischen den Zeilen variieren.

Für jeden Spaltentyp rufen Sie am Ende Folgendes auf:

obj.put(column_name, rs.getInt(column_name));

Die Verwendung des Spaltenindex zum Abrufen des Spaltenwerts ist etwas schneller:

obj.put(column_name, rs.getInt(i));
oravecz
quelle
Definieren Sie auch String column_name;außerhalb der while-Schleife.
Charney Kaye
22

Eine einfachere Lösung (basierend auf dem fraglichen Code):

JSONArray json = new JSONArray();
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()) {
  int numColumns = rsmd.getColumnCount();
  JSONObject obj = new JSONObject();
  for (int i=1; i<=numColumns; i++) {
    String column_name = rsmd.getColumnName(i);
    obj.put(column_name, rs.getObject(column_name));
  }
  json.put(obj);
}
return json;
Elhanan Mishraky
quelle
3
schön, aber es gibt einen Fehler mit DATETIME und TIMESTAMP (es werden keine Apostrophe
hinzugefügt
nett und einfach
Anoop LL
10

Sie können jOOQ für den Job verwenden. Sie müssen nicht alle Funktionen von jOOQ verwenden, um einige nützliche JDBC-Erweiterungen nutzen zu können. In diesem Fall schreiben Sie einfach:

String json = DSL.using(connection).fetch(resultSet).formatJSON();

Relevante verwendete API-Methoden sind:

Die resultierende Formatierung sieht folgendermaßen aus:

{"fields":[{"name":"field-1","type":"type-1"},
           {"name":"field-2","type":"type-2"},
           ...,
           {"name":"field-n","type":"type-n"}],
 "records":[[value-1-1,value-1-2,...,value-1-n],
            [value-2-1,value-2-2,...,value-2-n]]}

Sie können auch ganz einfach Ihre eigene Formatierung erstellen Result.map(RecordMapper)

Dies entspricht im Wesentlichen Ihrem Code, indem die Generierung von JSON-Objekten umgangen und direkt in a "gestreamt" wird StringBuilder. Ich würde jedoch sagen, dass der Leistungsaufwand in beiden Fällen vernachlässigbar sein sollte.

(Haftungsausschluss: Ich arbeite für das Unternehmen hinter jOOQ)

Lukas Eder
quelle
Das ist großartig, aber ich habe Probleme beim Parsen der resultierenden Zeichenfolge. Wenn einige der Werte ein Anführungszeichen der Parser kann enthalten nicht korrekt funktionieren: Ich denke , dass die Anführungszeichen innerhalb Werte sollten (entwertet werden "zu \"), um einen gültigen JSON - String zu erstellen. Ist das ein Fehler der formatJSON()Funktion? Oder fehlt mir etwas?
Oneiros
@Oneiros: jOOQ sollte diese Anführungszeichen korrekt umgehen ... Stellen Sie am besten eine neue Frage (mit Details) oder melden Sie einen Fehler: github.com/jOOQ/jOOQ/issues/new
Lukas Eder
In welchem ​​Beispiel wird resultSet verwendet fetch(resultSet)? Es ist nirgendwo definiert. Und wenn ich JDBC ResultSetvor dem Abrufen bekomme, wozu dient das dann DSL.using(connection)? Warum braucht es eine Verbindung? :)
Nikola Lošić
1
@ NikolaLošić: Nun, die Frage fragt nach der Verwendung eines JDBC ResultSet, also denke ich, dass es keinen Zweifel gibt ResultSet. In der Tat sieht es nicht offensichtlich aus, warum das connectionhier benötigt wird. Wenn Sie jOOQ verwenden, steht Ihnen jedoch ohnehin ein DSLContext(Ergebnis DSL.using(connection)oder ähnliches) Herumsitzen zur Verfügung.
Lukas Eder
Was ist die richtige JOOQ-Bibliothek? Ich versuche viele, aber jeder gibt mir Klasse nicht gefunden Fehler mit DSL-Referenz. Thnks
Lorenzo Barbagli
7

Zusätzlich zu den Vorschlägen von @Jim Cook. Ein anderer Gedanke ist, einen Schalter anstelle von if-elses zu verwenden:

while(rs.next()) {
  int numColumns = rsmd.getColumnCount();
  JSONObject obj = new JSONObject();

  for( int i=1; i<numColumns+1; i++) {
    String column_name = rsmd.getColumnName(i);

    switch( rsmd.getColumnType( i ) ) {
      case java.sql.Types.ARRAY:
        obj.put(column_name, rs.getArray(column_name));     break;
      case java.sql.Types.BIGINT:
        obj.put(column_name, rs.getInt(column_name));       break;
      case java.sql.Types.BOOLEAN:
        obj.put(column_name, rs.getBoolean(column_name));   break;
      case java.sql.Types.BLOB:
        obj.put(column_name, rs.getBlob(column_name));      break;
      case java.sql.Types.DOUBLE:
        obj.put(column_name, rs.getDouble(column_name));    break;
      case java.sql.Types.FLOAT:
        obj.put(column_name, rs.getFloat(column_name));     break;
      case java.sql.Types.INTEGER:
        obj.put(column_name, rs.getInt(column_name));       break;
      case java.sql.Types.NVARCHAR:
        obj.put(column_name, rs.getNString(column_name));   break;
      case java.sql.Types.VARCHAR:
        obj.put(column_name, rs.getString(column_name));    break;
      case java.sql.Types.TINYINT:
        obj.put(column_name, rs.getInt(column_name));       break;
      case java.sql.Types.SMALLINT:
        obj.put(column_name, rs.getInt(column_name));       break;
      case java.sql.Types.DATE:
        obj.put(column_name, rs.getDate(column_name));      break;
      case java.sql.Types.TIMESTAMP:
        obj.put(column_name, rs.getTimestamp(column_name)); break;
      default:
        obj.put(column_name, rs.getObject(column_name));    break;
    }
  }

  json.put(obj);
}
Vanderwyst
quelle
4
Das Zurückschleifen (Vergleichen des Index Null) ist ebenfalls schneller (als das Vergleichen des Index mit einem Ausdruck).
Dave Jarvis
4

Diese Antwort ist vielleicht nicht die effizienteste, aber sie ist sicher dynamisch. Durch die Kombination von nativem JDBC mit der Gson-Bibliothek von Google kann ich problemlos von einem SQL-Ergebnis in einen JSON-Stream konvertieren.

Ich habe den Konverter, eine Beispiel-DB-Eigenschaftendatei, eine SQL-Tabellengenerierung und eine Gradle-Build-Datei (mit verwendeten Abhängigkeiten) hinzugefügt.

QueryApp.java

import java.io.PrintWriter;

import com.oracle.jdbc.ResultSetConverter;

public class QueryApp {
    public static void main(String[] args) {
        PrintWriter writer = new PrintWriter(System.out);
        String dbProps = "/database.properties";
        String indent = "    ";

        writer.println("Basic SELECT:");
        ResultSetConverter.queryToJson(writer, dbProps, "SELECT * FROM Beatles", indent, false);

        writer.println("\n\nIntermediate SELECT:");
        ResultSetConverter.queryToJson(writer, dbProps, "SELECT first_name, last_name, getAge(date_of_birth) as age FROM Beatles", indent, true);
    }
}

ResultSetConverter.java

package com.oracle.jdbc;

import java.io.*;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.*;

import com.google.common.reflect.TypeToken;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonWriter;

public class ResultSetConverter {
    public static final Type RESULT_TYPE = new TypeToken<List<Map<String, Object>>>() {
        private static final long serialVersionUID = -3467016635635320150L;
    }.getType();

    public static void queryToJson(Writer writer, String connectionProperties, String query, String indent, boolean closeWriter) {
        Connection conn = null;
        Statement stmt = null;
        GsonBuilder gson = new GsonBuilder();
        JsonWriter jsonWriter = new JsonWriter(writer);

        if (indent != null) jsonWriter.setIndent(indent);

        try {
            Properties props = readConnectionInfo(connectionProperties);
            Class.forName(props.getProperty("driver"));

            conn = openConnection(props);
            stmt = conn.createStatement();

            gson.create().toJson(QueryHelper.select(stmt, query), RESULT_TYPE, jsonWriter);

            if (closeWriter) jsonWriter.close();

            stmt.close();
            conn.close();
        } catch (SQLException se) {
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
            try {
                if (stmt != null) stmt.close();
            } catch (SQLException se2) {
            }
            try {
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
            try {
                if (closeWriter && jsonWriter != null) jsonWriter.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }

    private static Properties readConnectionInfo(String resource) throws IOException {
        Properties properties = new Properties();
        InputStream in = ResultSetConverter.class.getResourceAsStream(resource);
        properties.load(in);
        in.close();

        return properties;
    }

    private static Connection openConnection(Properties connectionProperties) throws IOException, SQLException {
        String database = connectionProperties.getProperty("database");
        String username = connectionProperties.getProperty("username");
        String password = connectionProperties.getProperty("password");

        return DriverManager.getConnection(database, username, password);
    }
}

QueryHelper.java

package com.oracle.jdbc;

import java.sql.*;
import java.text.*;
import java.util.*;

import com.google.common.base.CaseFormat;

public class QueryHelper {
    static DateFormat DATE_FORMAT = new SimpleDateFormat("YYYY-MM-dd");

    public static List<Map<String, Object>> select(Statement stmt, String query) throws SQLException {
        ResultSet resultSet = stmt.executeQuery(query);
        List<Map<String, Object>> records = mapRecords(resultSet);

        resultSet.close();

        return records;
    }

    public static List<Map<String, Object>> mapRecords(ResultSet resultSet) throws SQLException {
        List<Map<String, Object>> records = new ArrayList<Map<String, Object>>();
        ResultSetMetaData metaData = resultSet.getMetaData();

        while (resultSet.next()) {
            records.add(mapRecord(resultSet, metaData));
        }

        return records;
    }

    public static Map<String, Object> mapRecord(ResultSet resultSet, ResultSetMetaData metaData) throws SQLException {
        Map<String, Object> record = new HashMap<String, Object>();

        for (int c = 1; c <= metaData.getColumnCount(); c++) {
            String columnType = metaData.getColumnTypeName(c);
            String columnName = formatPropertyName(metaData.getColumnName(c));
            Object value = resultSet.getObject(c);

            if (columnType.equals("DATE")) {
                value = DATE_FORMAT.format(value);
            }

            record.put(columnName, value);
        }

        return record;
    }

    private static String formatPropertyName(String property) {
        return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, property);
    }
}

database.properties

driver=com.mysql.jdbc.Driver
database=jdbc:mysql://localhost/JDBC_Tutorial
username=root
password=

JDBC_Tutorial.sql

-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: Jan 12, 2016 at 07:40 PM
-- Server version: 10.1.8-MariaDB
-- PHP Version: 5.6.14

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `jdbc_tutorial`
--
CREATE DATABASE IF NOT EXISTS `jdbc_tutorial` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `jdbc_tutorial`;

DELIMITER $$
--
-- Functions
--
DROP FUNCTION IF EXISTS `getAge`$$
CREATE DEFINER=`root`@`localhost` FUNCTION `getAge` (`in_dob` DATE) RETURNS INT(11) NO SQL
BEGIN
DECLARE l_age INT;
   IF DATE_FORMAT(NOW(),'00-%m-%d') >= DATE_FORMAT(in_dob,'00-%m-%d') THEN
      -- This person has had a birthday this year
      SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y');
   ELSE
      -- Yet to have a birthday this year
      SET l_age=DATE_FORMAT(NOW(),'%Y')-DATE_FORMAT(in_dob,'%Y')-1;
   END IF;
      RETURN(l_age);
END$$

DELIMITER ;

-- --------------------------------------------------------

--
-- Table structure for table `beatles`
--

DROP TABLE IF EXISTS `beatles`;
CREATE TABLE IF NOT EXISTS `beatles` (
  `id` int(11) NOT NULL,
  `first_name` varchar(255) DEFAULT NULL,
  `last_name` varchar(255) DEFAULT NULL,
  `date_of_birth` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Truncate table before insert `beatles`
--

TRUNCATE TABLE `beatles`;
--
-- Dumping data for table `beatles`
--

INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(100, 'John', 'Lennon', '1940-10-09');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(101, 'Paul', 'McCartney', '1942-06-18');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(102, 'George', 'Harrison', '1943-02-25');
INSERT INTO `beatles` (`id`, `first_name`, `last_name`, `date_of_birth`) VALUES(103, 'Ringo', 'Starr', '1940-07-07');

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

build.gradle

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'

mainClassName = 'com.oracle.jdbc.QueryApp'

repositories {
    maven  {
        url "http://repo1.maven.org/maven2"
    }
}

jar {
    baseName = 'jdbc-tutorial'
    version =  '1.0.0'
}

sourceCompatibility = 1.7
targetCompatibility = 1.7

dependencies {
    compile 'mysql:mysql-connector-java:5.1.16'
    compile 'com.google.guava:guava:18.0'
    compile 'com.google.code.gson:gson:1.7.2'
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.9'
}

Ergebnisse

Grundlegende SELECT

[
    {
        "firstName": "John",
        "lastName": "Lennon",
        "dateOfBirth": "1940-10-09",
        "id": 100
    },
    {
        "firstName": "Paul",
        "lastName": "McCartney",
        "dateOfBirth": "1942-06-18",
        "id": 101
    },
    {
        "firstName": "George",
        "lastName": "Harrison",
        "dateOfBirth": "1943-02-25",
        "id": 102
    },
    {
        "firstName": "Ringo",
        "lastName": "Starr",
        "dateOfBirth": "1940-07-07",
        "id": 103
    }
]

Intermediate SELECT

[
    {
        "firstName": "John",
        "lastName": "Lennon",
        "age": 75
    },
    {
        "firstName": "Paul",
        "lastName": "McCartney",
        "age": 73
    },
    {
        "firstName": "George",
        "lastName": "Harrison",
        "age": 72
    },
    {
        "firstName": "Ringo",
        "lastName": "Starr",
        "age": 75
    }
]
Mr. Polywhirl
quelle
3

Erste vorgenerierte Spaltennamen, zweite Verwendung rs.getString(i)anstelle von rs.getString(column_name).

Das Folgende ist eine Implementierung davon:

    /*
     * Convert ResultSet to a common JSON Object array
     * Result is like: [{"ID":"1","NAME":"Tom","AGE":"24"}, {"ID":"2","NAME":"Bob","AGE":"26"}, ...]
     */
    public static List<JSONObject> getFormattedResult(ResultSet rs) {
        List<JSONObject> resList = new ArrayList<JSONObject>();
        try {
            // get column names
            ResultSetMetaData rsMeta = rs.getMetaData();
            int columnCnt = rsMeta.getColumnCount();
            List<String> columnNames = new ArrayList<String>();
            for(int i=1;i<=columnCnt;i++) {
                columnNames.add(rsMeta.getColumnName(i).toUpperCase());
            }

            while(rs.next()) { // convert each object to an human readable JSON object
                JSONObject obj = new JSONObject();
                for(int i=1;i<=columnCnt;i++) {
                    String key = columnNames.get(i - 1);
                    String value = rs.getString(i);
                    obj.put(key, value);
                }
                resList.add(obj);
            }
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return resList;
    }
coderz
quelle
Wie greife ich auf das Objekt zu und verwende es? Angenommen, ich möchte die gesamte Spalte Name drucken. Ist das Objekt für CRUD-Operationen leicht verfügbar?
Prathamesh Dhanawade
@Prathameshdhanawade Mit dieser Methode wird JDBC ResultSet in ein JSON-Array umgewandelt. Entwickler verwenden normalerweise kein unformatiertes JDBC-Ergebnisset, sondern konvertieren es normalerweise in eine Liste von Java-Objekten, dh in ein JSON-Objekt. Sie sehen, dass der Rückgabewert ein Array von JSON-Objekten ist. Sie können problemlos auf ein Objekt zugreifen. JSONObject json = resList.get(i);Anschließend können Sie das JSON-Objekt bearbeiten json.
Coderz
Eigentlich brauche ich das Objekt, um eine grafische Ansicht zu erstellen. Ich bin nur neugierig, ob ich das Objekt manipulieren kann. Danke.
Prathamesh Dhanawade
Könnten Sie bitte "grafische Ansicht" beschreiben? Oder ein Beispiel gegeben?
Coderz
Ich versuche, den Spaltenwert wie folgt anzuzeigen: JSONObject obj = jsonList.get (1); System.out.println (obj.getString ("name") + "\ t" + obj.getString ("company")); Es wird jedoch ein Fehler als "org.json.JSONException: JSONObject [" name "] nicht gefunden" angezeigt.
Prathamesh Dhanawade
2

Wenn jemand diese Implementierung verwenden möchte , sollten Sie dies und das überprüfen

Dies ist meine Version dieses Konvertierungscodes:

public class ResultSetConverter {
public static JSONArray convert(ResultSet rs) throws SQLException,
        JSONException {
    JSONArray json = new JSONArray();
    ResultSetMetaData rsmd = rs.getMetaData();
    int numColumns = rsmd.getColumnCount();
    while (rs.next()) {

        JSONObject obj = new JSONObject();

        for (int i = 1; i < numColumns + 1; i++) {
            String column_name = rsmd.getColumnName(i);

            if (rsmd.getColumnType(i) == java.sql.Types.ARRAY) {
                obj.put(column_name, rs.getArray(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.BIGINT) {
                obj.put(column_name, rs.getLong(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.REAL) {
                obj.put(column_name, rs.getFloat(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.BOOLEAN) {
                obj.put(column_name, rs.getBoolean(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.BLOB) {
                obj.put(column_name, rs.getBlob(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.DOUBLE) {
                obj.put(column_name, rs.getDouble(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.FLOAT) {
                obj.put(column_name, rs.getDouble(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.INTEGER) {
                obj.put(column_name, rs.getInt(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.NVARCHAR) {
                obj.put(column_name, rs.getNString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.VARCHAR) {
                obj.put(column_name, rs.getString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.CHAR) {
                obj.put(column_name, rs.getString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.NCHAR) {
                obj.put(column_name, rs.getNString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.LONGNVARCHAR) {
                obj.put(column_name, rs.getNString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.LONGVARCHAR) {
                obj.put(column_name, rs.getString(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.TINYINT) {
                obj.put(column_name, rs.getByte(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.SMALLINT) {
                obj.put(column_name, rs.getShort(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.DATE) {
                obj.put(column_name, rs.getDate(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.TIME) {
                obj.put(column_name, rs.getTime(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.TIMESTAMP) {
                obj.put(column_name, rs.getTimestamp(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.BINARY) {
                obj.put(column_name, rs.getBytes(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.VARBINARY) {
                obj.put(column_name, rs.getBytes(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.LONGVARBINARY) {
                obj.put(column_name, rs.getBinaryStream(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.BIT) {
                obj.put(column_name, rs.getBoolean(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.CLOB) {
                obj.put(column_name, rs.getClob(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.NUMERIC) {
                obj.put(column_name, rs.getBigDecimal(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.DECIMAL) {
                obj.put(column_name, rs.getBigDecimal(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.DATALINK) {
                obj.put(column_name, rs.getURL(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.REF) {
                obj.put(column_name, rs.getRef(column_name));
            } else if (rsmd.getColumnType(i) == java.sql.Types.STRUCT) {
                obj.put(column_name, rs.getObject(column_name)); // must be a custom mapping consists of a class that implements the interface SQLData and an entry in a java.util.Map object.
            } else if (rsmd.getColumnType(i) == java.sql.Types.DISTINCT) {
                obj.put(column_name, rs.getObject(column_name)); // must be a custom mapping consists of a class that implements the interface SQLData and an entry in a java.util.Map object.
            } else if (rsmd.getColumnType(i) == java.sql.Types.JAVA_OBJECT) {
                obj.put(column_name, rs.getObject(column_name));
            } else {
                obj.put(column_name, rs.getString(i));
            }
        }

        json.put(obj);
    }

    return json;
}
}
Li3ro
quelle
2

Genau wie ein Heads-Up ist die if / then-Schleife effizienter als der Schalter für Aufzählungen. Wenn Sie den Schalter gegen die rohe Enum-Ganzzahl haben, ist er effizienter, aber gegen die Variable, wenn / dann effizienter ist, zumindest für Java 5, 6 und 7.

Dh aus irgendeinem Grund (nach einigen Leistungstests)

if (ordinalValue == 1) {
   ...
} else (ordinalValue == 2 {
   ... 
}

ist schneller als

switch( myEnum.ordinal() ) {
    case 1:
       ...
       break;
    case 2:
       ...
       break;
}

Ich sehe, dass ein paar Leute an mir zweifeln, also werde ich hier Code posten, damit Sie selbst den Unterschied sehen können, zusammen mit der Ausgabe, die ich von Java 7 habe. Die Ergebnisse des folgenden Codes mit 10 Aufzählungswerten sind wie folgt. Beachten Sie, dass der Schlüssel hier das Wenn / Dann ist, das einen ganzzahligen Wert verwendet, der mit Ordnungskonstanten der Aufzählung verglichen wird, im Vergleich zum Schalter mit dem Ordnungswert einer Aufzählung gegen die rohen Ordnungswerte im Vergleich zu einem Schalter mit der Aufzählung gegen jeden Aufzählungsnamen. Das if / then mit einem ganzzahligen Wert schlug beide anderen Schalter aus, obwohl der letzte Schalter etwas schneller als der erste Schalter war, war er nicht schneller als der if / else.

Wenn / sonst 23 ms
dauerte Switch dauerte 45 ms
Switch 2 dauerte 30 ms
Gesamtübereinstimmungen: 3000000

package testing;

import java.util.Random;

enum TestEnum {
    FIRST,
    SECOND,
    THIRD,
    FOURTH,
    FIFTH,
    SIXTH,
    SEVENTH,
    EIGHTH,
    NINTH,
    TENTH
}

public class SwitchTest {
    private static int LOOP = 1000000;
    private static Random r = new Random();
    private static int SIZE = TestEnum.values().length;

    public static void main(String[] args) {
        long time = System.currentTimeMillis();
        int matches = 0;
        for (int i = 0; i < LOOP; i++) {
            int j = r.nextInt(SIZE);
            if (j == TestEnum.FIRST.ordinal()) {
                matches++;
            } else if (j == TestEnum.SECOND.ordinal()) {
                matches++;
            } else if (j == TestEnum.THIRD.ordinal()) {
                matches++;
            } else if (j == TestEnum.FOURTH.ordinal()) {
                matches++;
            } else if (j == TestEnum.FIFTH.ordinal()) {
                matches++;
            } else if (j == TestEnum.SIXTH.ordinal()) {
                matches++;
            } else if (j == TestEnum.SEVENTH.ordinal()) {
                matches++;
            } else if (j == TestEnum.EIGHTH.ordinal()) {
                matches++;
            } else if (j == TestEnum.NINTH.ordinal()) {
                matches++;
            } else {
                matches++;
            }
        }
        System.out.println("If / else took "+(System.currentTimeMillis() - time)+" ms");
        time = System.currentTimeMillis();
        for (int i = 0; i < LOOP; i++) {
            TestEnum te = TestEnum.values()[r.nextInt(SIZE)];
            switch (te.ordinal()) {
                case 0:
                    matches++;
                    break;
                case 1:
                    matches++;
                    break;
                case 2:
                    matches++;
                    break;
                case 3:
                    matches++;
                    break;
                case 4:
                    matches++;
                    break;
                case 5:
                    matches++;
                    break;
                case 6:
                    matches++;
                    break;
                case 7:
                    matches++;
                    break;
                case 8:
                    matches++;
                    break;
                case 9:
                    matches++;
                    break;
                default:
                    matches++;
                    break;
            }
        }
        System.out.println("Switch took "+(System.currentTimeMillis() - time)+" ms");
        time = System.currentTimeMillis();
        for (int i = 0; i < LOOP; i++) {
            TestEnum te = TestEnum.values()[r.nextInt(SIZE)];
            switch (te) {
                case FIRST:
                    matches++;
                    break;
                case SECOND:
                    matches++;
                    break;
                case THIRD:
                    matches++;
                    break;
                case FOURTH:
                    matches++;
                    break;
                case FIFTH:
                    matches++;
                    break;
                case SIXTH:
                    matches++;
                    break;
                case SEVENTH:
                    matches++;
                    break;
                case EIGHTH:
                    matches++;
                    break;
                case NINTH:
                    matches++;
                    break;
                default:
                    matches++;
                    break;
            }
        }
        System.out.println("Switch 2 took "+(System.currentTimeMillis() - time)+" ms");     
        System.out.println("Total matches: "+matches);
    }
}
Marcus
quelle
Nun, ok, aber ... die praktische Wahrheit ist, dass der Unterschied zwischen diesen Codierungsalternativen für jeden realen Anwendungsfall so gering ist, dass in einer realen Anwendung die Leistungsunterschiede zwischen ihnen höchstwahrscheinlich unermesslich gering wären. Machen Sie Ihren Code zuerst korrekt und dann (nur dann) schnell (wenn er schneller sein muss).
Scottb
Einverstanden, aber die Hauptfrage betraf den schnellsten und effizientesten Weg. Es gibt viele Stile, die das Lesen oder Verwalten von Code erschweren, aber effizienter sind, obwohl diese normalerweise zu einem späteren Zeitpunkt durch Compiler-Optimierungen behoben werden. Ein Beispiel hierfür ist die Verwendung von intern()für Zeichenfolgen, die in den meisten modernen Java-Versionen größtenteils nicht mehr benötigt werden.
Marcus
Einverstanden, aber wenn-dann-sonst und Switch-Case-Blöcke selbst sind in jedem Fall schlechte Lösungen für Probleme der Wartbarkeit, Robustheit und Lesbarkeit. Bei Aufzählungen, die Sie besitzen (oder deren Code Sie ändern können), empfiehlt es sich sehr oft, konstantenspezifische Methoden in einem umfangreichen Aufzählungstyp zu verwenden. In den meisten Fällen sollte das Einschalten einer Aufzählung mit Umsicht betrachtet werden, da es bessere gibt Lösungen da draußen.
Scottb
1

Für alle, die sich für die if-else-Netzlösung entschieden haben, verwenden Sie bitte:

String columnName = metadata.getColumnName(
String displayName = metadata.getColumnLabel(i);
switch (metadata.getColumnType(i)) {
case Types.ARRAY:
    obj.put(displayName, resultSet.getArray(columnName));
    break;
...

Denn bei Aliasen in Ihrer Abfrage sind der Spaltenname und die Spaltenbezeichnung zwei verschiedene Dinge. Zum Beispiel, wenn Sie ausführen:

select col1, col2 as my_alias from table

Sie erhalten

[
    { "col1": 1, "col2": 2 }, 
    { "col1": 1, "col2": 2 }
]

Eher, als:

[
    { "col1": 1, "my_alias": 2 }, 
    { "col1": 1, "my_alias": 2 }
]
seekme_94
quelle
0
package com.idal.cib;

import java.io.FileWriter;
import java.io.IOException;
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 org.json.simple.JSONArray;
import org.json.simple.JSONObject;

public class DBJsonConverter {

    static ArrayList<String> data = new ArrayList<String>();
    static Connection conn = null;
    static PreparedStatement ps = null;
    static ResultSet rs = null;
    static String path = "";
    static String driver="";
    static String url="";
    static String username="";
    static String password="";
    static String query="";

    @SuppressWarnings({ "unchecked" })
    public static void dataLoad(String path) {
        JSONObject obj1 = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        conn = DatabaseConnector.getDbConnection(driver, url, username,
                password);
        try {
            ps = conn.prepareStatement(query);
            rs = ps.executeQuery();
            ArrayList<String> columnNames = new ArrayList<String>();
            if (rs != null) {
                ResultSetMetaData columns = rs.getMetaData();
                int i = 0;
                while (i < columns.getColumnCount()) {
                    i++;
                    columnNames.add(columns.getColumnName(i));
                }
                while (rs.next()) {
                    JSONObject obj = new JSONObject();
                    for (i = 0; i < columnNames.size(); i++) {
                        data.add(rs.getString(columnNames.get(i)));
                        {
                            for (int j = 0; j < data.size(); j++) {
                                if (data.get(j) != null) {
                                    obj.put(columnNames.get(i), data.get(j));
                                }else {
                                    obj.put(columnNames.get(i), "");
                                }
                            }
                        }
                    }

                    jsonArray.add(obj);
                    obj1.put("header", jsonArray);
                    FileWriter file = new FileWriter(path);
                    file.write(obj1.toJSONString());
                    file.flush();
                    file.close();
                }
                ps.close();
            } else {
                JSONObject obj2 = new JSONObject();
                obj2.put(null, null);
                jsonArray.add(obj2);
                obj1.put("header", jsonArray);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                    rs.close();
                    ps.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressWarnings("static-access")
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        driver = "oracle.jdbc.driver.OracleDriver";
        url = "jdbc:oracle:thin:@localhost:1521:database";
        username = "user";
        password = "password";
        path = "path of file";
        query = "select * from temp_employee";

        DatabaseConnector dc = new DatabaseConnector();
        dc.getDbConnection(driver,url,username,password);
        DBJsonConverter formatter = new DBJsonConverter();
        formatter.dataLoad(path);

    }

}




package com.idal.cib;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DatabaseConnector {

    static Connection conn1 = null;

    public static Connection getDbConnection(String driver, String url,
            String username, String password) {
        // TODO Auto-generated constructor stub
        try {

            Class.forName(driver);

            conn1 = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn1;
    }

}
Prashant Chilwant
quelle
Bitte fügen Sie Ihrer Antwort eine Erklärung hinzu.
Sahil Mittal
0
public static JSONArray GetJSONDataFromResultSet(ResultSet rs) throws SQLException {
    ResultSetMetaData metaData = rs.getMetaData();
    int count = metaData.getColumnCount();
    String[] columnName = new String[count];
    JSONArray jsonArray = new JSONArray();
    while(rs.next()) {
        JSONObject jsonObject = new JSONObject();
        for (int i = 1; i <= count; i++){
               columnName[i-1] = metaData.getColumnLabel(i);
               jsonObject.put(columnName[i-1], rs.getObject(i));
        }
        jsonArray.put(jsonObject);
    }
    return jsonArray;
}
hitesh bariya
quelle
-1

Umgekehrt habe ich hier ArrayList und Map verwendet, daher wird das json-Objekt nicht zeilenweise aufgerufen, sondern nach Abschluss der Iteration der Ergebnismenge:

 List<Map<String, String>> list = new ArrayList<Map<String, String>>();

  ResultSetMetaData rsMetaData = rs.getMetaData();  


      while(rs.next()){

              Map map = new HashMap();
              for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
                 String key = rsMetaData.getColumnName(i);

                  String value = null;

               if (rsmd.getColumnType(i) == java.sql.Types.VARCHAR) {
                           value = rs.getString(key);
               } else if(rsmd.getColumnType(i)==java.sql.Types.BIGINT)                         
                             value = rs.getLong(key);
               }                  


                    map.put(key, value);
              }
              list.add(map);


    }


     json.put(list);    
reil bhudaya
quelle