자바 결과 집합을 JSON으로 변환하는 방법은?
JDBC 커넥터를 이용한 MySQL 질의 결과 세트가 있습니다.그래서 저의 업무는 결과 세트를 JSON 형식으로 변환하는 것입니다.AJAX 응답으로 클라이언트 측에 보낼 수 있도록 하겠습니다.자바와 JSON 개념 모두 처음이라 JSON 포맷으로 변환하는 방법을 설명해주실 분?
많은 사람들이 그 질문에 정확하게 답했습니다.하지만 다음과 같은 작은 코드 조각으로 게시물에 가치를 더할 수 있다고 생각합니다.사용합니다.Apache-DBUtils
그리고.Gson
도서관.
public static String resultSetToJson(Connection connection, String query) {
List<Map<String, Object>> listOfMaps = null;
try {
QueryRunner queryRunner = new QueryRunner();
listOfMaps = queryRunner.query(connection, query, new MapListHandler());
} catch (SQLException se) {
throw new RuntimeException("Couldn't query the database.", se);
} finally {
DbUtils.closeQuietly(connection);
}
return new Gson().toJson(listOfMaps);
}
JSON을 사용하시는 분이라면 Jackson JSON 라이브러리를 추천합니다.
http://wiki.fasterxml.com/JacksonHome
jar 파일은 다음에서 확인할 수 있습니다.
http://wiki.fasterxml.com/JacksonDownload
Jackson J를 사용하여 임의의 결과 집합을 Map<> 또는 List<Map<>로 변환할 때 사용하는 일반 코드입니다.SON은 꽤 직설적입니다(아래 참조).
package com.naj.tmoi.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EntityFactory {
public EntityFactory(Connection connection, String queryString) {
this.queryString = queryString;
this.connection = connection;
}
public Map<String, Object> findSingle(Object[] params) throws SQLException {
List<Map<String, Object>> objects = this.findMultiple(params);
if (objects.size() != 1) {
throw new SQLException("Query did not produce one object it produced: " + objects.size() + " objects.");
}
Map<String, Object> object = objects.get(0); //extract only the first item;
return object;
}
public List<Map<String, Object>> findMultiple(Object[] params) throws SQLException {
ResultSet rs = null;
PreparedStatement ps = null;
try {
ps = this.connection.prepareStatement(this.queryString);
for (int i = 0; i < params.length; ++i) {
ps.setObject(1, params[i]);
}
rs = ps.executeQuery();
return getEntitiesFromResultSet(rs);
} catch (SQLException e) {
throw (e);
} finally {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
}
}
protected List<Map<String, Object>> getEntitiesFromResultSet(ResultSet resultSet) throws SQLException {
ArrayList<Map<String, Object>> entities = new ArrayList<>();
while (resultSet.next()) {
entities.add(getEntityFromResultSet(resultSet));
}
return entities;
}
protected Map<String, Object> getEntityFromResultSet(ResultSet resultSet) throws SQLException {
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
Map<String, Object> resultsMap = new HashMap<>();
for (int i = 1; i <= columnCount; ++i) {
String columnName = metaData.getColumnName(i).toLowerCase();
Object object = resultSet.getObject(i);
resultsMap.put(columnName, object);
}
return resultsMap;
}
private final String queryString;
protected Connection connection;
}
서블릿에서 com.fasterxml.jackson.databind를 사용하여 목록을 JSON으로 변환합니다.Java Generics를 JSON String으로 변환하는 ObjectMapper입니다.
Connection connection = null;
try {
connection = DataSourceSingleton.getConnection();
EntityFactory nutrientEntityFactory = new EntityFactory(connection, NUTRIENT_QUERY_STRING);
List<Map<String, Object>> nutrients = nutrientEntityFactory.findMultiple(new Object[]{});
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(nutrients);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(json);
} catch (SQLException e) {
throw new ServletException(e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new ServletException(e);
}
}
}
다음과 같이 매개변수를 준비 상태에 전달할 수 있습니다.
String name = request.getHeader("name");
EntityFactory entityFactory = new EntityFactory(DataSourceSingleton.getConnection(), QUERY_STRING);
Map<String, Object> object = entityFactory.findSingle(new String[]{name});
private static final String QUERY_STRING = "SELECT NAME, PASSWORD, TOKEN, TOKEN_EXPIRATION FROM USER WHERE NAME = ?";
}
저는 구글 GSON 라이브러리를 사용해 본 적이 있는데, 작은 gson-2.2.4.jar 190KB 라이브러리 하나를 제 웹앱/WEB-INF/lib 폴더에 사용했습니다.http://code.google.com/p/google-gson/
import com.google.gson.stream.JsonWriter;
---
httpres.setContentType("application/json; charset=UTF-8");
httpres.setCharacterEncoding("UTF-8");
JsonWriter writer = new JsonWriter(new OutputStreamWriter(httpres.getOutputStream(), "UTF-8"));
while(rs.next()) {
writer.beginObject();
// loop rs.getResultSetMetadata columns
for(int idx=1; idx<=rsmd.getColumnCount(); idx++) {
writer.name(rsmd.getColumnLabel(idx)); // write key:value pairs
writer.value(rs.getString(idx));
}
writer.endObject();
}
writer.close();
httpres.getOutputStream().flush();
JSON key:value pairs를 입력하려면 writer.value(String, long, integer 등) 설정자가 있습니다.각 rsmd 루프 내에서 switch-case를 수행하고 번호가 매겨진 sql 유형에 대해 적절한 setter를 사용합니다.기본값은 writer.value(rs.getString(idx)) setter를 사용할 수 있습니다.
JsonWriter를 사용하면 큰 json 응답 CPU+RAM을 효과적으로 쓸 수 있습니다.먼저 sql resultset을 루프하고 massive List를 RAM에 생성할 필요가 없습니다.그럼 json 문서를 작성하는 동안 루프 리스트를 다시 작성합니다.이 예제는 그대로 흐릅니다. 남은 데이터가 여전히 서블릿 출력에 기록되는 동안 http reply가 청크됩니다.
GSON+Sql 결과 집합을 중심으로 상위 수준의 래퍼 유틸리티를 만드는 것은 비교적 쉽습니다.jsp 페이지는 http 응답을 작성하는 동안 SqlIterator(sqlquery) 메서드(.next(), getColumnCount(), getType(idx), .getString(idx), .getLong(idx)...)을 사용할 수 있습니다.중간 목록 없이 원래 sql을 루프합니다.이것은 더 작은 앱에 상관없지만, 많이 사용하는 앱은 cpu+ram 사용 패턴을 더 면밀하게 고려해야 합니다.또는 SqlToJson(http response, sqlrs) 도우미를 수행하는 것이 jsp 또는 servlet 코드 노이즈를 최소화하는 것이 더 좋습니다.
JSON 라이브러리라면 어디든지 사용할 수 있습니다.
다음은 각 요소를 JSON 개체로 사용하여 목록을 반환하는 구현입니다.
/*
* 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;
}
- 결과 집합을 다음으로 변환
List<Map<String, Object>>
(각 맵에는 열 이름을 키로 하고 열 내용을 값으로 하는 행이 포함되어 있습니다. 목록은 해당 행의 목록입니다.) - Gson 또는 Jackson 라이브러리를 사용하여 이 개체를 JSON에 숨깁니다.
Spring을 사용하고 싶다면 꽤 쉽습니다.
@RestController
public class MyController
@Autowired
private JdbcTemplate jdbcTemplate;
@RequestMapping("/")
List<Map<String,Object>> getAll() {
return jdbcTemplate.queryForList("select * from my_table");
}
}
mvc-dispatcher-servlet.xml에서는 다음과 같이 JdbcTemplate를 설정합니다.
<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
<property name="dataSource">
...data source config...
</property>
</bean>
잭슨은 당신의 클래스 경로에 있어야 합니다(즉, 메이븐 의존).
자바에는 jsonlib을 사용합니다.결과 집합을 반복하고 원하는 속성을 다음과 같이 추가합니다.JSONObject
jsonlib의 개체에서 를 선택합니다.
애플리케이션(브라우저의 MySQL/java servlet/javascript) 내에서 나는 빠른 stringbuilder 메서드와 generic rs.getObject()를 가진 문자열 함수를 사용합니다.나는 그것이 그 일을 하는 가장 우아한 방법이라고 생각합니다.
public String rStoJason(ResultSet rs) throws SQLException
{
if(rs.first() == false) {return "[]";} else {rs.beforeFirst();} // empty rs
StringBuilder sb=new StringBuilder();
Object item; String value;
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int numColumns = rsmd.getColumnCount();
sb.append("[{");
while (rs.next()) {
for (int i = 1; i < numColumns + 1; i++) {
String column_name = rsmd.getColumnName(i);
item=rs.getObject(i);
if (item !=null )
{value = item.toString(); value=value.replace('"', '\'');}
else
{value = "null";}
sb.append("\"" + column_name+ "\":\"" + value +"\",");
} //end For = end record
sb.setCharAt(sb.length()-1, '}'); //replace last comma with curly bracket
sb.append(",{");
} // end While = end resultset
sb.delete(sb.length()-3, sb.length()); //delete last two chars
sb.append("}]");
return sb.toString();
}
여기서 최선의 해결책을 찾았습니다.
import org.json.JSONArray;
import org.json.JSONObject;
import java.sql.ResultSet;
/**
* Convert a result set into a JSON Array
* @param resultSet
* @return a JSONArray
* @throws Exception
*/
public static JSONArray convertToJSON(ResultSet resultSet)
throws Exception {
JSONArray jsonArray = new JSONArray();
while (resultSet.next()) {
int total_rows = resultSet.getMetaData().getColumnCount();
for (int i = 0; i < total_rows; i++) {
JSONObject obj = new JSONObject();
obj.put(resultSet.getMetaData().getColumnLabel(i + 1)
.toLowerCase(), resultSet.getObject(i + 1));
jsonArray.put(obj);
}
}
return jsonArray;
}
스프링 JDB를 활용한다면저장된 함수를 실행하기 위한 CT 템플릿은 커서를 테이블 항목의 목록으로 반환하고 지정된 빈 목록으로 매핑하려는 경우 가장 깔끔한 솔루션입니다.
import com.fasterxml.jackson.databind.ObjectMapper;
...
final static ObjectMapper mapper = new ObjectMapper();
...
<T> List<T> populateExecuteRetrieve(SimpleJdbcCall call, Map inputParameters, Class<T> outputClass) {
List<?> sqlResult;
sqlResult = call.executeFunction(ArrayList.class, parameter);
return sqlResult
.stream()
.map(entry -> mapper.convertValue(entry, outputBeanClass))
.collect(Collectors.toList());
}
천만에요!
해피코딩!
언급URL : https://stackoverflow.com/questions/18960446/how-to-convert-a-java-resultset-into-json
'programing' 카테고리의 다른 글
프로젝트의 여러 CSS 파일에서 사용되지 않는 CSS 정의를 식별하는 방법 (0) | 2023.10.28 |
---|---|
요소를 사용합니다.AddClass를 사용하여 'Class' 역할을 하도록 제한된 각도 js 지시문을 추가합니다. (0) | 2023.10.28 |
Spring Data Rest를 사용할 때 @Repository를 구성 요소 검색에서 제외하는 방법 (0) | 2023.10.28 |
MySql: MyISAM vs.이노 DB! (0) | 2023.10.28 |
컨트롤러 asp.net -core에서 최신 문화 가져오기 (0) | 2023.10.28 |