Ekstra

Ajan käsittely tietokannassa

Tietoon liittyy usein aikamääreitä. Esimerkiksi kirjalla on julkaisupäivämäärä, henkilöllä on syntymäpäivä, elokuvalla on näytösaika jne. Tarkastellaan seuraavaksi ajan käsittelyyn tarkoitettuja luokkia.

Luokkaa LocalDate käytetään vuoden, kuukauden ja päivämäärän tallentamiseen. Luokka LocalDateTime mahdollistaa taas vuoden, kuukauden ja päivämäärän lisäksi tuntien, minuuttien, sekuntien ja millisekuntien tallentamisen.

Yksinkertaisimmillaan luokat toimivat seuraavalla tavalla.

import java.time.LocalDate;
import java.time.LocalDateTime;

public class TimeTest {

    public static void main(String[] args) {
        System.out.println(LocalDate.now());
        System.out.println(LocalDateTime.now());
    }
}
Esimerkkitulostus

2020-02-11 2020-02-11T09:49:08.392536

Luokkia voi käyttää suoraan entiteettien oliomuuttujina. Alla on määritelty henkilöä kuvaava entiteetti. Henkilöllä on pääavain (id), nimi, ja syntymäpäivä.

import java.time.LocalDate;
import javax.persistence.Entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.jpa.domain.AbstractPersistable;

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person extends AbstractPersistable<Long> {

    private String name;
    private LocalDate birthday;

}

Sovelluksen käynnistyessä tietokantaan luodaan — kun käytössä on H2-tietokannanhallintajärjestelmä — seuraavanlainen tietokantataulu. Syntymäpäivää kuvaava sarake birthday luodaan date-tyyppisenä sarakkeena.

CREATE TABLE PERSON (
    id bigint not null,
    birthday date,
    name varchar(255),
    primary key (id)
)

Aikamääreiden lähettäminen onnistuu myös sovelluksesta palvelimelle. Tällöin kontrollerin metodissa tulee määritellä menetelmä aikaa kuvaavan merkkijonon muuntamiseen aikamääreeksi. Muunto merkkijonosta aikamääreeksi onnistuu DateTimeFormat-annotaation avulla. Annotaatiolle annetaan parametrina tiedon muoto, alla on käytetty muotoa DateTimeFormat.ISO.DATE.

@PostMapping("/persons")
public String create(@RequestParam String name,
      @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate birthday) {
    // toiminnallisuus
}

Edellä oleva muoto DateTimeFormat.ISO.DATE olettaa, että päivämäärä lähetetään palvelimelle muodossa yyyy-MM-dd. Tässä on ensin vuosi (4 numeroa), sitten viiva, sitten kuukausi (2 numeroa), sitten viiva, ja lopulta päivä (2 numeroa). Tämä muoto liittyy RFC3339-spesifikaatioon, joka määrittelee muodon, mitä päivämäärissä pitäisi käyttää kun tietoa lähetetään palvelimelle. Spesifikaation takia voimme olettaa (tai toivoa), että esimerkiksi HTML:n date-elementtiin syötettävä päivämäärä lähetetään palvelimelle em. muodossa.

Vastaavasti lomake, jolla henkilö voidaan luoda, on melko suoraviivainen. Lomake-elementin tyyppi date toimii joissakin selaimissa — jonkinlainen ohjeistus käyttäjälle on kuitenkin hyvä olla olemassa.

<form th:action="@{/persons}" method="POST">
    <input name="name" type="text"/><br/>
    <input name="birthday" type="date"/><br/>
    <input type="submit"/>
</form>

Mikäli päivämääriä haluaa näyttää osana sovellusta, kannattaa tutustua Thymeleafin aikojen muokkaamista helpottavaan #temporals-apuvälineeseen. Tästä lisää mm. Baeldungin päivämäärien käsittelyyn liittyvässä oppassa.

Pääsit aliluvun loppuun! Jatka tästä seuraavaan osaan: