560 votes

java.sql.Date vs java.util.Date

vs : quand utiliser qui et pourquoi ?

629voto

Esko Points 15578

Félicitations, vous avez touché mon préféré bête noire avec JDBC: Date de la gestion de classe.

Fondamentalement, les bases de données prennent généralement en charge d'au moins trois formes de datetime champs qui sont la date, l'heure et la date. Chacun d'eux a un correspondant de la classe JDBC et chacun d'eux s'étendre java.util.Date. Rapide de la sémantique de chacun de ces trois sont les suivantes:

  • java.sql.Date correspond à SQL DATE qui signifie qu'il stocke les années, les mois et les jours tandis que les heures, les minutes, les secondes et les millisecondes sont ignorés. En outre, sql.Date n'est pas liée à des fuseaux horaires.
  • java.sql.Time correspond à SQL TEMPS et comme cela devrait être évident, ne contient que les informations sur les heures, les minutes, les secondes et les millisecondes.
  • java.sql.Timestamp correspond à SQL TIMESTAMP qui est la date exacte de l'ordre de la nanoseconde (notez que util.Date prend uniquement en charge les millisecondes!) avec personnalisable de précision.

Un des plus fréquents bugs dans les pilotes JDBC dans le cadre de ces trois types est que les types ne sont pas traitées correctement. Cela signifie qu' sql.Date est le fuseau horaire spécifique, sql.Time contient de l'année en cours, le mois et le jour, et cetera, et cetera.

Enfin: Lequel utiliser?

Dépend du type SQL du champ, vraiment. PreparedStatement a-setters pour tous les trois valeurs, #setDate() étant l'un pour l' sql.Date, #setTime() pour sql.Time et #setTimestamp() pour sql.Timestamp.

Notez que si vous utilisez ps.setObject(fieldIndex, utilDateObject); vous pouvez effectivement donner un normal util.Date pour la plupart des pilotes JDBC qui seront heureux de vous dévorer, comme si c'était du type correct, mais lorsque vous demandez les données par la suite, vous remarquerez peut-être que vous êtes réellement en manque des trucs.

Je suis vraiment en disant qu'aucun des Dates doit être utilisé à tout.

Ce que je suis en train de dire que sauver les millisecondes/nanosecondes, la plaine de longs et de les convertir en ce que les objets que vous utilisez (obligatoire joda-time plug). Un hacky manière qui peut être fait est de stocker la date composant comme un long et composant comme un autre, par exemple en ce moment serait 20100221 et 154536123. Ces nombres magiques peuvent être utilisées dans des requêtes SQL et sera portable à partir de la base de données à l'autre et qui vous permettra d'éviter cette partie de JDBC/Java Date de l'API:s entièrement.

68voto

gustafc Points 13552

java.sql.Date - lorsque vous appelez les méthodes/constructeurs de bibliothèques qui l'utilisent (comme JDBC). Non pas le contraire. Vous ne voulez pas introduire des dépendances pour les bibliothèques de base de données pour les applications/modules qui ne sont pas explicitement traiter avec JDBC.

java.util.Date - lors de l'utilisation de bibliothèques qui l'utilisent. Sinon, aussi peu que possible, et ce pour plusieurs raisons:

  • C'est mutable, ce qui signifie que vous avez à faire une défensive copie de celui-ci chaque fois que vous passez à retourner ou à partir d'une méthode.

  • Il ne gère pas les dates très bien, ce qui renverse les gens aiment sincèrement, pensez à la date de la manipulation des classes.

  • Maintenant, parce que j.u.D ne pas le faire c'est le travail très bien, les affreux Calendar des classes ont été introduites. Ils sont aussi mutable, et terrible de travailler avec, et doit être évitée si vous n'avez pas le choix.

  • Il existe de meilleures alternatives, comme le Joda Time API (qui pourrait même faire ça en Java 7 et devenir la nouvelle date officielle de la manipulation de l'API - une recherche rapide dit qu'il ne va pas).

Si vous vous sentez que c'est trop d'introduire une nouvelle dépendance comme Joda, longs ne sont pas si mauvais que ça à utiliser pour les champs d'horodatage dans les objets, bien que j'ai moi-même généralement les envelopper dans j.u.D lors de leur passage autour de, pour la sécurité du type et de la documentation.

22voto

Paul Tomblin Points 83687

Le seul moment d’utiliser java.sql.Date est dans un PreparedStatement.setDate. Sinon, utilisez java.util.Date. C’est dire que ResultSet.getDate retourne un java.sql.Date mais il peut être assigné directement à un java.util.Date.

12voto

Israelm Points 145

J’ai eu le même problème, la meilleure façon que j’ai trouvé pour insérer la date actuelle dans une instruction préparée est celui-ci :

2voto

Kent Tong Points 21

La java.util.Date de classe en Java représente un moment particulier dans le temps (e,.g., 2013 Nov 25 16:30:45 vers le bas à quelques millisecondes), mais le type de données DATE dans la base de données représente une date (par exemple, 2013 Nov 25). Pour vous empêcher de vous fournir un java.util.Date objet de la DB par erreur, Java ne permet pas de définir un paramètre SQL en java.util.Date directement:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work

Mais elle permet tout de même de le faire par la force/l'intention (puis les heures et les minutes seront ignorés par le pilote de base de données). Cela se fait avec le java.sql.Classe Date:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work

Un java.sql.Date objet peut stocker un moment dans le temps (de sorte qu'il est facile à construire à partir de java.util.La Date) mais lève une exception si vous essayez de lui demander pour le nombre d'heures (à appliquer son concept d'être un jour le seul). Le pilote de base de données devrait reconnaître cette classe et il suffit d'utiliser 0 pour les heures. Essayez ceci:

public static void main(String[] args) {
  java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
  java.sql.Date d2 = new java.sql.Date(12345);
  System.out.println(d1.getHours());
  System.out.println(d2.getHours());
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X