Обходной путь setDate для PreparedStatement в Java

У меня есть метод с PreparedStatement

    public static boolean TSTHolidayPrepMapper(PreparedStatement st, TSTObject item, MapperType type) throws SQLException
{
    TSTHoliday hol = (TSTHoliday) item;
    int id = 1;
    if (type != MapperType.DELETE)
    {
        st.setString(id++, hol.getCountry());
        st.setString(id++, hol.getCommodity());
        st.setString(id++, hol.getMarketArea());
        st.setString(id++, hol.getMarketPlace());
        st.setString(id++, hol.getName());

        st.setDate(id++, hol.getCalenderDate());
    }
    if (type != MapperType.INSERT)
        st.setInt(id++, hol.getId());

    return true;
}

который ожидает объект типа Date в st.setDate(id++, hol.getCalenderDate()), но метод getCalenderDate() предоставляет объект класса, который я создал сам, под названием TSTLocalDate

public class TSTLocalDate extends TSTObject
{
public int year;
public int month;
public int day;

public TSTLocalDate()
{
    this.year = 1900;
    this.month = 1;
    this.day = 1;
}

public TSTLocalDate(int year, int month, int day)
{
    this.year = year;
    this.month = month;
    this.day = day;
}

public String toString()
{
    String val = "" + year + "-" + TSTStringFormatter.getIntWithLeadingZeros(month, 2) + "-" + TSTStringFormatter.getIntWithLeadingZeros(day, 2);

    return val;
}
}

Я думал о двух разных решениях

  1. Я попытался преобразовать свой TSTLocalDate calenderDate в Date calenderDate, но похоже, что он не работает, поскольку методы классов Date устарели.

    @SuppressWarnings({ "deprecation"})
    public Date tstlocaldateToDate(TSTLocalDate tstlocaldate) throws ParseException {       
    
    Date date = new Date(0);
    
    date.setYear(tstlocaldate.year);
    date.setMonth(tstlocaldate.month);
    date.setDate(tstlocaldate.day);
    
    Log.info(date.getYear());
    return date;
    }
    
  2. Я попытался найти способ объявить собственный тип данных для PreparedStatement, чтобы я мог передать calenderDate как объект TSTLocalDate в PreparedStatement, например st.setTSTLocalDate(id++, hol.getCalenderDate());, но, к сожалению, я не нашел способа, как это сделать.

Я бы предпочел второе решение, но я открыт и для других решений.

Вам действительно нужен класс TSTLocalDate? Можете ли вы вместо этого использовать что-то вроде java.sql.Timestamp?

JonK 05.06.2019 14:24

@JonK - Или LocalDate.

T.J. Crowder 05.06.2019 14:25

Зачем вы создали кастомный тип TSTLocalDate, когда есть java.time.LocalDate и возможность сделать Date date = Date.valueOf(LocalDate localDate);? См. ответ, данный @T.J.Crowder

deHaar 05.06.2019 14:25

К сожалению, мне приходится использовать класс TSTLocalDate, потому что это требование, которое я получил с этой задачей.

Mad Scientist 05.06.2019 14:27

Чтобы было ясно, мой ответ показывает, как использовать LocalDate для перехода от TSTLocalDate к java.sql.Date для PreparedStatement, он не рекомендует использовать LocalDateвместо для TSTLocalDate (хотя, конечно, если бы это был вариант...).

T.J. Crowder 05.06.2019 14:40

@T.J.Crowder, ваше решение очень хорошо подходит для этого.

Mad Scientist 05.06.2019 14:46
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
316
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

...but it seems like it does not work well since the Date classes methods are deprecated.

Если вы посмотрите на сообщение об устаревании JavaDoc, это говорит вам, что делать:

Deprecated.

As of JDK version 1.1, replaced by Calendar.set(Calendar.YEAR, year + 1900).

(мой акцент на втором абзаце)

Таким образом, старый способ будет заключаться в следующем:

  • Получите Calendar, используя getInstance или одну из его перегрузок.
  • Используйте методы Calendar, чтобы установить правильную дату.
  • Используйте причудливое имя getTime, чтобы получить экземпляр Date для этой даты.
  • Используйте конструктор java.sql.Date, передав DategetTime().
  • Используйте это со своим PreparedStatement.

Тем не менее, с современным JDK вы, вероятно, захотите пройти через классы java.time, возможно, LocalDate, чтобы выполнить преобразование, поскольку это немного проще. Тогда вы должны использовать java.sql.Date.valueOf(LocalDate):

ps.setDate(java.sql.Date.valueOf(LocalDate.of(
    tstlocaldate.year,
    tstlocaldate.month,
    tstlocaldate.dayOfMonth
));

Другие вопросы по теме