(java)如何将从数据库中查询出来的结果集转换为对应类的对象?可考虑hibernate。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(java)如何将从数据库中查询出来的结果集转换为对应类的对象?可考虑hibernate。相关的知识,希望对你有一定的参考价值。

假设我有一张表:t1 有一个字段 a ,里面有3条记录。
我另有一个类:T1 有一个属性 a,并有对应的get/set方法。
T1有3个对象:t1,t2,t3

我执行如下的查询:select * from t1
得到一个结果集(ResultSet):rst

那么rst中肯定就会有3条记录。

我的问题是,如何将这3条记录分别赋给3个T1的对象?
while(rst.next())
t1=(T1)rst;

是不行的。

我想借助hibernate是否做起来会方便些?
我知道传了一个id,hibernate能返回一个对象的,但是如何返回多个对象呢?
如果不借助hibernate,又如何做到呢?
谢谢。
麻烦知道怎么弄的,说得详细点。谢谢.
0079007 ,,if中应该是布尔值,一个Object怎么可以。
再说了,你的o得到的也仅仅是个true/false而已。

List<BranchBase> rtnList = new ArrayList<BranchBase>();

String sql = "select * from params.tb_branch_kbmp where depttype <> 3070";

//从容器中得到session

Connection connection = null;
PreparedStatement statement=connection.prepareStatement(sql);
ResultSet resultSet= statement.executeQuery();
while(resultSet.next())
//这里得一个一个取
BranchBase b=new BranchBase();
b.属性名=resultSet.getInt("表的列名");//如果列为varchar()类型就resultSet.getString("表的列名")
//就这样取完
rtnList.add(b);


return rtnList;
参考技术A 你可以使用List呀,把取得的所有的记录组织成对象然后放进List里面,使用的时候在从里面取就是了。如果使用的Hibernian的话那么Hibernian里面的查询都可以返回一个List集合。直接用就是了 参考技术B //呵呵,改了一下

int count=0;
Object o=null;
while(rst.next())
o = rst.getObject(1);//1 2 ... n 索引值根据你的数据库实际情况而定
switch(count%3)
case 0:t1=(T1)o;break;
case 1:t2=(T1)o;break;
case 2:t3=(T1)o;break;

++count;

如何将 Java 结果集转换为 JSON?

【中文标题】如何将 Java 结果集转换为 JSON?【英文标题】:How to convert a Java resultset into JSON? 【发布时间】:2013-09-28 10:04:42 【问题描述】:

我有一个使用 JDBC 连接器的 MySQL 查询结果集。所以我的工作是将结果集转换为 JSON 格式。这样我就可以将它作为 AJAX 响应发送到客户端。有人可以解释如何转换为 JSON 格式,因为我对 Java 和 JSON 的概念都很陌生

【问题讨论】:

【参考方案1】:

很多人都正确回答了这个问题。但是,我认为我可以使用以下小 sn-p 代码为帖子添加更多价值。它使用Apache-DBUtilsGson 库。

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

【讨论】:

工作就像一个魅力:) 谢谢你的朋友!阿帕奇岩石 @HardikThaker 欢迎 :-) 我将此答案扩展为:***.com/questions/35134337/java-query-into-json/…,它显示了包含和 maven 依赖项。也可以随意在此答案中包含任何信息。 很好的工作示例,一些很棒的工具(Apache-DBUtils 和 Gson)。【参考方案2】:

如果您使用 JSON,我推荐 Jackson JSON 库。

http://wiki.fasterxml.com/JacksonHome

jar 文件可以在这里找到:

http://wiki.fasterxml.com/JacksonDownload

这是我用来将任何结果集转换为 Map 或 List > 使用 JacksonJSON 将其转换为 JSON 的通用代码非常简单(见下文)。

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;

在 servlet 中,我使用将 Java 泛型转换为 JSON 字符串的 com.fasterxml.jackson.databind.ObjectMapper 将列表转换为 JSON。

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

您可以像这样将参数传递给 PreparedStatement:

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 = ?";

【讨论】:

这段代码为我节省了大约 2 天的工作时间。非常感谢。 @cYn 我还没有使用过这个新的库(JSR-353),但我建议看看这个实现,因为它现在是一个标准。从 Jackson 转换会很简单,然后您就可以使用 JSR 标准了。 jsonp.java.net 感谢您提供的信息。但是将 resultSets 用作 JSON 是非常简约的,不是吗?既然物体永远不会很深,那可能没什么大不了的?对我来说,ResultSet 对象似乎只是一个键(列)和一个值(行)。 是的,使用 JSR-353 的唯一好处是它将成为标准 JRE 的一部分,而不需要外部依赖。您可能会发现 Apache DBUtils 类 MapListHandler 非常有用。它与这段代码做同样的事情(减去 json 部分),并具有附带一堆其他有用的东西的优势。 commons.apache.org/proper/commons-dbutils/apidocs/index.html 嗨 Nate,我最近遇到了这个实现的问题。不确定您是否发现了这一点,但使用 Map 返回未排序的列排序。如果您已经在 SQL 调用中设置了所需列的顺序,则不需要此行为。为了解决这个问题,我将所有 Map 更改为 LinkedHashMap。再次感谢您提供此代码,因为它对我非常有用。【参考方案3】:

我使用了 Google GSON 库,它是一个很小的 ​​gson-2.2.4.jar 190KB 库,位于 mywebapp/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 键:值对,则可以使用 writer.value(String,long,integer,etc..) 设置器。在 foreach rsmd 循环中进行 switch-case 并为编号的 sql 类型使用适当的 setter。默认可以使用 writer.value(rs.getString(idx)) setter。

使用 JsonWriter 可以有效地编写大型 json 回复 CPU+RAM。您不需要先循环 sqlresultset 并在 RAM 中创建大量列表。然后在编写 json 文档时再次循环列表。这个例子顺其自然,http 回复被分块,而剩余的数据仍被写入 servlet 输出。

围绕 GSON+Sql 结果集创建更高级别的包装实用程序相对容易。 jsp 页面在编写 http 回复时可以使用 SqlIterator(sqlquery) 方法(.next()、getColumnCount()、getType(idx)、.getString(idx)、.getLong(idx) ...)。它在没有中间列表的情况下循环原始 sql。这对于较小的应用程序无关紧要,但重度使用的应用程序必须更仔细地考虑 cpu+ram 使用模式。或者更好的做法是使用 SqlToJson(httpresponse, sqlrs) 助手,然后 jsp 或 servlet 代码噪音最小。

【讨论】:

你提出了一个关于大型结果集的好观点。这两个库都实现了 Streaming。我更喜欢获取结果集并将其转换为集合,因为它更易于调试,而且一般来说,解析为 JSON 的结果集不应该很大,我也经常有更复杂的对象,需要来自多个查询的额外数据或其他来源。最后一点是,此方法允许您更改表,唯一需要更改的代码是查询字符串。 “一般来说,解析成 JSON 的结果集应该不会很大”。没错,客户端服务器之间的海量数据结构应该考虑某种分页。但是后来有人提出了一个关于并发客户端的问题,一直有 +3000 个活动客户端,每个客户端读取每个 JSON 100 行,这会产生不错的 jvm 噪音。 我想了更多...你是正确的。内存问题绝对是一个问题。我正在考虑我自己的设计,并且可能使用代理,每个查询元素都有一个 sendToStream 方法。【参考方案4】:

您可以使用任何 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;

【讨论】:

【参考方案5】: 将结果集转换为List&lt;Map&lt;String, Object&gt;&gt;(每个映射都包含一行,其中列名作为键,列内容作为值,List 是此类行的列表) 使用 Gson 或 Jackson 库将此对象转换为 JSON。

【讨论】:

【参考方案6】:

如果你想使用 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>

Jackson 应该在您的类路径中(即 Maven 依赖项)。

【讨论】:

【参考方案7】:

对 Java 使用 jsonlib。遍历结果集并从 jsonlib 中将所需的属性添加为 JSONObject 对象。

【讨论】:

【参考方案8】:

在我的应用程序(浏览器上的 MySQL/java servlet/javascript)中,我使用带有快速字符串构建器方法和通用 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();

【讨论】:

【参考方案9】:

我在这里找到了最佳解决方案。

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;

【讨论】:

【参考方案10】:

如果您使用 Spring 的 JDBCTemplate 来执行存储函数,该函数将光标作为表条目列表返回,然后您希望将其映射为指定 bean 的列表,那么有最简洁的解决方案:

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

不客气!

编码愉快!

【讨论】:

以上是关于(java)如何将从数据库中查询出来的结果集转换为对应类的对象?可考虑hibernate。的主要内容,如果未能解决你的问题,请参考以下文章

java怎么从mysql查询出来的结果转化为二维数组,举个例子

hibernate进行多表查询每个表中各取几个字段,也就是说查询出来的结果集没有一个实体类与之对应如何解决?

JPA:如何将原生查询结果集转换为 POJO 类集合

如何将查询的结果集转换为可以进一步解析以创建json的pojo类?

在union的时候怎么强制指定数据类型

hibernate框架之-查询结果集返回类型