Я пытаюсь использовать Java с Spring Boot, чтобы получить результат хранимой процедуры в базе данных.
Я хочу, чтобы метод getBillInformation
возвращал объект ArrayList<BillInformation>
. Я думал, что метод SimpleJdbcCall.returningResultSet()
сделает это в тандеме с интерфейсом RowMapper<T>
.
Когда я вызываю метод SimpleJdbcCall.execute()
, я получаю обратно объект Map<String, Object>
. Object
имеет тип ArrayList<BillInformation>
, но я получаю unchecked
ошибок во время выполнения. Этот метод не очень хорошо подходит для обработки нескольких строк вывода.
Я тоже пробовал использовать метод SimpleJdbcCall.executeObject()
, но всякий раз, когда я пробовал код return jdbcCall.executeObject(ArrayList.class, callParams);
, я получал Null Pointer Error
.
Может ли кто-нибудь помочь мне заставить этот метод чисто возвращать ArrayList<BillInformation>
, содержащий сопоставленные результаты хранимой процедуры моей базы данных? Спасибо!
@Service
public class BillInformationService {
@Autowired
DataSource dataSource;
public ArrayList<BillInformation> getBillInformation(Integer loadId, String trackingNumber) {
JdbcTemplate template = new JdbcTemplate(dataSource);
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(template)
.withProcedureName("getBillInformationByLcIdAndTrackingNumber")
.returningResultSet("billInformation", (RowMapper<BillInformation>) (rs, rowNum) -> {
BillInformation billInformation = new BillInformation();
billInformation.setAccountNumber(rs.getString("ldc_acct"));
billInformation.setStartDate(rs.getDate("start_date").toLocalDate());
billInformation.setEndDate(rs.getDate("end_date").toLocalDate());
billInformation.setConsumption(rs.getInt("cons"));
billInformation.setTrackingNumber(rs.getString("tracking_no"));
billInformation.setLoadId(rs.getInt("lc_id"));
billInformation.setCrossReferenceNumber(rs.getString("xref_num"));
billInformation.setTransactionDate(rs.getDate("tran_date").toLocalDate());
billInformation.setReportMonth(rs.getDate("report_month").toLocalDate());
billInformation.setBillParty(rs.getString("bill_party"));
return billInformation;
});
System.out.println("CLASS: " + jdbcCall.getClass());
jdbcCall.addDeclaredParameter(new SqlParameter("lcId", Types.INTEGER));
jdbcCall.addDeclaredParameter(new SqlParameter("trackingNumber", Types.VARCHAR));
Map<String, String> callParams = new HashMap<>();
callParams.put("lcId", String.valueOf(loadId));
callParams.put("trackingNumber", trackingNumber);
return (ArrayList<BillInformation>) jdbcCall.execute(callParams).get("billInformation");
}
}
Текст оператора создания хранимой процедуры (обратите внимание, что я усек несколько полей в приведенном выше тексте, чтобы сократить сообщение):
DELIMITER $$
CREATE DEFINER=`database`@`%` PROCEDURE `getBillingByLcIdAndTrackingNumber`(lcId INT,trackingNumber VARCHAR(30))
BEGIN
(
SELECT m.ldc_acct, m.rate_class, m.load_profile, m.start_date,
m.end_date, SUM(m.cons) as cons,
CASE WHEN tp.peak IS NULL THEN 'TOTAL' ELSE tp.peak END as season_map,
l.ldc_id,
n.nyiso_zone, m.tracking_no, m.lc_id, m.meas_id, m.xref_num,
(CASE WHEN mbt.rate_option = 'MHP' THEN true ELSE false END) AS is_hourly,
u.drop_end,
u.ldc_name,
mbt.rate_option,
u.iso_id,
m.tran_date,
mbt.report_month,
mbt.bill_party
FROM
load_tab l
JOIN (select m.m_id,m.ldc_acct, m.rate_class, m.load_profile, m.start_date, m.end_date, m.cons, m.ptd_code, m.tod,
m.tracking_no, m.lc_id, m.meas_id, m.xref_num,m.tran_date
from meter_usage m
WHERE
m.tracking_no = trackingNumber AND m.uom = 'KH' AND m.lc_id = lc_id AND m.lc_id = lcId
) as m ON l.lc_id = m.lc_id
JOIN nyiso_subzones n ON l.zone = n.zone_id
LEFT OUTER JOIN
fedata.tod_peak tp ON tp.tod = m.tod
join ldcs u on l.ldc_id = u.ldc_id
INNER JOIN
load_info li
ON li.lc_id = l.lc_id
LEFT OUTER JOIN
fedata.meter_bill_type mbt
ON mbt.tracking_no = m.tracking_no
AND mbt.lc_id = m.lc_id
where u.retail_rate in (1,2)
GROUP BY
m.ldc_acct, m.rate_class, m.load_profile, m.start_date,
m.end_date,m.tran_date,
CASE WHEN tp.peak IS NULL THEN 'TOTAL' ELSE tp.peak END,
l.ldc_id,
n.nyiso_zone, m.tracking_no, m.lc_id, m.meas_id, m.xref_num,
u.drop_end,
u.ldc_name,
u.iso_id,
mbt.report_month,
mbt.bill_party
ORDER BY m.meas_id,m.m_id
)
union
(
SELECT m.ldc_acct, m.rate_class, m.load_profile, m.start_date, m.end_date, m.cons, s.season_map, l.ldc_id,
n.nyiso_zone, m.tracking_no, m.lc_id, m.meas_id, m.xref_num,
(CASE WHEN mbt.rate_option = 'MHP' THEN true ELSE false END) AS is_hourly,
u.drop_end,
u.ldc_name,
mbt.rate_option,
u.iso_id,
m.tran_date,
mbt.report_month,
mbt.bill_party
FROM load_tab l
JOIN
(select m.m_id,m.ldc_acct, m.rate_class, m.load_profile, m.start_date, m.end_date, m.cons, m.ptd_code, m.tod,
m.tracking_no, m.lc_id, m.meas_id, m.xref_num,m.tran_date
from meter_usage m
WHERE
m.tracking_no = trackingNumber AND m.lc_id = lcId AND m.uom = 'KH' and m.meas_id IN ('00','01','52') and tod = 51 and meter_num = ''
) as m ON l.lc_id = m.lc_id
JOIN nyiso_subzones n ON l.zone = n.zone_id
JOIN season s ON (case m.tod when '' then m.ptd_code else m.tod end) = s.season_code
join ldcs u on l.ldc_id = u.ldc_id
INNER JOIN
load_info li
ON li.lc_id = l.lc_id
LEFT OUTER JOIN
fedata.meter_bill_type mbt
ON mbt.tracking_no = m.tracking_no
AND mbt.lc_id = m.lc_id
where u.retail_rate = 3
ORDER BY m.meas_id,m.m_id
)
UNION
(
SELECT m.ldc_acct, m.rate_class, m.load_profile, m.start_date,
m.end_date, SUM(m.cons) as cons,
NULL AS season_map,
l.ldc_id,
NULL as nyiso_zone,
m.tracking_no,
m.lc_id,
m.meas_id,
m.xref_num,
(CASE WHEN l.hist_type = 4 THEN true ELSE false END) AS is_hourly,
u.drop_end,
u.ldc_name,
mbt.rate_option,
u.iso_id,
m.tran_date,
mbt.report_month,
mbt.bill_party
FROM
load_tab l
JOIN (select m.m_id,m.ldc_acct, m.rate_class, m.load_profile, m.start_date, m.end_date, m.cons, m.ptd_code, m.tod,
m.tracking_no, m.lc_id, m.meas_id, m.xref_num,m.tran_date
from meter_usage m
WHERE
m.uom = 'KH'
AND m.meas_id IN ('00','01','52')
AND m.tod_desc != 'I'
AND m.tod = '51'
AND m.tracking_no = trackingNumber
AND m.lc_id = lcId
) as m ON l.lc_id = m.lc_id
join ldcs u on l.ldc_id = u.ldc_id
INNER JOIN
load_info li
ON li.lc_id = l.lc_id
LEFT OUTER JOIN
fedata.meter_bill_type mbt
ON mbt.tracking_no = m.tracking_no
AND mbt.lc_id = m.lc_id
where u.iso_id = 2
GROUP BY
m.ldc_acct, m.rate_class, m.load_profile, m.start_date,
m.end_date,
l.ldc_id,
m.tracking_no, m.lc_id, m.meas_id, m.xref_num,
u.drop_end,
u.ldc_name,
u.iso_id,
m.tran_date,
mbt.report_month,
mbt.bill_party
ORDER BY m.m_id
)
ORDER BY
meas_id,
tracking_no;
END$$
DELIMITER ;