【问题标题】:Construct JSON Object based on Query Result List根据查询结果列表构造 JSON 对象
【发布时间】:2015-10-26 14:25:00
【问题描述】:

试图找出解决我面临的问题的方法,但到目前为止在网上找不到任何可以帮助我的材料。

基本上,我拥有的是一个休息控制器中的方法,它将查询字符串传递给我的 Hibernate DAO 并返回请求的数据。

例如

@RequestMapping("/submitQuery")
    public Object submitQuery() {
// example of a query string, note this is dynamic and thus never hardcoded
        String query = "SELECT C.amount, C.transactionDate, R.amount, R.transactionDate FROM CAR C, RFT R";

        return  DAO.submitQuery(query);
    }

道:

public List<T> submitQuery(String query) {
        Query q = getSession().createQuery(query);
        return q.list();
    }

此查询字符串将是动态的,因此创建实体并将其附加到查询的选项不是一个选项。

上述方法将返回以下格式的数据:

[
    [
        -4890.38,
        1451826000000,
        25.04,
        1421499600000
    ],
    [
        -660,
        1413205200000,
        25.04,
        1421499600000
    ],
    [
        -10768.53,
        1423054800000,
        25.04,
        1421499600000
    ]
]

因此,没有标题,并且除此之外,日期已转换为数字。 我想要实现的是让方法以以下格式返回结果:

[
    [
        "amountc" : -4890.38,
        "datec" : "01-03-2014",
        "amountr" : 25.04,
        "dater" : "01-03-2014"
    ],
    [
        "amountc" : -660,
        "datec" : "03-02-2014",
        "amountr" : 25.04,
        "dater" : "03-02-2014"
    ],
    [
        "amountc" : -10768.53,
        "datec" : "01-02-2014",
        "amountr" : 25.04,
        "dater" : "01-02-2014"
    ]
]

任何建议/帮助将不胜感激。

注意:不能使用 DTO 或实体,因为查询字符串是动态的并且会发生变化。我那里的查询字符串只是作为示例。

【问题讨论】:

  • 使用ammountc,datec,amountr,dater 字段创建一个数据传输对象,而不是返回DAO.submitQuery(query),从该列表构建一个DTO 列表并返回它。
  • 查询字符串更改,因此 DTO 需要更改。不能使用对象。
  • 将结果转换成地图
  • 你能举例说明你的意思吗@ShijuKBabu

标签: java json spring hibernate spring-mvc


【解决方案1】:

如果不知道T 的样子,很难说...但我相信T 的toString 方法是您的朋友。

【讨论】:

  • T 无关紧要,因为它将返回一个包含结果的对象。但同样我不能使用预定义的实体作为查询字符串的变化。
  • T 不是无关紧要的,只要它出现在你的 DAO submitQuery 方法签名中
  • 您不必定义 T,因此它会返回一个对象,使其与它是什么无关。
  • 我说的不是这个。您可以强制执行某些格式的 toString
  • 对,但这是假设有一个特定的对象/实体要转换为字符串。我没有使用对象/实体,因为查询是动态的,可以随心所欲地改变。
【解决方案2】:

你可以创建一个对象模型

例如

class TransObj  {

public double amountc;
public String datec;
public double amountr;
public String  dater;
public double getAmountc() {
    return amountc;
}
public void setAmountc(double amountc) {
    this.amountc = amountc;
}
public String getDatec() {
    return datec;
}
public void setDatec(String datec) {
    this.datec = datec;
}
public double getAmountr() {
    return amountr;
}
public void setAmountr(double amountr) {
    this.amountr = amountr;
}
public String getDater() {
    return dater;
}
public void setDater(String dater) {
    this.dater = dater;
}
}

然后将你的代码修改为这个

@RequestMapping("/submitQuery")
public List<TransObj> submitQuery() {
    String query = "SELECT C.amount as amountc, C.transactionDate as datec, R.amount as amountr, R.transactionDate as dater FROM CAR C, RFT R";

    return  DAO.submitQuery(query);
}


public List<TransObj> submitQuery(String query) {
        Query q = getSession().createQuery(query);
        return q.list();
    }

【讨论】:

  • 对象很简单,我不能使用对象,因为查询字符串是动态的,所以一旦它改变你的对象就会过时并引发错误。
【解决方案3】:

创建一个 bean 类 let ABC.java 包含 setter 和 getter 方法,并将 toString 覆盖到 DTO 类中,像这样。

  public class ABC implements Serializable{

    private double amountc;
    private String datec;
    private double amountr;
    private String  dater;

    ... setter and getters

    @Override
    public String toString(){
        return "[\"amountc:\""+amountc+",\"datec:\""+datec+",\"amountr:\""+amountr+",\"dater:\""+dater+"]";
    }
}

并对 DAO 实现类进行少量更改

public List<ABC> submitQuery(String query) {
    Query q = getSession().createQuery(query).setResultTransformer(Transformers.aliasToBean(ABC.class));
    List<ABC> resultList=q.list();
    System.out.println(resultList); //desire output 
    return resultList;
}

请确保实体和DTO类ABC的数据类型相同

已编辑

如果您不想要任何 bean 或 DTO,那么您可以使用 Criteria.ALIAS_TO_ENTITY_MAP 将结果查询转换为具有键值对的映射对象。键名称与 SQL 查询中的别名名称相同。如果您没有在 sql 查询中使用别名,那么键就像 0,1,2,3,.... 等等。

public List<ABC> submitQuery(String query) {
        Query q = getSession().createQuery(query).setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
        List<ABC> resultList=q.list();
        System.out.println(resultList); //desire output 
        return resultList;
    }

【讨论】:

  • 您是否阅读了“不能使用实体或 DTO”的部分?当查询变为“select r.id from car r”时会发生什么?
  • 如果您不想要 DTO 或实体,那么您可以使用 'Criteria.ALIAS_TO_ENTITY_MAP' 将结果传输到带有键值对的哈希映射中。
【解决方案4】:

我想Sunil 已经回答了。检查有关如何转换为地图的已编辑部分。或者试试下面的

public List<Map<String,Object>> submitQuery(String query) {
        Query q = getSession().createQuery(query);
        return q.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
    }

【讨论】:

  • 瞧!太神奇了.. ;) 但是列的序列以某种方式以 JSON 格式改变了..
  • 谢谢.. List> 非常适合我。
【解决方案5】:

在 HQL 中使用 select new map 语法来获取 Map 中每一行的结果。

基本上,如果您像这样构建 HQL 查询:

"SELECT new HashMap(user.id as id, user.firstName as fullName) FROM User user"; 

然后返回值将形成一个映射结构,这是一种易于序列化为 JSON 的良好格式。您的地图(和 json)将如下所示:

{
"id" : "<id value>",

"fullname" : "<firstname value>"
}

【讨论】:

  • 请在您的帖子中添加更多详细信息。不鼓励仅提供链接的答案,因为如果提供的链接发生变化,它们将无用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 2011-04-24
  • 2022-06-10
  • 1970-01-01
相关资源
最近更新 更多