Вопрос по java, date, sql – Java Date - вставить в базу данных

13

Мне нужно найти способ вставить запись с полем java.util.Date в базу данных, и я застрял.

Кто-нибудь знает, как я могу это сделать? Прямо сейчас у меня есть что-то вроде.

        java.util.Date myDate = new java.util.Date("01/01/2009");

        sb.append("INSERT INTO USERS");
        sb.append("(USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE) ");
        sb.append("VALUES ( ");
        sb.append("  '" + userId + "'");
        sb.append(", '" + myUser.GetFirstname() + "' ");
        sb.append(", '" + myUser.GetLastname() + "' ");
        sb.append(", '" + myUser.GetSex() + "' ");
        sb.append(", '" + myDate  + "'");
        sb.append(")");

        Util.executeUpdate(sb.toString());

Но когда я запускаю что-то вроде этого, я получаю ошибку:     Синтаксис строкового представления значения даты и времени неверен.

Вот как выглядит выражение sql:

INSERT INTO USERS (USER_ID
    , FIRST_NAME
    , LAST_NAME
    , SEX
    , CRDATE) 
VALUES (   
    'user'
    , 'FirstTest' 
    , 'LastTest' 
    , 'M'
    , 'Thu Jan 01 00:00:00 CST 2009')

Спасибо

Ваш Ответ

10   ответов
2

Ответ от OscarRyz правильно, и должен был быть принят ответ. Но теперь этот ответ устарел.

java.time

В Java 8 и позже у нас есть новыйпакет java.time (вдохновленныйJoda времени, определяетсяJSR 310, сруководство, продленThreeTen-Extra проект).

Avoid Old Date-Time Classes

Старые классы java.util.Date/.Calendar, SimpleDateFormat и java.sql.Date вызывают путаницу. Во-первых, у j.u.Date есть датаand время дня, в то время как j.s.Date только датаwithout время-день. Ох, за исключением того, что j.s.Date толькоpretends не иметь времени суток. Как подкласс j.u.Date, j.s.Date наследует время суток, но автоматически корректирует это время дня до полуночи (00:00:00.000). Смешение? Да. Откровенно говоря, плохой взлом.

По этой и многим другим причинам этих старых классов следует избегать, используя только последнее средство. Используйте java.time, где это возможно, сJoda времени как запасной вариант.

LocalDate

В java.time,LocalDate класс чисто представляет значение только для даты без какого-либо времени суток или часового пояса. Это то, что нам нужно для решения этого вопроса.

Чтобы получить этот объект LocalDate, мы анализируем входную строку. Но вместо того, чтобы использовать старыйSimpleDateFormat класс, java.time предоставляет новыйDateTimeFormatter класс впакет java.time.format.

String input = "01/01/2009" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ;
LocalDate localDate = LocalDate.parse( input, formatter ) ;

Драйверы JDBC, соответствующиеJDBC 4.2 или позже можете использовать типы java.time напрямую черезPreparedStatement::setObject а такжеResultSet::getObject методы.

PreparedStatement pstmt = connection.prepareStatement(
    "INSERT INTO USERS ( USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE ) " +
    " VALUES (?, ?, ?, ?, ? )");

pstmt.setString( 1, userId );
pstmt.setString( 3, myUser.getLastName() ); 
pstmt.setString( 2, myUser.getFirstName() ); // please use "getFir…" instead of "GetFir…", per Java conventions.
pstmt.setString( 4, myUser.getSex() );
pstmt.setObject( 5, localDate ) ;  // Pass java.time object directly, without any need for java.sql.*. 

Но пока у вас не появится такой обновленный драйвер JDBC, откатитесь на использованиеjava.sql.Date учебный класс. К счастью, этот старыйjava.sql.Date Java подарил классу новый удобный статический метод преобразования,valueOf( LocalDate ).

В примере кодаОтвет родного брата от OscarRyzзамените его & quot; sqlDate = & quot; строка с этим:

java.sql.Date sqlDate = java.sql.Date.valueOf( localDate ) ;
1

2009-12-31 & quot; например.

обновить персону set birthday_date = "2009-12-31"

но я предпочитаю использовать jdbc, хотя вы должны создать java.sql.Date ...

* Дата - это зло в этом мире ... :)

Вы намного легче в .NET LOL zSynopsis
8
PreparedStatement

PreparedStatement. (Руководство)

Таким образом, вы можете вызвать:

pstmt.setDate( 1, aDate );

Драйвер JDBC сделает обработку даты и времени подходящей для вашей конкретной базы данных.

Кроме того, PreparedStatement останавливает любойSQL-инъекция попытки взлома & # x2013;very important! (юмор)

Это должно выглядеть так:

SimpleDateFormat format = new SimpleDateFormat( "MM/dd/yyyy" );  // United States style of format.
java.util.Date myDate = format.parse( "10/10/2009" );  // Notice the ".util." of package name.

PreparedStatement pstmt = connection.prepareStatement(
"INSERT INTO USERS ( USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE ) " +
" values (?, ?, ?, ?, ? )");

pstmt.setString( 1, userId );
pstmt.setString( 3, myUser.getLastName() ); 
pstmt.setString( 2, myUser.getFirstName() ); // please use "getFir…" instead of "GetFir…", per Java conventions.
pstmt.setString( 4, myUser.getSex() );
java.sql.Date sqlDate = new java.sql.Date( myDate.getTime() ); // Notice the ".sql." (not "util") in package name.
pstmt.setDate( 5, sqlDate ); 

И это все, драйвер JDBC создаст правильный синтаксис SQL для вас.

Retrieving

При извлечении объекта Date вы можете использоватьSimpleDateFormat создать отформатированное строковое представление значения даты и времени.

Вот одна строка быстрого примера, но поиск StackOverflow дляmany Больше.

String s = new SimpleDateFormat("dd/MM/yyyy").format( aDate ); 
методsetDate принимает java.sql.Date, а не java.util.Date.
Это должен быть принятый ответ. ИспользуяPreparedStatement устраняет проблему взлома SQL-инъекций, поэтому его следует использовать почти всегда. Использованиеjava.sql.Date Лучше практиковаться, чем струны.
Я сделал несколько значительных изменений в этом ответе, таких как замена устаревшего кода. Кроме того, пользователи Java 8 и более поздних версий должны читать [мой собственный ответ] как дополнение к этому ответу (используя новый пакет java.time).
@ CD1: спасибо. Это исправлено сейчас. @zSisop: java.sql.Date и java.sql.TimeStamps - это разные объекты, если вы хотите сохранить дату и час, вы должны использовать позже.
6

PreparedStatement сделает ваш код лучше, но чтобы ответить на ваш вопрос, вам нужно указать СУБД формат вашего строкового представления даты. В Oracle (вы не называете своего поставщика базы данных) строковая дата преобразуется вDate с использованиемTO_DATE() функция:

INSERT INTO TABLE_NAME(
  date_column
)values(
  TO_DATE('06/06/2006', 'mm/dd/yyyy')
)
@zSyspo: Да String s = новый SimpleDateFormat (& quot; dd / MM / yyyy & quot;). format (aDate); Сделаю
Большое спасибо, Брайан! Вы были очень полезны. : D zSynopsis
Ну что ж, код не форматируется в комментариях :-).
Знаете ли вы, могу ли я в любом случае получить java.util.Date для вывода даты в формате «01.01.2009»? zSynopsis
Внимание: SimpleDateFormat не является потокобезопасным. Сделайте свою собственную простую обертку, безопасную для потоков. открытый класс ThreadSafeSimpleDateFormat {private DateFormat df; public ThreadSafeSimpleDateFormat (формат строки) {this.df = new SimpleDateFormat (формат); } открытый синхронизированный формат String (Дата дата) {return df.format (date); } открытый синхронизированный анализ даты (строка String) создает исключение ParseException {return df.parse (string); }}
0
pst.setDate(6, new java.sql.Date(txtDate.getDate().getTime()));

который я использовал для сохранения даты в базе данных с помощью JDBC хорошо работает для меня

pst is a variable for preparedstatement txtdate is the name for the JDateChooser
0

у них есть методы для правильной установки параметров для каждого нативного типа Java.

Посмотрите на API дляSETDATE иПримеры

0

Также использование PreparedStatement избавит вас от беспокойства о форматировании.

0

INSERT INTO TABLE_NAME(
  date_column
)values(
  TO_DATE('2016-10-05 10:53:56', 'SYYYY-MM-DD HH24:MI:SS')
)
-1
VALUES ('"+user+"' , '"+FirstTest+"'  , '"+LastTest+"'..............etc)

13

я хотел бы упомянуть, что вам, вероятно, стоит подумать об использовании какого-либо решения ORM (например, Hibernate), скрытого за уровнем доступа к данным. То, что вы делаете, похоже, очень противозаконно. По общему признанию, я не знаю, как выглядит остальная часть вашего кода, но, как правило, если вы начинаете видеть себя использующим много классов Utility, вы, вероятно, придерживаетесь слишком структурного подхода.

Чтобы ответить на ваш вопрос, как уже упоминали другие, посмотрите вjava.sql.PreparedStatementи использоватьjava.sql.Date или жеjava.sql.Timestamp, Что-то вроде (чтобы максимально использовать исходный код, вы, вероятно, захотите изменить его еще больше):

java.util.Date myDate = new java.util.Date("10/10/2009");
java.sql.Date sqlDate = new java.sql.Date(myDate.getTime());

sb.append("INSERT INTO USERS");
sb.append("(USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE) ");
sb.append("VALUES ( ");
sb.append("?, ?, ?, ?, ?");
sb.append(")");

Connection conn = ...;// you'll have to get this connection somehow
PreparedStatement stmt = conn.prepareStatement(sb.toString());
stmt.setString(1, userId);
stmt.setString(2, myUser.GetFirstName());
stmt.setString(3, myUser.GetLastName());
stmt.setString(4, myUser.GetSex());
stmt.setDate(5, sqlDate);

stmt.executeUpdate(); // optionally check the return value of this call

Одним дополнительным преимуществом этого подхода является то, что он автоматически экранирует ваши строки (например, если вы вставите кого-то с фамилией «O» Brien », у вас возникнут проблемы с вашей первоначальной реализацией).

Почему это считается анти ой? Вы можете объяснить. Я новичок в этом, так что это было бы полезно. Спасибо! zSynopsis
@Jack Leow: Это не анти-OO, просто у него может быть другой уровень абстракции OO. Мартин Фаулер блестяще объясняет это в своей книге PEAA «Шаблоны логики домена»:martinfowler.com/eaaCatalog в то время как некоторые системы могут найти полезным использовать TransactionScript (в значительной степени то, что использует zSysop) для других, может быть слишком сложно или даже невозможно поддерживать его и использовать & quot; модель домена & quot; вместо. Для небольших приложений & quot; Модель домена & quot; может быть излишним. Это очень интересная тема.

Похожие вопросы