복붙노트

[SQL] JSON에 ResultSet의 대부분의 효율적인 변환?

SQL

JSON에 ResultSet의 대부분의 효율적인 변환?

다음 코드는 JSONArray와 된 JSONObject를 사용하여 JSON 문자열로 ResultSet의 변환합니다.

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

해결법

  1. ==============================

    1.JIT를 컴파일러는 아마 그냥 가지 기본적인 테스트를 이후 꽤 빨리이를 만들 것입니다. 당신은 아마 콜백에 HashMap의 조회와 더 우아한 만들 수 있지만, 나는 그것이 빨리 될 것이다 의심한다. 메모리에 관해서는,이 같이 꽤 슬림입니다.

    JIT를 컴파일러는 아마 그냥 가지 기본적인 테스트를 이후 꽤 빨리이를 만들 것입니다. 당신은 아마 콜백에 HashMap의 조회와 더 우아한 만들 수 있지만, 나는 그것이 빨리 될 것이다 의심한다. 메모리에 관해서는,이 같이 꽤 슬림입니다.

    어떻게 든이 코드가 실제로 메모리 나 성능이 중요한 병목 의심. 당신은 그것을 최적화하기 위해 시도하는 어떤 진짜 이유가 있습니까?

  2. ==============================

    2.나는 더 적은 메모리를 (고정이 아닌 선형 양의 데이터 카디널리티에 따라)를 사용하는 방법이 있다고 생각하지만이 방법 서명을 변경할 의미한다. 우리는 결과 집합에서 그들을 가져 빨리으로 사실 우리는 출력 스트림에 직접 JSON 데이터를 인쇄 할 수 있습니다 : 이미 기록 된 데이터는 우리가 메모리에 유지하는 배열을 필요로하지 않기 때문에 가비지 수집 될 것입니다.

    나는 더 적은 메모리를 (고정이 아닌 선형 양의 데이터 카디널리티에 따라)를 사용하는 방법이 있다고 생각하지만이 방법 서명을 변경할 의미한다. 우리는 결과 집합에서 그들을 가져 빨리으로 사실 우리는 출력 스트림에 직접 JSON 데이터를 인쇄 할 수 있습니다 : 이미 기록 된 데이터는 우리가 메모리에 유지하는 배열을 필요로하지 않기 때문에 가비지 수집 될 것입니다.

    I 형 어댑터를 받아 GSON를 사용합니다. 나는 JsonArray에 ResultSet의 변환 타입 어댑터를 쓴 그리고 그것은 매우 당신의 코드처럼 보인다. 나는 "GSON 2.1 : 2011년 12월 31일 대상으로"기다리고있어 "사용자 정의 스트리밍 유형 어댑터에 대한 지원"을해야합니다 릴리스. 그리고 나는 스트리밍 어댑터로 내 어댑터를 수정할 수 있습니다.

    약속대로 내가 대신 잭슨 2. 죄송합니다 늦게 (2 년)로, 다시하지만 GSON과 함께 해요.

    머리말 : 키는 itsef는 "서버 측"커서에 결과의 적은 메모리를 사용합니다. 클라이언트가 읽기 앞으로 간다 커서 이런 종류의 (자바 개발자들에게 일명, 결과 집합)와 DBMS 클라이언트 (일명 드라이버)로 점진적으로 데이터를 전송한다. 나는 오라클을 생각 커서 기본적으로 서버 측이다. MySQL의 경우> 연결 URL의 paramenter에서 useCursorFetch에 대한 5.0.2보세요. 좋아하는 DBMS에 대해 확인합니다.

    1 : 그래서 우리가해야 메모리를 적게 사용합니다 :

    2 :로 잭슨 문서는 말합니다 :

    3 : 당신의 코드 사용의 getInt, getBoolean에서 당신을 참조하십시오. wasNull를하지 않고 결과 집합 getFloat .... 나는이 문제를 얻을 수 있습니다 기대합니다.

    4 : 캐시가 생각하고 각 반복 게터 전화를 피하기 위해에 내가 배열을 사용했다. 스위치 / 케이스 구조의 팬이 있지만, 그 INT의 SQL 유형을 위해 그것을 사용했다.

    답 : 아직 완전히 테스트되지 않음, 그것은 잭슨 2.2을 기반으로 :

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

    결과 집합 직렬화 객체 직렬화는 ResultSet (JSON에 개체를 변환) 방법에 잭슨을 지시합니다. 그것은 잭슨 스트리밍 API의 내부를 사용합니다. 테스트의 코드 여기 :

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

    그리고, 물론, 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);
            }
        }
    }
    
  3. ==============================

    3.이 빠른 것 두 가지가 있습니다 :

    이 빠른 것 두 가지가 있습니다 :

    while 루프에서 rsmd.getColumnCount ()로 전화를 이동합니다. 열 수는 행에 걸쳐하지를 변경해야합니다.

    각 열 유형의 경우, 다음과 같이 호출 결국 :

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

    그것은 열 값을 검색 할 열 인덱스를 사용하는 약간 빠른 것입니다 :

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

    4.(문제의 코드를 기반으로) 간단한 해결책 :

    (문제의 코드를 기반으로) 간단한 해결책 :

    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;
    
  5. ==============================

    5.당신은 작업 jOOQ를 사용할 수 있습니다. 당신은 몇 가지 유용한 JDBC 확장을 활용 jOOQ의 모든 기능을 사용할 필요가 없습니다. 이 경우, 단순히 쓰기 :

    당신은 작업 jOOQ를 사용할 수 있습니다. 당신은 몇 가지 유용한 JDBC 확장을 활용 jOOQ의 모든 기능을 사용할 필요가 없습니다. 이 경우, 단순히 쓰기 :

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

    사용 관련 API 방법은 다음과 같습니다 :

    결과 형식은 다음과 같이 표시됩니다

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

    또한 Result.map을 통해 오히려 쉽게 자신 만의 서식을 만들 수 있습니다 (RecordMapper)

    이것은 본질적으로 JSON의 생성을 우회, 코드와 동일하게 수행 직접 모두 StringBuilder에 "스트리밍", 객체. 나는 성능 오버 헤드가 있지만, 두 경우 모두 무시해야한다고 말하고 싶지만.

    (면책 조항 : jOOQ 뒤에 회사 I 작업)

  6. ==============================

    6.@Jim 쿡에 의해 제안뿐만 아니라. 또 다른 생각은 elses의 경우 - 대신 스위치를 사용하는 것입니다 :

    @Jim 쿡에 의해 제안뿐만 아니라. 또 다른 생각은 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);
    }
    
  7. ==============================

    7.이 답변이 가장 효율적으로되지 않을 수도 있습니다,하지만 그것은 확실히 동적입니다. 구글의 GSON 라이브러리 기본 JDBC 페어링, 내가 쉽게 JSON 스트림에 SQL 결과에서 변환 할 수 있습니다.

    이 답변이 가장 효율적으로되지 않을 수도 있습니다,하지만 그것은 확실히 동적입니다. 구글의 GSON 라이브러리 기본 JDBC 페어링, 내가 쉽게 JSON 스트림에 SQL 결과에서 변환 할 수 있습니다.

    나는 컨버터, 예를 들어 DB 속성 파일, SQL 테이블 생성, (사용 종속성)를 Gradle을 빌드 파일을 포함했다.

    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);
        }
    }
    
    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);
        }
    }
    
    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);
        }
    }
    
    driver=com.mysql.jdbc.Driver
    database=jdbc:mysql://localhost/JDBC_Tutorial
    username=root
    password=
    
    -- 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 */;
    
    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'
    }
    
    [
        {
            "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
        }
    ]
    
    [
        {
            "firstName": "John",
            "lastName": "Lennon",
            "age": 75
        },
        {
            "firstName": "Paul",
            "lastName": "McCartney",
            "age": 73
        },
        {
            "firstName": "George",
            "lastName": "Harrison",
            "age": 72
        },
        {
            "firstName": "Ringo",
            "lastName": "Starr",
            "age": 75
        }
    ]
    
  8. ==============================

    8.첫째 열 이름 대신 rs.getString (COLUMN_NAME)의 두 번째 사용 rs.getString (I)을 사전에 생성한다.

    첫째 열 이름 대신 rs.getString (COLUMN_NAME)의 두 번째 사용 rs.getString (I)을 사전에 생성한다.

    다음은이의 구현입니다 :

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

    9.사람이 계획에이 구현을 사용하는 경우, 당신은이를이 체크 아웃 싶어 수도

    사람이 계획에이 구현을 사용하는 경우, 당신은이를이 체크 아웃 싶어 수도

    이것은 그 convertion 코드의 내 버전입니다 :

    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;
    }
    }
    
  10. ==============================

    10.그냥 머리까지, 같은 다음 루프 열거 형 스위치보다 더 효율적인 경우 /. 당신은 원시 열거 정수에 대한 스위치를 가지고 있다면, 그것은 더 효율적이지만, 변수에 대해, 경우 / 사용 후 자바 5, 6, 7, 적어도 더 효율적입니다.

    그냥 머리까지, 같은 다음 루프 열거 형 스위치보다 더 효율적인 경우 /. 당신은 원시 열거 정수에 대한 스위치를 가지고 있다면, 그것은 더 효율적이지만, 변수에 대해, 경우 / 사용 후 자바 5, 6, 7, 적어도 더 효율적입니다.

    즉, 어떤 이유로 (일부 성능 테스트 후)

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

    빨리보다

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

    나는 10 개 열거 값으로 다음 코드의 결과로 다음이다 나는 자바 7에서이 출력과 함께 그래서, 당신은 차이를 볼 자신을 실행할 수 있습니다 여기에 코드를 게시 할 수 있습니다, 몇 사람이 나를 의심하는 것을 알 수있다. 각각의 ENUM 이름에 대한 ENUM와 스위치 대 원시 INT 서수 값에 대해 열거의 순서 값과 상기 스위치 대 상기 ENUM의 서수 상수에 대해 비교하는 정수 값을 사용하는 경우 / 현재 키가 참고. 상기 스위치가 마지막으로 조금 더 빨리 제 1 스위치보다 있었지만, 그렇지 않은 경우 빨랐다 / 후 모두 다른 스위치 아웃 정수 값의 비트와 함께,보다 / IF 다른.

    경우 / 다른 23 밀리했다 스위치는 45 밀리했다 스위치 2는 30 밀리했다 총 경기 : 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);
        }
    }
    
  11. ==============================

    11.은 if-다른 메쉬 솔루션을 선택했다 한 모든 사람들을 위해, 사용하십시오 :

    은 if-다른 메쉬 솔루션을 선택했다 한 모든 사람들을 위해, 사용하십시오 :

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

    때문에 쿼리의 별칭의 경우, 열 이름 및 열 레이블이 다른 두 가지입니다. 예를 들어, 당신은 실행하면 :

    select col1, col2 as my_alias from table
    

    당신은 얻을 것이다

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

    보다는 :

    [
        { "col1": 1, "my_alias": 2 }, 
        { "col1": 1, "my_alias": 2 }
    ]
    
  12. ==============================

    12.

    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;
        }
    
    }
    
  13. ==============================

    13.

    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;
    }
    
  14. ==============================

    14.해당 행이 아니라 결과 집합의 반복이 끝난 후 JSON 객체 행을 호출하지 않도록, 여기에 내가, ArrayList를하고지도 사용했던 다른 방법 :

    해당 행이 아니라 결과 집합의 반복이 끝난 후 JSON 객체 행을 호출하지 않도록, 여기에 내가, ArrayList를하고지도 사용했던 다른 방법 :

     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);    
    
  15. from https://stackoverflow.com/questions/6514876/most-efficient-conversion-of-resultset-to-json by cc-by-sa and MIT license