Взглянув на то, что вы предоставили, кажется, что у вас есть беспорядочная коллекция битов кода, и хотя большая часть этого есть, она не все там и не совсем все в правильном порядке.
Чтобы получить некоторую ясность, попробуйте разбить то, что вы делаете, на отдельные этапы, и найдите метод, который фокусируется на каждом этапе. В частности, вы пишете
Я пытаюсь проанализировать файл с разделителями каналов и вставить поля в таблицу
Это естественно разбивается на две части:
- синтаксический анализ файла с разделителями каналов и
- вставка полей в таблицу.
В первой части, похоже, большинство частей уже есть в вашем insertZygateData
метод. В частности, эта строка считывает все строки файла в список:
List<String> lines = Files.readAllLines(Paths.get(filePath));
Затем эти строки удаляют первую и последнюю строки из списка прочитанных строк:
// remove date and amount
lines.remove(0);
lines.remove(lines.size() - 1);
Затем у вас есть некоторый код, который выглядит немного неуместным: похоже, это связано с вставкой в базу данных, но мы еще не создали наш список ZygateEntity
объектов, так как мы еще не закончили чтение файла. Давайте пока поместим это for
l oop в одну сторону.
Наконец, мы берем список строк, которые мы читаем, разбиваем их по каналам, создаем ZygateEntity
объекты из деталей и создаем List
из этих объектов, которые мы затем возвращаем.
return lines.stream()
.map(s -> s.split("[|]")).map(val -> new ZygateEntity(val[0],val[1],val[2])).collect(Collectors.toList());
Соединяя этот лот, у нас есть полезный метод, который анализирует файл, выполняя первую часть задачи:
private List<ZygateEntity> parseZygateData() throws IOException {
String filePath = "C:\\DEV\\Test_file.xlsx";
List<String> lines = Files.readAllLines(Paths.get(filePath));
// remove date and amount
lines.remove(0);
lines.remove(lines.size() - 1);
return lines.stream()
.map(s -> s.split("[|]")).map(val -> new ZygateEntity(val[0],val[1],val[2])).collect(Collectors.toList());
}
(Конечно, мы могли бы добавить параметр для пути к файлу для чтения, но для того, чтобы что-то работало, нормально придерживаться текущего жестко заданного пути к файлу.)
* 1038 Итак, у нас есть список из
ZygateEntity
объектов. Как мы напишем метод для вставки их в базу данных?
Мы можем найти пару необходимых нам компонентов в вашем примере кода. Во-первых, нам нужен оператор SQL для вставки данных. Это в вашем cleanThetable
методе:
String sql = "INSERT INTO Landing.midrange_xygate_load (account_name,command_name,system_name)"+
"VALUES (:account_name,:command_name,:system_name)";
У нас тогда есть l oop:
for (ZygateEntity zygateInfo : parseData){
new MapSqlParameterSource("account_name", zygateInfo.getAccountName())
.addValue("command_name", zygateInfo.getCommandName())
.addValue("system_name", zygateInfo.getSystemName())
.getValues();
}
Этот l oop создает MapSqlParameterSource
из каждого ZygateEntity
объекта, а затем преобразует его в Map<String, Object>
, вызывая метод getValues()
. Но тогда это ничего не делает с этим значением. Фактически вы создаете эти объекты и снова избавляетесь от них, ничего не делая с ними. Это не идеально.
A MapSqlParameterSource
используется с пружиной NamedParameterJdbcTemplate
. В вашем коде упоминается jdbcTemplate
, представляющее собой поле в классе, которое анализирует данные и вставляет их в базу данных, но вы не показываете полный код этого класса. Я собираюсь предположить, что это NamedParameterJdbcTemplate
, а не "обычный" JdbcTemplate
.
NamedParameterJdbcTemplate
содержит метод update
, который принимает строку SQL и SqlParameterSource
. У нас есть строка SQL, и мы создаем объекты MapSqlParameterSource
, поэтому мы можем использовать их для выполнения вставки. Нет смысла создавать один из этих MapSqlParameterSource
объектов только для преобразования его в карту, поэтому давайте удалим вызов getValues()
.
Итак, теперь у нас есть метод для вставки данных в базу данных:
public void insertZygateData(List<ZygateEntity> parseData) {
String sql = "INSERT INTO Landing.midrange_xygate_load (account_name,command_name,system_name)"+
"VALUES (:account_name,:command_name,:system_name)";
for (ZygateEntity zygateInfo : parseData){
SqlParameterSource source = new MapSqlParameterSource("account_name", zygateInfo.getAccountName())
.addValue("command_name", zygateInfo.getCommandName())
.addValue("system_name", zygateInfo.getSystemName());
jdbcTemplate.update(sql, source);
}
}
Наконец, давайте посмотрим на ваш cleanThetable
метод. Как и в случае с другими, давайте сосредоточимся на одной задаче: похоже, что в тот момент, когда вы пытаетесь удалить данные из таблицы, а затем вставить их тем же методом, давайте просто сосредоточимся на удалении данных. теперь у нас есть метод для вставки данных.
Мы не можем сразу избавиться от строки String sql = ...
, потому что блок finally
в вашем коде использует ее. Если stmt
не равно нулю, вы пытаетесь запустить оператор INSERT
и затем закрыть stmt
.
Однако stmt
никогда не присваивается никакое значение, кроме null
, поэтому оно остается null
. Поэтому stmt != null
всегда false
, поэтому оператор INSERT
никогда не выполняется. Ваш finally
блок никогда ничего не делает, так что лучше всего его полностью удалить. С отсутствующим блоком finally
вы также можете избавиться от локальной переменной stmt
и строки sql
, и у нас останется метод, целью которого является усечение таблицы:
public boolean cleantheTable() throws SQLException {
boolean truncated = false;
try {
String sqlTruncate = "truncate table Landing.midrange_xygate_load";
jdbcTemplate.execute(sqlTruncate);
truncated = true;
} catch (Exception e) {
e.printStackTrace();
truncated = false;
return truncated;
}
log.info("Clean the table return value :" + truncated);
return truncated;
}
I Вы оставите за собой право написать код, который вызывает эти методы. Я написал некоторый код для этой цели, и он успешно запустился и был вставлен в базу данных.
Итак, в общем, данные не записывались в вашу базу данных, потому что вы никогда не обращались к базе данных вставить любой. В вашем методе insertZygateData
вы создавали объекты-источники параметров, но не делали с ними ничего полезного, а в вашем методе cleanThetable
выглядело, как будто вы пытались вставить данные, но ваша строка jdbcTemplate.execute(sql)
, которая пыталась это сделать это никогда не бежало. Даже если stmt
не равно нулю, эта строка не будет работать, поскольку вы нигде не передавали значения параметров: вы получите исключение из базы данных, так как оно будет ожидать значений параметров, но вы никогда не дадите его любой.
Надеюсь, мое объяснение даст вам способ заставить ваш код работать и поможет понять, почему это не так.