477 votos

java.util.Date vs adiciones

java.util.Date¿vs java.sql.Date : Cuándo usar el cual y por qué?

563voto

Esko Puntos 15578

Felicidades, has llegado a mi mascota favorita pone de mal humor con JDBC: Fecha de la clase de manejo.

Básicamente las bases de datos suelen apoyar al menos tres formas de campos de fecha y hora que se la fecha, la hora y la fecha y hora. Cada uno de estos tienen una clase correspondiente en JDBC y cada uno de ellos se extienden java.util.Date. Rápido semántica de cada una de estas tres son las siguientes:

  • java.sql.Date corresponde a SQL FECHA que significa que las tiendas de años, meses y días , mientras que de la hora, minuto, segundo y milisegundo son ignorados. Además, sql.Date no está ligado a las zonas horarias.
  • java.sql.Time corresponde a SQL TIEMPO y como debería ser obvio, sólo contiene información sobre la hora, minutos, segundos y milisegundos.
  • java.sql.Timestamp corresponde a SQL marca de tiempo que es la fecha exacta para el nanosegundo (tenga en cuenta que util.Date sólo admite milisegundos!) personalizable de precisión.

Uno de los más comunes errores en los controladores JDBC en relación a estos tres tipos es que los tipos se manejan de forma incorrecta. Esto significa que sql.Date está en la zona horaria específica, sql.Time contiene corriente año, mes y día, et cetera, et cetera.

Por último: ¿cuál usar?

Depende del tipo SQL de el campo, la verdad. PreparedStatement ha incubadoras para los tres valores, #setDate() siendo el uno para sql.Date, #setTime() para sql.Time y #setTimestamp() para sql.Timestamp.

Tenga en cuenta que si utilizas ps.setObject(fieldIndex, utilDateObject); puede dar realmente una normal util.Date para la mayoría de los controladores JDBC que estará feliz de devorar como si fuera del tipo correcto, pero cuando usted solicita los datos después de esto, usted puede notar que en realidad estás faltan cosas.

Realmente estoy diciendo que ninguna de las Fechas debe ser utilizado en su totalidad.

Lo que yo estoy diciendo que guardar el milisegundos/nanosegundos en formato anhela y convertirlos en objetos de cualquier cosa que se esté utilizando (obligatorio joda tiempo de enchufe). Un hacky manera que se puede hacer es almacenar el componente de fecha como una larga y componente de tiempo como de otra, por ejemplo ahora mismo sería 20100221 y 154536123. Estos números de magia puede ser utilizado en consultas de SQL y serán portátiles de la base de datos a otra y te permitirá evitar esta parte de JDBC/Java Fecha de la API:s completamente.

57voto

gustafc Puntos 13552

java.sql.Date - al llamar a los métodos/constructores de las bibliotecas que lo utilizan (como JDBC). No de otro modo. No quiero presentar a las dependencias en la base de datos de las bibliotecas de aplicaciones/módulos que explícitamente no lidiar con JDBC.

java.util.Date - cuando el uso de las bibliotecas que usan. De lo contrario, como poco como sea posible, por varias razones:

  • Es mutable, lo que significa que usted tiene que hacer una defensa copia de la misma cada vez de pasar o de retorno de un método.

  • No manejar fechas muy bien, que al revés de la gente como el tuyo realmente, creo que la fecha de manejo de clase.

  • Ahora, porque j.u.D no hacer su trabajo muy bien, la horrorosa Calendar clases fueron introducidas. También son mutables, y terrible para trabajar, y deben ser evitados si usted no tiene ninguna opción.

  • Hay alternativas mejores, como la Joda de la API de Tiempo (que puede incluso hacer en Java 7 y convertirse en la nueva fecha oficial de manejo de API - una búsqueda rápida le dice que no).

Si usted siente que es una exageración para introducir una nueva dependencia como Joda, longs no son nada malos para uso de campos de fecha en objetos, aunque yo generalmente se envuelven en j.u.D cuando se les pasa de todo, para el tipo de seguridad y documentación.

19voto

Paul Tomblin Puntos 83687

El único momento para utilizar adiciones está en un PreparedStatement.setDate. De lo contrario, utilice java.util.Date. Dice que ResultSet.getDate devuelve un adiciones pero puede asignarse directamente a un java.util.Date.

10voto

Israelm Puntos 145

Tuve el mismo problema, la forma más fácil que he encontrado para insertar la fecha actual en una declaración preparada es ésta:

preparedStatement.setDate(1, new java.sql.Date(new java.util.Date().getTime()));

2voto

Kent Tong Puntos 21

El java.util.Date clase en Java que representa un momento concreto en el tiempo (e .g., 2013 Noviembre 25 16:30:45 hacia abajo para milisegundos), pero el tipo de datos de FECHA en el DB representa una fecha (e.g., 2013 Noviembre 25). Para evitar que proporciona un java.util.Date objeto a la base de datos por error, Java no permite establecer un parámetro SQL para java.util.Date directamente:

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

Pero todavía permite que hacerlo por la fuerza/de la intención (luego de horas y minutos serán ignoradas por la base de datos del controlador). Esto se hace con el java.sql.Date clase:

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

Un java.sql.Date objeto puede almacenar un momento en el tiempo (de modo que es fácil construir a partir de un java.util.Date), pero producirá una excepción si se intenta preguntar por el horario (para imponer su concepto de ser una fecha única). La base de datos del controlador se espera que reconocer esta clase y sólo use 0 para las horas. Intente esto:

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());
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X