Je dois trouver un moyen d'insérer un enregistrement avec un champ Java.util.Date dans une base de données et je suis bloqué.
Est-ce que quelqu'un sait comment je peux faire ça? À l'heure actuelle, j'ai quelque chose comme.
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());
Mais quand je lance quelque chose comme ça, j'obtiens l'erreur suivante: La syntaxe de la représentation sous forme de chaîne d'une valeur datetime est incorrecte.
Voici à quoi ressemble la déclaration 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')
Merci
Certes, PreparedStatement
améliorera votre code, mais pour répondre à votre question, vous devez indiquer au SGBD le format de votre représentation sous forme de chaîne de la Date. Dans Oracle (vous ne nommez pas votre fournisseur de base de données), une date de chaîne est convertie en Date
à l'aide de la fonction TO_DATE()
:
INSERT INTO TABLE_NAME(
date_column
)values(
TO_DATE('06/06/2006', 'mm/dd/yyyy')
)
Avant de répondre à votre question, je voudrais mentionner que vous devriez probablement envisager d’utiliser une sorte de solution ORM (par exemple, Hibernate), intégrée dans un niveau d’accès aux données. Ce que vous faites semble être très anti-OO. Certes, je ne sais pas à quoi ressemble le reste de votre code, mais en général, si vous commencez à vous voir utiliser de nombreuses classes d’utilitaires, vous adoptez probablement une approche trop structurelle.
Pour répondre à votre question, comme d'autres l'ont déjà mentionné, examinez Java.sql.PreparedStatement
et utilisez Java.sql.Date
ou Java.sql.Timestamp
. Quelque chose comme (pour utiliser votre code original autant que possible, vous voudrez probablement le changer encore plus):
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
Un autre avantage de cette approche est qu’elle échappe automatiquement à vos chaînes (par exemple, si vous insérez une personne portant le nom de famille "O'Brien", vous auriez des problèmes avec votre implémentation initiale).
Vous devez absolument utiliser un PreparedStatement
. ( Didacticiel )
De cette façon, vous pouvez invoquer:
pstmt.setDate( 1, aDate );
Le pilote JDBC gérera la gestion de la date et de l'heure en fonction de votre base de données.
En outre, un PreparedStatement arrête toute injection SQL _ tentatives de piratage - très important! ( humour )
Ça devrait ressembler à ça:
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 );
Et c'est tout, le pilote JDBC créera la syntaxe SQL qui vous convient.
Lors de la récupération d'un objet Date, vous pouvez utiliser un SimpleDateFormat pour créer une représentation sous forme de chaîne de la valeur date-heure.
Voici un exemple de ligne rapide, mais recherchez StackOverflow pour many more.
String s = new SimpleDateFormat("dd/MM/yyyy").format( aDate );
La réponse de OscarRyz est correct et aurait dû être la réponse acceptée. Mais maintenant, cette réponse est obsolète.
Dans Java 8 et versions ultérieures, nous avons le nouveau package Java.time (inspiré de Joda-Time , défini par JSR 310 , avec tutoriel , étendu de ThreeTen-Extra projet).
Les anciennes classes Java.util.Date/.Calendar, SimpleDateFormat et Java.sql.Date sont un désordre déroutant. D'une part, j.u.Date a la date et l'heure du jour alors que j.s.Date est la date uniquement sans l'heure. Oh, sauf que j.s.Date seulement prétend ne pas avoir d’heure. En tant que sous-classe de j.u.Date, j.s.Date hérite de l'heure du jour mais ajuste automatiquement cette heure à minuit (00:00:00.000
). Déroutant? Oui. Un mauvais bidouillage, franchement.
Pour cette raison et bien d'autres encore, il convient d'éviter ces anciennes classes, qui ne sont utilisées qu'en dernier recours. Utilisez Java.time si possible, avec Joda-Time comme solution de secours.
LocalDate
Dans Java.time, la classe LocalDate
représente proprement une valeur de date uniquement, sans heure ni fuseau horaire. C’est ce dont nous avons besoin pour la solution de cette question.
Pour obtenir cet objet LocalDate, nous analysons la chaîne d'entrée. Mais plutôt que d'utiliser l'ancienne classe SimpleDateFormat
, Java.time fournit une nouvelle classe DateTimeFormatter
dans le package Java.time.format .
String input = "01/01/2009" ;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ;
LocalDate localDate = LocalDate.parse( input, formatter ) ;
Les pilotes JDBC compatibles avec JDBC 4.2 ou version ultérieure peuvent utiliser les types Java.time directement via les méthodes PreparedStatement::setObject
et 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.*.
Mais jusqu'à ce que vous ayez un pilote JDBC mis à jour, utilisez la classe Java.sql.Date . Heureusement, Java 8 a doté cette ancienne classe Java.sql.Date
d'une nouvelle méthode pratique de conversion statique, valueOf( LocalDate )
.
Dans l'exemple de code de Réponse de la fratrie par OscarRyz , remplacez la ligne "sqlDate =" par celle-ci:
Java.sql.Date sqlDate = Java.sql.Date.valueOf( localDate ) ;
si vous utilisez mysql .. vous pouvez enregistrer la date comme "2009-12-31" par exemple.
mettre à jour le jeu de personnes birthday_date = '2009-12-31'
mais je préfère utiliser jdbc bien que vous deviez créer Java.sql.Date ...
* La date est un peu diabolique dans ce monde ... :)
Vous devez utiliser Java.sql.Timestamp au lieu de Java.util.Date . De plus, l’utilisation de PreparedStatement vous évitera de vous inquiéter du formatage.
pst.setDate(6, new Java.sql.Date(txtDate.getDate().getTime()));
c'est le code que j'ai utilisé pour sauvegarder la date dans la base de données en utilisant jdbc fonctionne bien pour moi
pst
est une variable pour l'état préparétxtdate
est le nom de JDateChooser vous pouvez utiliser ce code date et heure heure est 24 h
INSERT INTO TABLE_NAME(
date_column
)values(
TO_DATE('2016-10-05 10:53:56', 'SYYYY-MM-DD HH24:MI:SS')
)