Chuyển đổi ResultSet sang JSON hiệu quả nhất?


109

Đoạn mã sau chuyển đổi a ResultSetthành chuỗi JSON bằng cách sử dụng JSONArrayJSONObject.

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;
  }
}
  • Có cách nào nhanh hơn không?
  • Có cách nào sử dụng ít bộ nhớ hơn không?


1
triển khai cho java.sql.Types.ARRAY không hoạt động đối với tôi khi sử dụng postgresql (mảng được đặt làm Chuỗi bằng cách sử dụng "{...}". Đã kết thúc việc thay đổi dòng "obj.put (column_name, rs.getArray (column_name) );" thành "mảng array = rs.getArray (column_name); if (array = null) obj.put (column_name, mới JSONArray (array.getArray ()!));"
phân tử

Nếu hiệu suất là một vấn đề lớn, bạn không nên sử dụng API JSON này mà nên sử dụng thư viện phát trực tuyến chỉ ghi JSON mà không cần tạo các đối tượng bộ nhớ của tất cả dữ liệu (nơi bạn có thể xem lại / tìm nội dung trong cây). Điều đó nói rằng, tôi sẽ đảm bảo rằng bạn thực sự gặp vấn đề về hiệu suất trước khi làm điều đó.
Sebastiaan van den Broek

3
Có lỗi trong đoạn mã của bạn. java.sql.Types.BIGINTlà 8 byte kích thước, vì vậy nó phải được đọc cùng với rs.getLong()khôngrs.getInt()
polarfish

3
Cảm ơn vì đã tải cái này. Bạn vừa tiết kiệm cho tôi hàng giờ làm việc đáng giá.
DRich

Câu trả lời:


23

Trình biên dịch JIT có thể sẽ thực hiện điều này khá nhanh vì nó chỉ là các nhánh và các bài kiểm tra cơ bản. Bạn có thể làm cho nó trở nên thanh lịch hơn với tra cứu HashMap để gọi lại nhưng tôi nghi ngờ rằng nó sẽ nhanh hơn. Đối với bộ nhớ, điều này là khá mỏng.

Bằng cách nào đó, tôi nghi ngờ mã này thực sự là một cổ chai quan trọng cho bộ nhớ hoặc hiệu suất. Bạn có lý do thực sự nào để cố gắng tối ưu hóa nó không?


Tôi đang đặt mã nguồn trong một khuôn khổ mã nguồn mở, vì vậy tôi không biết nó sẽ được sử dụng để làm gì. Vì vậy, tôi đang cố gắng làm cho nó hiệu quả nhất có thể.
Devin Dixon

1
@DevinDixon: framework có sẵn không? Có bất cứ điều gì giống như mã trong câu hỏi của bạn đã có sẵn trong một kho nguồn mở ở đâu đó không?

34

Tôi nghĩ rằng có một cách để sử dụng ít bộ nhớ hơn (một lượng cố định và không tuyến tính tùy thuộc vào bản số dữ liệu) nhưng điều này ngụ ý để thay đổi chữ ký phương thức. Trên thực tế, chúng tôi có thể in dữ liệu Json trực tiếp trên một luồng đầu ra ngay sau khi chúng tôi tìm nạp chúng từ ResultSet: dữ liệu đã được viết sẵn sẽ được thu thập rác vì chúng tôi không cần một mảng giữ chúng trong bộ nhớ.

Tôi sử dụng GSON chấp nhận bộ điều hợp loại. Tôi đã viết một bộ điều hợp loại để chuyển đổi ResultSet thành JsonArray và nó trông rất giống với mã của bạn. Tôi đang chờ bản phát hành "Gson 2.1: Nhắm mục tiêu vào ngày 31 tháng 12 năm 2011" sẽ có "Hỗ trợ cho bộ điều hợp loại phát trực tuyến do người dùng xác định". Sau đó, tôi sẽ sửa đổi bộ điều hợp của mình thành bộ điều hợp phát trực tuyến.


Cập nhật

Như đã hứa, tôi sẽ trở lại nhưng không phải với Gson, thay vào đó là Jackson 2. Xin lỗi vì đã đến muộn (trong 2 năm).

Lời nói đầu: Chìa khóa để sử dụng ít bộ nhớ của kết quả itsef nằm trong con trỏ "phía máy chủ". Với loại con trỏ này (hay còn gọi là tập kết quả cho các nhà phát triển Java), DBMS gửi dữ liệu tăng dần đến máy khách (hay còn gọi là trình điều khiển) khi máy khách tiếp tục đọc. Tôi nghĩ rằng con trỏ Oracle là phía máy chủ theo mặc định. Đối với MySQL> 5.0.2, hãy tìm useCursorFetch tại tham số url kết nối . Kiểm tra về DBMS yêu thích của bạn.

1: Vì vậy, để sử dụng ít bộ nhớ hơn, chúng ta phải:

  • sử dụng con trỏ phía máy chủ đằng sau cảnh
  • sử dụng tập kết quả mở dưới dạng chỉ đọc và tất nhiên, chỉ chuyển tiếp ;
  • tránh tải tất cả con trỏ trong một danh sách (hoặc a JSONArray) nhưng viết từng hàng trực tiếp trên một dòng đầu ra , trong đó đối với dòng đầu ra, tôi có nghĩa là một luồng đầu ra hoặc một trình ghi hoặc cũng là một trình tạo json bao bọc một luồng đầu ra hoặc một trình ghi.

2: Như Tài liệu Jackson nói:

Streaming API hoạt động tốt nhất (chi phí thấp nhất, đọc / ghi nhanh nhất; 2 phương pháp khác được xây dựng dựa trên nó)

3: Tôi thấy bạn trong mã của bạn sử dụng getInt, getBoolean. getFloat ... của ResultSet mà không có wasNull . Tôi hy vọng điều này có thể mang lại vấn đề.

4: Tôi đã sử dụng mảng để bộ nhớ cache suy nghĩ và tránh để gọi getters mỗi lần lặp. Mặc dù không phải là người yêu thích cấu trúc switch / case, tôi đã sử dụng nó cho intSQL đó Types.

Câu trả lời: Chưa được thử nghiệm đầy đủ, nó dựa trên Jackson 2.2 :

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

Đối ResultSetSerializertượng hướng dẫn Jackson cách tuần tự hóa (chuyển đối tượng thành JSON) một ResultSet. Nó sử dụng API Jackson Streaming bên trong. Đây là mã của một bài kiểm tra:

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);

Và tất nhiên, mã của lớp ResultSetSerializer:

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);
        }
    }
}

27

Hai điều sẽ làm cho việc này nhanh hơn là:

Di chuyển cuộc gọi của bạn rsmd.getColumnCount()ra khỏi vòng lặp while. Số lượng cột không được thay đổi giữa các hàng.

Đối với mỗi loại cột, bạn sẽ gọi một cái gì đó như sau:

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

Sẽ nhanh hơn một chút khi sử dụng chỉ mục cột để truy xuất giá trị cột:

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

Cũng xác định String column_name;ra khỏi vòng lặp while.
Charney Kaye

22

Một giải pháp đơn giản hơn (dựa trên mã được đề cập):

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;

3
tốt đẹp, nhưng có một lỗi với DATETIME và dấu thời gian (nó không thêm Apostrophes
OhadR

đẹp và đơn giản
Anoop LL

10

Bạn có thể sử dụng jOOQ cho công việc. Bạn không cần phải sử dụng tất cả các tính năng của jOOQ để tận dụng một số tiện ích mở rộng JDBC hữu ích. Trong trường hợp này, chỉ cần viết:

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

Các phương pháp API có liên quan được sử dụng là:

Định dạng kết quả sẽ giống như sau:

{"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]]}

Bạn cũng có thể tạo định dạng của riêng mình khá dễ dàng, thông qua Result.map(RecordMapper)

Điều này về cơ bản hoạt động giống như mã của bạn, phá vỡ việc tạo các đối tượng JSON, "truyền trực tiếp" trực tiếp vào a StringBuilder. Tuy nhiên, tôi muốn nói rằng chi phí hiệu suất sẽ không đáng kể trong cả hai trường hợp.

(Tuyên bố từ chối trách nhiệm: Tôi làm việc cho công ty đằng sau jOOQ)


Điều này thật tuyệt nhưng tôi đang gặp sự cố khi phân tích cú pháp chuỗi kết quả. Khi một số giá trị chứa dấu ngoặc kép, trình phân tích cú pháp không thể hoạt động chính xác: Tôi nghĩ rằng dấu ngoặc kép bên trong các giá trị nên được thoát ( "thành \") để tạo chuỗi JSON hợp lệ. Đây có phải là một lỗi của formatJSON()chức năng? Hay tôi đang thiếu cái gì đó?
Oneiros

@Oneiros: jOOQ nên thoát một cách chính xác những dấu ngoặc kép ... tốt nhất đặt một câu hỏi mới (với các chi tiết) hoặc báo cáo lỗi: github.com/jOOQ/jOOQ/issues/new
Lukas Eder

Trong ví dụ của bạn, resultSet được sử dụng trong việc fetch(resultSet)gì? Nó không được định nghĩa ở bất cứ đâu. Và nếu tôi nhận được JDBC ResultSettrước khi tìm nạp thì mục đích là DSL.using(connection)gì? Tại sao nó cần kết nối? :)
Nikola Lošić

1
@ NikolaLošić: Chà, câu hỏi hỏi về việc sử dụng JDBC ResultSet, vì vậy tôi nghĩ không có gì phải nghi ngờ cả ResultSet. Thật vậy, không có vẻ rõ ràng tại sao lại connectioncần ở đây. Tuy nhiên, nếu bạn đang sử dụng jOOQ, bạn sẽ có DSLContext(kết quả của DSL.using(connection)hoặc tương tự) sẵn sàng cho bạn.
Lukas Eder

thư viện JOOQ chính xác để bao gồm là gì? Tôi đang thử nhiều nhưng cái nào cũng cho tôi lỗi Lớp không tìm thấy với tham chiếu DSL. Thnks
Lorenzo Barbagli

7

Ngoài các đề xuất được thực hiện bởi @Jim Cook. Một suy nghĩ khác là sử dụng công tắc thay vì if-elses:

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);
}

4
Việc lặp lại vòng lặp (so sánh chỉ số 0) cũng nhanh hơn (so sánh chỉ số với một biểu thức).
Dave Jarvis

4

Câu trả lời này có thể không hiệu quả nhất, nhưng nó chắc chắn là động. Ghép nối JDBC gốc với thư viện Gson của Google, tôi có thể dễ dàng chuyển đổi từ kết quả SQL sang luồng JSON.

Tôi đã bao gồm trình chuyển đổi, tệp thuộc tính DB mẫu, tạo bảng SQL và tệp xây dựng Gradle (có sử dụng các phần phụ thuộc).

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'
}

Các kết quả

CHỌN cơ bản

[
    {
        "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
    }
]

SELECT trung gian

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

3

Tạo trước tên cột đầu tiên, sử dụng thứ hai rs.getString(i)thay vì rs.getString(column_name).

Sau đây là một triển khai của điều này:

    /*
     * 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;
    }

làm cách nào để truy cập và sử dụng đối tượng .... nói rằng tôi muốn in toàn bộ cột Tên..và đối tượng có dễ dàng sẵn sàng cho các hoạt động CRUD không ??
Prathamesh dhanawade

@Prathameshdhanawade Phương pháp này là để ẩn JDBC ResultSet vào một mảng JSON. Các nhà phát triển thường không sử dụng JDBC ResultSet thô, họ thường chuyển nó thành danh sách các đối tượng Java, tức là đối tượng JSON. Bạn thấy giá trị trả về là một mảng các đối tượng JSON. Bạn có thể dễ dàng truy cập một đối tượng thông qua JSONObject json = resList.get(i);Sau đó, bạn có thể tự do thao tác với đối tượng JSON json.
coderz

Trên thực tế, tôi sẽ cần đối tượng để chuẩn bị một chế độ xem đồ họa. Vì vậy, tôi chỉ tò mò tôi có thể thao tác đối tượng. Thnx.
Prathamesh dhanawade

Bạn có thể vui lòng mô tả "chế độ xem đồ họa"? Hoặc cho một ví dụ?
coderz

Tôi đang cố gắng hiển thị giá trị cột dưới dạng: JSONObject obj = jsonList.get (1); System.out.println (obj.getString ("name") + "\ t" + obj.getString ("company")); nhưng gặp lỗi là "org.json.JSONException: JSONObject [" name "] không tìm thấy."
Prathamesh dhanawade

2

Nếu bất kỳ ai có kế hoạch sử dụng triển khai này, Bạn có thể muốn xem điều này và điều này

Đây là phiên bản của tôi về mã chuyển đổi đó:

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;
}
}

2

Cũng giống như một vòng lặp, vòng lặp if / then hiệu quả hơn so với chuyển đổi cho enums. Nếu bạn có chuyển đổi đối với số nguyên enum thô, thì nó hiệu quả hơn, nhưng đối với biến, if / then sẽ hiệu quả hơn, ít nhất là đối với Java 5, 6 và 7.

Tức là, vì một số lý do (sau một số bài kiểm tra hiệu suất)

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

nhanh hơn

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

Tôi thấy rằng một số người đang nghi ngờ tôi, vì vậy tôi sẽ đăng mã ở đây để bạn có thể tự chạy để xem sự khác biệt, cùng với đầu ra tôi có từ Java 7. Kết quả của đoạn mã sau với 10 giá trị enum như sau. Lưu ý rằng chìa khóa ở đây là if / then sử dụng giá trị số nguyên so sánh với hằng số thứ tự của enum, so với chuyển đổi với giá trị thứ tự của enum so với giá trị thứ tự int thô, so với chuyển đổi với enum đối với mỗi tên enum. Nếu / thì với một giá trị số nguyên đánh bại cả hai công tắc khác, mặc dù công tắc cuối cùng nhanh hơn một chút so với công tắc đầu tiên, nhưng nó không nhanh hơn if / else.

If / else mất 23 ms
Chuyển đổi mất 45 ms
Chuyển đổi 2 mất 30 ms
Tổng số trận đấu: 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);
    }
}

Chà, ok nhưng .. sự thật thực tế là sự khác biệt giữa các lựa chọn thay thế mã hóa này cho bất kỳ trường hợp sử dụng thực tế nào là rất nhỏ, đến mức trong một ứng dụng thực, sự khác biệt về hiệu suất giữa chúng rất có thể sẽ rất nhỏ. Trước tiên hãy làm cho mã của bạn chính xác và sau đó (chỉ sau đó) làm cho nó nhanh (nếu nó cần nhanh hơn).
scottb

Đồng ý, nhưng câu hỏi chính liên quan đến cách nhanh nhất, hiệu quả nhất. Có nhiều kiểu làm cho mã khó đọc hoặc khó bảo trì, nhưng hiệu quả hơn, mặc dù thông thường những kiểu này được giải quyết bằng cách tối ưu hóa trình biên dịch tại một số thời điểm trong tương lai. Một ví dụ về điều này là việc sử dụng intern()chuỗi for mà phần lớn không còn cần thiết trong hầu hết các phiên bản Java hiện đại.
Marcus

Đồng ý, nhưng bản thân các khối if-then-else và switch-case là những giải pháp kém cho các vấn đề về khả năng bảo trì, tính mạnh mẽ và khả năng đọc trong mọi trường hợp. Đối với enum mà bạn sở hữu (hoặc mã của nó mà bạn có thể sửa đổi), phương pháp hay nhất là thường xuyên sử dụng các phương thức cụ thể không đổi trong một kiểu enum phong phú. giải pháp ra khỏi đó.
scottb

1

Đối với tất cả những người đã chọn giải pháp lưới if-else, vui lòng sử dụng:

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

Bởi vì trong trường hợp bí danh trong truy vấn của bạn, tên cột và nhãn cột là hai thứ khác nhau. Ví dụ: nếu bạn thực thi:

select col1, col2 as my_alias from table

Bạn sẽ nhận được

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

Thay vì:

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

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;
    }

}

Xin thêm một số lời giải thích cho câu trả lời của bạn.
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;
}

-1

theo cách khác, ở đây tôi đã sử dụng ArrayList và Map, vì vậy nó không gọi đối tượng json theo từng hàng mà sau khi lặp lại tập kết quả hoàn tất:

 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);    
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.