mybatis 3 + spring:我可以根据查询结果中的列值将收集结果分为两组

问题描述

我有2个这样的Java模型

public class DeviceData {
    private String name;
    private List<Metric> up;
    private List<Metric> down;
}
public class Metric{
    private Long data;
    private LocalDateTime timeStamp;
}

实际查询数据库中按名称获取结果,列名称如下。

-------------------------------------------------------------
data | timestamp            | name  | trafficType
-------------------------------------------------------------
10   | 2020-10-08 13:10:00  | test1 | down
20   | 2020-10-08 12:15:00  | test1 | up
30   | 2020-10-08 13:10:00  | test2 | down
40   | 2020-10-08 12:15:00  | test2 | up

不,我一直在尝试使mybatis xml根据基于trafficType列的上述查询结果分为两组,然后将划分的集合分别复制到DeviceData.java类的向上列表和向下列表中。我尝试使用鉴别器,但由于两种情况我都无法使用。

到目前为止,resultMap就是这样。(基本)

<resultMap id="trafficData" type="DeviceData" autoMapping="true">
    <id property="name" column="name" jdbcType="VARCHAR"/>
    <collection property="upload" ofType="Metric" autoMapping="true">
    </collection>
</resultMap>

尝试实现此JSON响应:

[
    {
        "name": "test1","down": [
            {
                "data": 10,"timeStamp": "2020-10-08 13:10:00"
            }
        ],"up": [
            {
                "data": 20,"timeStamp": "2020-10-08 12:15:00"
            }
        ]
    },{
        "name": "test2,"down": [

            {
                "data": 30,"up": [

            {
                "data": 40,"timeStamp": "2020-10-08 12:15:00"
            }
        ]
    }
]

感谢任何想法/语法,谢谢!

解决方法

可能无法将单列的结果分为两个列表。

要获得所需的结果,您需要将结果集中的数据分开。
有点冗长,但是例如可以使用CASE表达式。

select
  name,case traffic_type
    when 'up' then ts
    else null
  end as up_timeStamp,case traffic_type
    when 'up' then data
    else null
  end as up_data,case traffic_type
    when 'down' then ts
    else null
  end as down_timeStamp,case traffic_type
    when 'down' then data
    else null
  end as down_data
from device_data

在您有问题的样本数据的情况下,结果将如下所示。

+-------+-----------------------------+----------+-----------------------------+------------+  
| NAME  |         UP_TIMESTAMP        |  UP_DATA |        DOWN_TIMESTAMP       |  DOWN_DATA |  
+-------+-----------------------------+----------+-----------------------------+------------+  
| test1 |  null                       |  null    |  2020-10-08 13:10:00.000000 |  10        |  
| test1 |  2020-10-08 12:15:00.000000 |  20      |  null                       |  null      |  
| test2 |  null                       |  null    |  2020-10-08 13:10:00.000000 |  30        |  
| test2 |  2020-10-08 12:15:00.000000 |  40      |  null                       |  null      |  
+-------+-----------------------------+----------+-----------------------------+------------+  

要映射到up列表的数据在前缀为up_的列中。
down也是如此。

关于结果映射,应该有两个<collection />,因为DeviceType中有两个列表属性。
在这种情况下,最好为Metric定义另一个结果图,并与columnPrefix一起使用。

<resultMap id="trafficData" type="test.DeviceData">
  <id property="name" column="name" />
  <collection property="up"
      resultMap="metric" columnPrefix="up_" />
  <collection property="down"
      resultMap="metric" columnPrefix="down_" />
</resultMap>

<resultMap id="metric" type="test.Metric">
  <id property="timeStamp" column="timeStamp" />
  <result property="data" column="data" />
</resultMap>

这里我假设timeStampMetric的ID。
如果没有<id />,MyBatis将使用timeStampdata的组合作为ID,即使结果相同,效率也会降低。

如果要自动映射,只需将autoMapping="true"添加到结果图。

p.s。
另外,也可以使用ResultHandler

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...