Ответ 1
Кажется, что это комбинация Spring "bug" и драйвера "ошибка".
Spring пытается определить тип данных столбца каждый раз, когда вызывается setValue()
. Он делает это, вызывая PreparedStatementMetaData.getParameterMetaData()
Это, по-видимому, приводит к отправке инструкции "подготовить" в базу данных, которая сама по себе довольно быстро (не более 1 мс на моем ноутбуке), но поскольку она вызывается для каждого столбца для каждой строки это суммирует до большого количества времени (он требует для каждого значения, не равного нулю, что приводит к примерно 23 000 вызовов)
В некоторой степени это скорее ошибка Spring, а ошибка драйвера, потому что не кэширование метаданных параметра не имеет смысла (по крайней мере, на мой взгляд). Драйвер MySQL JDBC не поддерживает getParameterMetaData()
и Spring знает об этом, и поэтому эта "ошибка" не отображается с MySQL, потому что Spring никогда не вызывает этот метод.
Я не уверен, что поведение драйвера JDBC Postgres можно классифицировать как ошибку, но было бы неплохо, если бы драйвер выполнял кэширование этих метаданных после первого вызова.
Spring может быть убежден, что не получить метаданные оператора через свойство spring.jdbc.getParameterType.ignore
Итак, поставив:
System.setProperty("spring.jdbc.getParameterType.ignore", "true");
перед строка:
LetsGo letsGo = new LetsGo();
это поведение отключено.
Свойство должно быть установлено , прежде чем Spring будет инициализирован.
Когда я делаю это с вашим образцовым проектом, вставка работает на 500 мс на моем ноутбуке.
Изменить
После просмотра комментария относительно использования драйвера Postgres-NG я выкопал источники "официального" драйвера и драйвера NG, а драйвер NG скрывает метаданные параметров после первого вызова, тогда как официальный драйвер не объясняет, почему использование драйвера NG намного быстрее (без отключения вызова в Spring)