<?xml version="1.0" encoding="UTF-8" ?>
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<mapper namespace="com.battery.business.mapper.TDeviceIngestRecordMapper">
|
<resultMap id="TDeviceIngestRecordResultMap" type="com.battery.business.domain.TDeviceIngestRecord">
|
<id property="ingestId" column="ingest_id"/>
|
<result property="adapterCode" column="adapter_code"/>
|
<result property="payloadKind" column="payload_kind"/>
|
<result property="devtype" column="devtype"/>
|
<result property="devid" column="devid"/>
|
<result property="subdevid" column="subdevid"/>
|
<result property="chlid" column="chlid"/>
|
<result property="recordSequence" column="record_sequence"/>
|
<result property="recordKey" column="record_key"/>
|
<result property="sourceRef" column="source_ref"/>
|
<result property="deviceTimeUtc" column="device_time_utc"/>
|
<result property="deviceTimeRaw" column="device_time_raw"/>
|
<result property="timezoneId" column="timezone_id"/>
|
<result property="cycleNo" column="cycle_no"/>
|
<result property="stepNo" column="step_no"/>
|
<result property="relativeTimeSeconds" column="relative_time_seconds"/>
|
<result property="voltageV" column="voltage_v"/>
|
<result property="currentA" column="current_a"/>
|
<result property="chargeCapacityAh" column="charge_capacity_ah"/>
|
<result property="dischargeCapacityAh" column="discharge_capacity_ah"/>
|
<result property="chargeEnergyWh" column="charge_energy_wh"/>
|
<result property="dischargeEnergyWh" column="discharge_energy_wh"/>
|
<result property="payloadJson" column="payload_json"/>
|
<result property="contentSha256" column="content_sha256"/>
|
<result property="receivedAtUtc" column="received_at_utc"/>
|
</resultMap>
|
|
<!-- 落地行的显式列名,顺序与建表脚本一致;列集合不随运行期表结构变化。 -->
|
<sql id="ingestColumns">ingest_id, adapter_code, payload_kind, devtype, devid, subdevid, chlid, record_sequence, record_key,
|
source_ref, device_time_utc, device_time_raw, timezone_id, cycle_no, step_no, relative_time_seconds,
|
voltage_v, current_a, charge_capacity_ah, discharge_capacity_ah, charge_energy_wh, discharge_energy_wh,
|
payload_json, content_sha256, received_at_utc</sql>
|
|
<!-- 驼峰映射未开启(见 mybatis-config.xml),列名带下划线的查询一律显式映射。 -->
|
<resultMap id="TDeviceIngestChannelResultMap" type="com.battery.business.domain.vo.TDeviceIngestChannel">
|
<result property="devtype" column="devtype"/>
|
<result property="devid" column="devid"/>
|
<result property="subdevid" column="subdevid"/>
|
<result property="chlid" column="chlid"/>
|
<result property="lastDataAt" column="last_data_at"/>
|
</resultMap>
|
|
<!-- 落地行只追加:来源行身份(adapter_code + 类别 + record_key)撞键即视为重复推送,不改动既有事实。 -->
|
<insert id="insertIngestRecord" parameterType="com.battery.business.domain.TDeviceIngestRecord"
|
useGeneratedKeys="true" keyProperty="ingestId">
|
insert ignore into t_device_ingest_record
|
(adapter_code, payload_kind, devtype, devid, subdevid, chlid, record_sequence, record_key, source_ref,
|
device_time_utc, device_time_raw, timezone_id, cycle_no, step_no, relative_time_seconds,
|
voltage_v, current_a, charge_capacity_ah, discharge_capacity_ah, charge_energy_wh, discharge_energy_wh,
|
payload_json, content_sha256, received_at_utc)
|
values (#{adapterCode}, #{payloadKind}, #{devtype}, #{devid}, #{subdevid}, #{chlid}, #{recordSequence},
|
#{recordKey}, #{sourceRef}, #{deviceTimeUtc}, #{deviceTimeRaw}, #{timezoneId}, #{cycleNo}, #{stepNo},
|
#{relativeTimeSeconds}, #{voltageV}, #{currentA}, #{chargeCapacityAh}, #{dischargeCapacityAh},
|
#{chargeEnergyWh}, #{dischargeEnergyWh}, cast(#{payloadJson} as json), #{contentSha256}, #{receivedAtUtc})
|
</insert>
|
|
<!-- 心跳单独占一行并覆盖接收时间:它只表示"取数程序还在推",不是设备事实,没有保留历史的意义。 -->
|
<insert id="upsertHeartbeat" parameterType="com.battery.business.domain.TDeviceIngestRecord">
|
insert into t_device_ingest_record
|
(adapter_code, payload_kind, devtype, devid, subdevid, chlid, record_sequence, record_key, source_ref,
|
device_time_utc, device_time_raw, timezone_id, cycle_no, step_no, relative_time_seconds,
|
voltage_v, current_a, charge_capacity_ah, discharge_capacity_ah, charge_energy_wh, discharge_energy_wh,
|
payload_json, content_sha256, received_at_utc)
|
values (#{adapterCode}, #{payloadKind}, #{devtype}, #{devid}, #{subdevid}, #{chlid}, #{recordSequence},
|
#{recordKey}, #{sourceRef}, #{deviceTimeUtc}, #{deviceTimeRaw}, #{timezoneId}, #{cycleNo}, #{stepNo},
|
#{relativeTimeSeconds}, #{voltageV}, #{currentA}, #{chargeCapacityAh}, #{dischargeCapacityAh},
|
#{chargeEnergyWh}, #{dischargeEnergyWh}, cast(#{payloadJson} as json), #{contentSha256}, #{receivedAtUtc})
|
on duplicate key update received_at_utc = values(received_at_utc)
|
</insert>
|
|
<select id="selectIngestRecordHashByKey" resultType="string">
|
select lower(hex(content_sha256)) from t_device_ingest_record
|
where adapter_code = #{adapterCode} and payload_kind = #{payloadKind} and record_key = #{recordKey}
|
limit 1
|
</select>
|
|
<select id="selectHeartbeatAt" resultType="java.util.Date">
|
select max(received_at_utc) from t_device_ingest_record
|
where adapter_code = #{adapterCode} and payload_kind = 'HEARTBEAT'
|
</select>
|
|
<!-- 最近数据时间取该通道自己的采样行:没有新采样行就是没有,不按拓扑上报时间代替。 -->
|
<select id="selectTopologyChannels" resultMap="TDeviceIngestChannelResultMap">
|
select t.devtype, t.devid, t.subdevid, t.chlid,
|
(select max(prior.device_time_utc) from t_device_ingest_record prior
|
where prior.adapter_code = t.adapter_code and prior.payload_kind = 'SAMPLE'
|
and prior.devtype = t.devtype and prior.devid = t.devid
|
and prior.subdevid = t.subdevid and prior.chlid = t.chlid) as last_data_at
|
from t_device_ingest_record t
|
where t.adapter_code = #{adapterCode} and t.payload_kind = 'TOPOLOGY'
|
order by t.devid, t.subdevid, t.chlid
|
</select>
|
|
<select id="selectLatestSample" resultMap="TDeviceIngestRecordResultMap">
|
select <include refid="ingestColumns"/> from t_device_ingest_record
|
where adapter_code = #{adapterCode} and payload_kind = 'SAMPLE'
|
and devtype = #{devtype} and devid = #{devid} and subdevid = #{subdevid} and chlid = #{chlid}
|
order by device_time_utc desc, record_sequence desc
|
limit 1
|
</select>
|
|
<!-- 只取严格晚于水位的行;同秒多行按协议序号各自成立,不按秒合并。 -->
|
<select id="selectSamplesSince" resultMap="TDeviceIngestRecordResultMap">
|
select <include refid="ingestColumns"/> from t_device_ingest_record
|
where adapter_code = #{adapterCode} and payload_kind = 'SAMPLE'
|
and devtype = #{devtype} and devid = #{devid} and subdevid = #{subdevid} and chlid = #{chlid}
|
<if test="watermarkTime != null">
|
and (device_time_utc > #{watermarkTime}
|
or (device_time_utc = #{watermarkTime} and record_sequence > #{watermarkSequence}))
|
</if>
|
order by device_time_utc, record_sequence
|
limit #{limit}
|
</select>
|
</mapper>
|