Rozliczenie pojazdu aplikacja

Tworzę projekt rozliczenie pojazdu aplikacja, który ma za zadanie kontrolować zużycie paliwa w moim aucie prywatnym. Projekt nie będzie zawierał elementów komercyjnych. Jeżeli potrzebujesz dodatkowych funkcjonalności, przeczytaj ten cykl artykułów i rozbuduje swoją wersję o potrzebne elementy.

Powiązane artykuły

  1. Tworzenie bazy danych
  2. Zapis danych do bazy
  3. Aktualizacja danych w bazie
  4. Pobieranie danych
  5. Aplikacja REST, MyBatis, MySQL.

Analiza – rozliczenie pojazdu

Role użytkowników.

  • Administrator – jest to osoba odpowiedzialna za dodawanie nowych użytkowników.
  • Użytkownik – jest to osoba używająca systemu do rozliczenia przejazdów i tankowań swojego pojazdu. Po wprowadzeniu danych otrzymuje statystyki.

Scenariusze

  • Użytkownik – Za dodawanie i usuwanie użytkowników jest odpowiedzialny administrator systemu.
  • Pojazd – Każdy użytkownika może dodawać i edytować pojazdy, które sam posiada. Nie ma podglądu do pojazdów innych użytkowników.
  • Przejazd – Dla każdego pojazdu będą rejestrowane przejazdy i na podstawie zgromadzonych danych będzie możliwość określenia kosztów każdego przejazdu.
  • Tankowanie – Użytkownik dodaje oraz edytuje tankowania dla pojazdu, które sam stworzył w systemie.
  • Rozliczenia – Na podstawie zgromadzonych danych użytkownik będzie w stanie określić wszystkie parametry dotyczące przejazdu. Na początkowym etapie stworzymy ręczne dodawanie danych. Jednak synchnizator jest bardziej eleganckim rozwiązaniem i spróbujemy je zrealizować.

Architektura rozwiązania – rozliczenie pojazdu

Struktura bazy danych – rozliczenie pojazdu

Baza danych projektu rozliczenie pojazdy wraz z tabelami i relacjami

Repozytorium kodu źródłowego

Kod źródłowy każdego rozwiązania umieszczam na GitHub, gdzie każda zainteresowana osoba może go pobrać.

Zapraszam do kolejnych artykułów rozliczenie pojazdu aplikacja.

Zaszufladkowano do kategorii Projekty | Otagowano , | Możliwość komentowania Rozliczenie pojazdu aplikacja została wyłączona

Rozliczenie pojazdu baza danych

Pierwszym elementem, którym się zajmiemy to rozliczenie pojazdu bazy danych. Podczas budowy naszej aplikacji, pierwszym krokiem jest zaprojektowanie baza danych i utworzenie tabele. Na początku musimy określić, co tak naprawdę jest nam potrzebne i jakie dane będziemy przechowywać w bazie danych.

Możesz zadać pytanie, czy warto zajmować się budową tabel. Skoro można rozpocząć od budowy klas JPA. Jednak ja uważam, że warto. W ostatecznym rozrachunku JPA generuje tabele za nas na podstawie klas. Dlatego po zaprojektowaniu klas i uruchomieniu aplikacji. Możemy wejść do bazy i sprawdzić, czy na pewno osiągnęliśmy to, co JPA wygenerowało. Łatwiej wtedy poprawić klasy lub tabele. Problem pojawi się później, gdy aplikacja będzie miała jakieś dane.

Jeżeli zaczynasz swoją przygodę i nie rozumiesz baz danych. Zapraszam do przeczytania artykułu Jak zrozumieć bazę danych.

Rozliczenie pojazdu baza danych – utworzenie bazy

Zajmiemy się stworzenie bazy danych w MySQL, w której będziemy tworzyć nasze tabele. Sposób instalacji dla każdego systemu operacyjnego znacząco się różni. Dlatego należy w Google wpisać taką teks: 'MySQL install’ i nazwę swojego operacyjnego. Sam nie używam systemu Windows, dlatego zapraszam do instalacji do stron, które dobrze to opisują. Pokaże natomiast jak utworzyć bazę danych już po instalacji MySQL. Jeżeli jesteś gotowy, wykonuj następujące polecenia:

# mysql -u root -p

Gdy udało się nam zalogować, możemy utworzyć bazę danych.

create database transport DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

Po utworzeniu bazy danych należy utworzyć również użytkownika. Można tego nie robić i ustawić sobie login i hasło root, ale wtedy w kodzie mamy dane uwierzytelniające root do bazy danych. Niepowołana osoba może zrobić wszystko z naszą bazą danych. Nie jest to tak ważne, gdy tworzymy bazę danych na własnym komputerze czy laptopie, ale uczmy się bezpiecznych praktyk już na tym etapie nauki. Bezpieczeństwa nigdy za wiele, a to są tylko dwie linijki kodu, które wykonujemy teraz.

create user transport identified by 'transport';


GRANT ALL PRIVILEGES ON transport.* TO transport WITH GRANT OPTION;

W pierwszej linijce tworzymy użytkownika. W drugiej powiążemy użytkownika z bazą danych. Takie rozwiązanie zabezpiecza nas przed przejęciem naszej bazy danych, ponieważ jeżeli nawet ktoś niepowołany będzie miał dostęp do kodu i wpisze login i hasło będzie w stanie przejąć kontrole tylko nad jedną bazą, a nie nad całym systemem baz danych. Można również ograniczyć uprawnienia do tworzenia i usuwania tabel. Dzięki temu będziemy trochę bezpieczniejsi.

Rozliczenie pojazdu baza danych – tabele

Pierwszą tabelą, jaką się zajmę to tabela Person (osoba). Zakładam, że osoba zarejestrowana w systemie ma dostęp tylko do swoich danych. Wykorzystam tę tabelę do zarządzania pojazdami, przejazdami i tankowaniami oraz do logowania użytkownika.

Tabela Person (osoba)

Jednak tabela Person w obecnej chwili będzie bardzo ograniczona. Nie zamierzam na samym początku tworzyć od razu rozbudowanej tabeli Person. Teraz stworzymy bardzo prostą tabele Person, która nam pozwoli zbudować projekt. Gdy przyjdzie czas na budowę systemu logowania. Wtedy rozbudujemy naszą tabele Person o potrzebne elementy niezbędne do prawidłowego działania uwierzytelniania.

CREATE TABLE `Person` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `firstName` varchar(20) NOT NULL,
  `lastName` varchar(20) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

O co tak naprawdę chodzi w tym zapisie. Pierwsza linij to zapis informujący MySQL, że chcemy stworzyć tabele w bazie danych. W drugiej linijce tworzymy identyfikator Id. W tym miejscu przechowujemy identyfikator rekordu(numer wiersza) w tabeli, jest to nam potrzebne do relacji, między tabelami. AUTO_INCREMENT informuje, że chcemy tworzyć ten identyfikator automatycznie, a PRIMARY KEY informuje, że jest to klucz główny. Wytłumaczę to na późniejszym etapie tego artykułu.

Kolejne dwie linijki to firstName(Imię), lastName(Nazwisko). Varchar oznacza, że mamy do czynienia z polem tekstowym. Dwadzieścia w nawiasach oznacza, że wielkość tego pola to dwadzieścia znaków. Kolejny zapis to NOT NULL, który mówi MySQL, że nie przewidujemy, aby dane pole miało wartość null. Co to oznacza, mówi MySQL, że musimy za każdym razem wypełnić to pole podczas wstawiania danych.

Ostatnia linijka zawiera dane informujące MySQL o konfiguracji naszej tabeli. Pierwszy InnoDB to typ MySQL. Drugi to numer, od jakiego ma zostać odliczany identyfikator. Ostatni zapis informuje MySQL, że chcemy używać kodowania znaków utf8

Tabela Vehicle (pojazd)

W tej tabeli będziemy przechowywać dane dotyczące pojazdu. Projekt, który tworze jest uproszczony. Dlatego, że takie mam założenia. Jeżeli stworzysz projekt, który będziesz używać w firmie, musisz rozbudować tę tabelę o potrzebne kolumny. Ja w tym projekcie upraszczam tę tabelę, gdyż projekt będę używać do rozliczania prywatnego samochodu i gromadzenie rozbudowanych danych nie jest mi potrzebne.

CREATE TABLE `Vehicle` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `idPerson` bigint(20) NOT NULL,
  `createDate` datetime NOT NULL,
  `registrationNumber` varchar(100) NOT NULL,
  `mark` varchar(100) NOT NULL,
  KEY `Vehicle_idPerson_index` (`idPerson`),
  CONSTRAINT `Vehicle_Person_id_fk` FOREIGN KEY (`idPerson`) REFERENCES `Person` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

Większość elementów spotkaliśmy już w tabeli osoba, ale mamy kilka nowych, więc przyjrzyjmy się im.

Pierwszy element, którego nie było wcześniej, jest createDate. Jest to kolumna, która przechowuje po prostu datę i czas, w naszym przypadku jest to data i czas utworzenia wpisu.

Drugi element dotyczy zapisu IdPerson oraz CONSTRAINT. Jest to powiązanie kolumny idPerson z tabelą Person. Dzięki temu wiemy, który pojazd należy do jakiej osoby. Jest to relacja jeden do wielu, gdzie tabela Person występuje jako jeden a tabela Vehicle jako wiele.

Dodatkowym elementem, który nie występował w tabeli Person to linijka KEY. Ten zapis tworzy index dla danej kolumny. Pozwala to szybciej przeszukiwać kolumnę, dzięki temu przyśpieszamy wykonanie zapytań.

Tabela Ride (przejazd)

To jest tabela zawierająca wszystkie przejazdy. Dzięki tej tabeli możemy określić, gdzie jechaliśmy, ile przejechaliśmy kilometrów, ile zużyliśmy paliwa oraz jaka norma zużycia paliwa jest dla każdego przejazdu.

CREATE TABLE `Ride` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `idVehicle` bigint(20) NOT NULL,
  `createDate` datetime NOT NULL,
  `rideDate` datetime NOT NULL,
  `counterBefore` int(11) NOT NULL,
  `counterAfter` int(11) NOT NULL,
  `km` int(11) NOT NULL,
  `whence` varchar(100) NOT NULL,
  `where` varchar(100) NOT NULL,
  `rideKind` varchar(100) NOT NULL,
  `fuelCondition` double NOT NULL,
  `fuelAdd` double NOT NULL,
  `fuelAfter` double NOT NULL,
  `fuelConsumed` double NOT NULL,
  `fuelNorm` double NOT NULL,
  KEY `Ride_idVehicle_index` (`idVehicle`),
  CONSTRAINT `Ride_Vecicle_id_fk` FOREIGN KEY (`idVehicle`) REFERENCES `Vehicle` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

Jak widać, ta tabela ma powiązanie jedynie z tabelą Vehicle (pojazd), dzięki temu wiemy który pojazd jest powiązany z danym przejazdem.

Tabela Refuel (tankowanie)

Refuel to tabela zawierająca wszystkie tankowania pojazdów. Dzięki użyciu tej tabeli ułatwimy rozliczenia każdego przejazdu.

CREATE TABLE `Refuel` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `idVehicle` bigint(20) NOT NULL,
  `idRide` bigint(20) NOT NULL,
  `createDate` datetime NOT NULL,
  `refuelDate` datetime NOT NULL,
  `name` varchar(100) NOT NULL,
  `counterBefore` int(11) NOT NULL,
  `counterAfter` int(11) NOT NULL,
  `km` int(11) NOT NULL,
  `refuel` double NOT NULL,
  `price` double NOT NULL,
  `value` double NOT NULL,
  `fuelNorm` int(11) NOT NULL,
  KEY `Refuel_idVehicle_index` (`idVehicle`),
  KEY `Refuel_idRide_index` (`idRide`),
  CONSTRAINT `Refuel_Ride_id_fk` FOREIGN KEY (`idRide`) REFERENCES `Ride` (`id`),
  CONSTRAINT `Refuel_Vecicle_id_fk` FOREIGN KEY (`idVehicle`) REFERENCES `Vehicle` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

Ta tabela posiada dwie relacje. Z tabelą Vecicle (pojazd) oraz Ride (przejazd) jak wcześniej jest to relacja jeden to wielu. Czyli w pierwszej relacji jeden pojazd i wiele tankowań, w drugiej jeden przejazd i wiele tankowań. Taka relacja pozwala nam określić, przy którym przejeździe nastąpiło tankowanie. Oczywiście jest to relacja jedne do wielu, ponieważ do jednego przejazdu możemy przypisać wiele tankowań, jeżeli jedziemy w daleką trasę.

Tabela Settlement ()

Jest to tabela, dzięki której możemy powiązanie każdy pojazd do przejazdu i tankowania. Dzięki temu będzie możliwe prześledzić ile tak naprawdę kosztował nas każdy przejazd.

CREATE TABLE `Settlement` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `idVehicle` bigint(20) NOT NULL,
  `idRide` bigint(20) NOT NULL,
  `idRefuel` bigint(20) NOT NULL,
  `createDate` datetime NOT NULL,
  `fuel` double NOT NULL DEFAULT '0',
  KEY `Settlement_idVehicle_index` (`idVehicle`),
  KEY `Settlement_idRide_index` (`idRide`),
  KEY `Settlement_idRefuel_index` (`idRefuel`),
  CONSTRAINT `Settlement_Refuel_id_fk` FOREIGN KEY (`idRefuel`) REFERENCES `Refuel` (`id`),
  CONSTRAINT `Settlement_Ride_id_fk` FOREIGN KEY (`idRide`) REFERENCES `Ride` (`id`),
  CONSTRAINT `Settlement_Vecicle_id_fk` FOREIGN KEY (`idVehicle`) REFERENCES `Vehicle` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

Jak widać mamy tutaj powiązanie zarówno z tabelą Verhicle (pojazd), Ride (przejazdy) i Refuel (tankowania). Dzięki temu mamy powiązane wszystkie przejazdy i tankowania z pojazdem.

Teraz możemy obejrzeć wszystkie stworzone przez nas tabeli w całej okazałości:

Transport baza danych - Pokazanie widoku wszystkich stworzonych tabel

Widać wszystkie tabele i relacje między nimi. Sprawdźmy więc rozliczenie pojazdu baza danych. Sprawdźmy tylko, czy wszystko się zgadza i przejdźmy dalej do następnego artykułu.

Zaszufladkowano do kategorii Rozliczenie pojazdu | Otagowano , , , , , | Możliwość komentowania Rozliczenie pojazdu baza danych została wyłączona

Wzorzec projektowy budowniczy

Przykład zastosowania

Załóżmy że tworzymy projekt w oparciu o spring boot i w naszej aplikacji wykorzystujemy FreeMarker. Jednak nasz projekt jest tworzony przez dwie osoby. Pierwszą jesteśmy my sami i odpowiadamy za przygotowanie back end a druga tworzy projekt w FreeMarker i odpowiada za front end. Naszym zadaniem jest przekazanie dla tej drugiej osoby klasy modelu z którego FreeMarker będzie pobierał dane do wyświetlania. Oczywiście można zastosować zwykłą klasę która przekażemy do front endu ale ma to jeden wielki minus. Przez pomyłkę ta druga osoba może nadpisać nam dane, a znalezienie takiego błędy często graniczy z cudem. Dlatego w takim przypadku najlepszym rozwiązaniem jest wzorzec projektowy budowniczy.

Ktoś jednak powie jaki ma to sens skoro możemy przekazać dane w konstruktorze i nie tworzyć seterów. Ja również się z tym zgadzam. Jeżeli mam do przekazania dwie zmienne, to nie ma sensu tworzyć wzorca budowniczy. Inaczej sprawa wygląda gdy mamy do przekazania więcej niż dziesięć zmiennych. Ja osobiście spotkałem się z taką sytuacją gdy tworzyłem formularz do rekrutacji. Kandydat musiał zamieścić 20 różnego rodzaju dokumentów potwierdzających prawo do wyjazdu na Erasmus. W takiej sytuacji wykorzystałem wzorzec, aby poprawić czytelność kodu. Ponieważ bardzo łatwo można się zorientować czy na pewno prawidłowo zostały przekazane pliki do back endu.

Wzorzec projektowy budowniczy – budowa

Stwórzmy więc nasza pierwsza klasę, jednak nie będziemy jej za bardzo rozbudowywać aby łatwiej można było o co chodzi. W pierwszej kolejności tworzymy zwykłą klasę w której jednak nie będzie setterów.

public class Book {

    private String title;
    private String author;
    private int year;
    private String publisher;

    public Campaign(String title, String author, int year, String publisher) {
        this.title = title;
        this.author = author;
        this.year = year;
        this.publisher = publisher;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public int getYear() {
        return year;
    }

    public String getPublisher() {
        return publisher;
    }
}

Czyli co mamy. Po pierwsze tworzymy klasę Book a następnie w tej klasie cztery zmienne prywatne. Dlaczego prywatne aby nie było do nich dostępu z poza klasy. Dostęp będzie dostępny przez metody get których jest również cztery. Tak właśnie wygląda zwykła klasa. Brakuje jedynie metod set dzięki którym można ustawić dane. Jeżeli nie chcemy zmieniać wartości zmiennych po utworzeniu obiektu możemy zastosować właśnie taką konstrukcję a dane ustawiać przy tworzeniu obiektu przez podanie danych startowych w konstruktorze. Tak właśnie jest obecnie zbudowana ta klasa.

Jednak aby ta klasa implementowała wzorzec budowniczy musimy dodać jeszcze jedną metodę:

    public static final class Builder {
        private String title;
        private String author;
        private int year;
        private String publisher;

        private Builder() {
        }

        public Builder title(String title) {
            this.title = title;
            return this;
        }

        public Builder author(String author) {
            this.author = author;
            return this;
        }

        public Builder year(int year) {
            this.year = year;
            return this;
        }

        public Builder publisher(String publisher) {
            this.publisher = publisher;
            return this;
        }

        public Book build() {
            return new Book(this);
        }
    }

Dzięki zastosowaniu tej metody klasa obecnie zasługuje na nazwę budowniczy.

Wzorzec projektowy budowniczy – zastosowanie

Teraz pokażmy po co tak na prawdę ta cała zabawa. Przecież możemy do tego celu wykorzystać zwykły konstruktor. Więc zobaczmy najpierw jak wygląda tworzenie projektu przy wykorzystaniu konstruktora

String title = "Wzorce Projektowe";
String author = "Grzegorz Kossakowski";
int year = 2020;
String publisher = "programowanie.lomza.pl";
Book book = new Book(title, author, year, publisher);

Tak wygląda wykorzystanie konstruktora do budowy obiektu, teraz zajmiemy się tworzeniem obiektu przy zastosowaniu wzorca budowniczy.

String title = "Wzorce Projektowe";
String author = "Grzegorz Kossakowski";
int year = 2020;
String publisher = "programowanie.lomza.pl";

Book book = Book.newBuilder()
    .title(title)
    .author(author)
    .year(year)
    .publisher(publisher)
    .build();

Teraz można wreszcie przyjrzeć się w różnicy implementacji obydwu metod. W tym przypadku może tego tak nie widać ponieważ przekazujemy tylko cztery zmienne ale co by było gdyby było ich na przykład czternaście. Wtedy zalety stosowania wzorca budowniczy będzie bardziej oczywiste.

Wzorzec projektowy budowniczy – cała klasa

public class Book {

    private Book(Builder builder) {
        title = builder.title;
        author = builder.author;
        year = builder.year;
        publisher = builder.publisher;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    private String title;
    private String author;
    private int year;
    private String publisher;

    public Campaign(String title, String author, int year, String publisher) {
        this.title = title;
        this.author = author;
        this.year = year;
        this.publisher = publisher;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }

    public int getYear() {
        return year;
    }

    public String getPublisher() {
        return publisher;
    }

    public static final class Builder {
        private String title;
        private String author;
        private int year;
        private String publisher;

        private Builder() {
        }

        public Builder title(String title) {
            this.title = title;
            return this;
        }

        public Builder author(String author) {
            this.author = author;
            return this;
        }

        public Builder year(int year) {
            this.year = year;
            return this;
        }

        public Builder publisher(String publisher) {
            this.publisher = publisher;
            return this;
        }

        public Book build() {
            return new Book(this);
        }
    }
}

Zaszufladkowano do kategorii Wzorce projektowe | Otagowano , | Możliwość komentowania Wzorzec projektowy budowniczy została wyłączona

Typy proste w Javie

Wstęp

Do typów prostych w Javie zaliczamy wszystkie typy, które nie są obiektami, czyli nie posiadają żadnych metod i ich nazwy są pisane małą literą. Każdy typ prosty ma swojego odpowiednika w typie obiektowym, dzięki temu możliwe jest zastępowanie jednych drugimi. Przydaje, się zwłaszcza gdy chcemy mieć pewność ze zwracana wartość typu long jest na pewno różna od zera. W takiej sytuacji najlepiej użyć właśnie typu long zamiast Long. Typy proste w Javie dzielimy na cztery grupy:

  • Liczby całkowite
  • Liczby zmiennoprzecinkowe
  • Wartość logiczna
  • Wartość znakowa

Typy proste w Javie – Liczby

Liczby całkowite

To zbiór liczb naturalnych dodatnich, ujemnych oraz zero. Liczby całkowite są podzielone na cztery grupy ze względu na ilość zajmowanego przez nie miejsca w pamięci i zakresu przechowywania wartości.

byte1 bajtzakres od -128 do 127
short2 bajtyzakres od -32 768 do 32 767
int4 bajtyzakres od -2 147 483 648 do 2 147 483 647
long 8 bajtów zakres od -263 do 263-1

Liczby zmiennoprzecinkowe

Liczby zmiennoprzecinkowe to na przykład: 2.5 lub na przykład liczba Pi=3.14. Posiadają część dziesiętną i można je podzielić na dwie grupy ze względu na ilość zajmowanego przez nie miejsca w pamięci, a co za tym idzie dokładności przechowywania danych.

float4 bajty
double8 bajtów

Typy proste w Javie – Typ znakowy

Typ znakowy służy do przechowywania znaków zapisanych w kodzie UNICODE, pozwalające na zapisanie wszystkich dostępnych znaków. W rzeczywistości wykorzystuje się go bardzo rzadko a najczęściej używa się klasy String

char2 bajty

Typy proste w Javie – Typ logiczny

Typ logiczny w przeciwieństwie do pozostałych typów przyjmuje tylko dwie wartości, prawda lub fałsz. Jeżeli do zmiennej logicznej przekażemy 0 to zostanie ustawiona wartość fałsz, a jeżeli liczbę naturalną dodatnią zostanie ustawiona wartość prawda.

booleanprawda(true) / fałsz(false)

Typy obiektowe

Każdy z typów prymitywnych ma swój odpowiednik również w typach obiektowych (opakowanie). Nawet jest ich więcej niż typów prymitywnych.

  • Byte,
  • Integer,
  • Float,
  • Double,
  • Short,
  • Long,
  • BigDecimal,
  • BigInteger,
  • AtomicInteger,
  • AtomicLong.

Poza podstawowymi klasami, które również mają swoje odpowiedniki w typach prostych są jeszcze dodatkowe cztery klasy. Ponieważ pierwsze dwa (BigDecimal, BigInteger) służą do obliczeń z dużą dokładnością, kolejne dwa (AtomicInteger, AtomicLong) są wykorzystywane do obliczeń z wykorzystaniem wielowątkowości.

Podsumowując tak właśnie wyglądają typy proste w Javie. Typy proste są bardzo często wykorzystywanym elementem języka w codziennej pracy. W odróżnieniu od typów obiektowych nie przekazują wartości null. Na przykład, jeżeli chcemy mieć pewność, że wynik będzie wartością inną niż null, możemy skorzystać z typu prostego.

Przeczytaj pozostałe artykuły z serii Java

Zaszufladkowano do kategorii Java | Otagowano , | Możliwość komentowania Typy proste w Javie została wyłączona

Java pętla

Wstęp

Pobraliśmy dane z bazy danych i mamy w nich dwadzieścia obiektów tego samego typu. Pytanie brzmi jak wyświetlić te dwadzieścia wierszy i zaprezentować dane w konsoli. Odpowiedz jest prosta należy wykorzystać Java pętle

Obecnie mamy do dyspozycji trzy sposoby na operowanie na danych które mamy zgromadzone w liście, mapie lub zbiorze.

Java pętla – for

Zacznijmy od pętli for. Jest to najstarszy sposób wykonywania operacji z góry określoną ilość razy. Do takich operacji kiedyś należało obsługa kolekcji. Teraz wykorzystujemy do wykonania pewną z góry zakładaną ilość operacji, ale nie są to kolekcje. To kolekcji są lepsze rozwiązania.

for (int i =0; i<list.size(); i++) {
     System.out.println(list.get(i));
}

Zobacz, jak to działa. Najpierw omówmy parametry niezbędne do prawidłowego działania pętli.

for (int i =0; i<list.size(); i++) {

Kolejne zapisy są rozdzielone średnikami. Pierwszy to int i=0, który określa wartość początkową. Czyli tworzymy zmienną i nadajemy jej wartość zero. Są jednak sytuacje, kiedy wartość jest ustawiona inaczej. Możemy na przykład chcieć dodać coś takiego int i=list.size()-1, w takiej sytuacji przypisujemy do zmiennej ilość elementów w tabeli i odejmujemy jeden.

Kolejny zapis i<list.size() określa wartość końcową, po osiągnięciu której pętla przestaje działać. Tutaj również jak przy pierwszym elemencie jest możliwość dodania różnych zapisów na przykład i > 0.

W ostatnim zapisie określamy, jaka wartość ma być dodawana do zmiennej i. W tym przypadku wartość jest dodawana o jeden, ale możemy chcieć dodawać lub odejmować inną wartość.

Jednak podając nieprawidłowe parametry, możemy sprawić, że pętla nie wykona się ani razu, albo wykonywać się będzie bez końca. Przykładem nieskończonej pętli, jest taki zapis:

 for (int i =0; i=5; i+3)

Dlaczego jest to pętla nieskończona, sprawdźmy to. Po pierwszym przejściu wartość zmiennej i równa się zero. Po drugim przejściu równa się trzy a po trzecim już sześć. Jak widać, nigdy nie będzie pięć. Dlatego jest to tak niebezpieczna dla nas sytuacja.

Java pętla – foreach

Od Java w wersji 5 dostaliśmy do dyspozycji kolejną możliwość przeglądania (iteracji) po elementach na listach lub zbiorach. Pętla foreach od razu mamy dostęp do obiektu elementu przechowywanego w tabeli. To duże ułatwienie.

for (String text: list2) {
     System.out.println(text);
}

Jak widać używanie tej pętli, jest bardzo proste. Według mnie jest dużo bardziej czytelne niż wcześniejszej.

Java pętla – lambda

Od Java w wersji 8 możemy korzystać z kolejnego rozwiązania, które pozwala iterować po elementach na listach i zbiorach. Dodatkowo skrócił się zapis do jednej linijki. Można również jak w wersji foreach korzystać z bloku do tworzenia wielu operacji.

Pierwsza wersja pętli lambda wygląda następująco:

list2.forEach(text -> System.out.println(text));

Jak widzimy, zapis jest jeszcze prostszy niż poprzednio. Jest również wersja z blokiem kodu, w którym możemy użyć więcej niż jedno polecenie.

list2.forEach(text -> {
     System.out.println(text);
}

Jak widać, Java pętla są stosunkowo prostym elementem języka. Jednocześnie bardzo ważnym i najczęściej wykorzystywanym w kodzie elementem języka.

Przeczytaj pozostałe artykuły z serii Java

Zaszufladkowano do kategorii Java | Otagowano , , , | Możliwość komentowania Java pętla została wyłączona

Java Enum

Wstęp

Zajmiemy się teraz Java Enum, jest to typ danych wyliczeniowy. Można go porównać do stałych, czyli do takich zmiennych, które nigdy nie zmieniają swojej wartości. Jednak Enum ma więcej zalet. Grupuje te stałe w gotowe bloki. Pozwala szybko zrozumieć, co oznacza dana wartość.

public enum Status {
    CREATE, EMPLOYEE, CLIENT, ARCHIVE
}

Rozpatrzmy taką sytuację. Stworzyliśmy sobie cztery statusy. Pierwszy jest tworzony, gdy klient tworzy sprawę. Następnie sprawa jest przypisywana do pracownika, zmieniamy status na EMPLOYEE. Pracownik odpowiada klientowi, sprawa jest przepisywana dla CLIENT i tak w kółko aż do zakończenia rozmowy, gdy sprawa trafia na status ARCHIVE.

Czytelny kod przy wykorzystaniu Java Enum

Co daje nam takie rozwiązanie, przede wszystkim czytelność w kodzie. Załóżmy, że chcemy zapisać komentarz, który dostaliśmy od klienta i zmienić status na EMPLOYEE.

int result = documentDAO.upgradeStatus(document.getId(), Status.EMPLOYEE.id());
int result = documentDAO.upgradeStatus(document.getId(), 2);

Jeżeli porównamy te dwie linijki kodu, to stwierdzimy, że są one zupełnie inne. Jednak są one sobie równoznaczne. Jednocześnie można zauważyć, że w przypadku pierwszego zapisu od razu wiemy, jaki jest status. W drugim przypadku musimy sięgnąć do bazy danych, aby sprawdzić, co oznacza identyfikator 2. To już dużo więcej pracy.

Teraz jednak nasz status nie zadziała, bo nie zawiera metody Id, która zdefiniujemy teraz.

public enum Status {
    CREATE, EMPLOYEE, CLIENT, ARCHIVE;

    public int getId() {
        return this.ordinal()+1;
    }
}

Operowanie na Stringach

Możemy jednak nie wykorzystywać Enum w sposób przedstawiony powyżej. Gdy potrzebujemy porównać wartość otrzymaną w formie tekstowej z wartością Enum. Porównywanie wartości w Enum może się odbywać na dwa sposoby:

Pierwszy z nich to przekształcenia Enum na string i dopiero wtedy porównujemy wartości.

        Status status = Status.ARCHIVE;
        String archive = status.name();
        String arch = "ARCHIVE";
        if(archive.equals(arch)) {
            System.out.println("tak");
        } else {
            System.out.println("nie");
        }

Drugą zaś przekształcenie String na Enum i porównanie obydwu elementów

        Status status = Status.ARCHIVE;
        Status archive = Status.valueOf("ARCHIVE");
        if(status==archive) {
            System.out.println("tak");
        } else {
            System.out.println("nie");
        }

W tym jednak przypadku możemy się spotkać z problemem poprawności wprowadzanych danych. Co, gdy utworzymy taki kod:

        Status status = Status.ARCHIVE;
        Status archive = Status.valueOf("Archive");
        if(status==archive) {
            System.out.println("tak");
        } else {
            System.out.println("nie");
        }

Oczywiście otrzymujemy wyjątek. Jest to spowodowane faktem, że dla Javy Archive nie równa się ARCHIVE.

Exception in thread "main" java.lang.IllegalArgumentException: No enum constant Status.Archive
	at java.lang.Enum.valueOf(Enum.java:238)
	at pl.grzegorzkossa.weight.Status.valueOf(Status.java:3)
	at pl.grzegorzkossa.weight.Document.main(Document.java:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Przeczytaj pozostałe artykuły z serii Java

Zaszufladkowano do kategorii Java | Otagowano , | Możliwość komentowania Java Enum została wyłączona

Kolekcje w Javie

Wstęp

Kolekcje w Javie służą do przechowywania elementów tego samego typu. Najczęściej dane pobrane z baz danych są właśnie dostarczane w formie kolekcji. Takie rozwiązanie pozwala na operowanie na dużej ilości danych oraz zapewnia do nich szybki dostęp. Kolekcje dzielimy na trzy rodzaje: listy(List), Zbiory(Set) i Mapy(Map).

Kolekcje w Javie – Lista(java.util.List)

Lista służy do przechowywania elementów zgodnie z kolejnością jej dodawania. Każdy dodawany element posiada swój liczbowy identyfikator. Na podstawie tego identyfikatora możemy pobierać elementy z listy.

List<String> list = new ArrayList<>();
list.add("Kasia");

List<String> list1 = new LinkedList<>();
list1.add("Jan");

List<String> list2 = Arrays.asList("Kasia","Jan","Krzyś");

Pierwszy sposób utworzenia listy jest wykorzystywany do list, z których istnieje potrzeba dużej ilości odczytu zawartości. Drugi zapis sprawdza się tam gdzie więcej jest modyfikacji listy. Zapis trzeci jest tak naprawdę skróconym zapisem pierwszym.

Teraz zajmiemy się pobieraniem danych z listy. Mamy do dyspozycji trzy sposoby:

System.out.println("for");
for (int i =0; i<list2.size(); i++) {
     System.out.println(list2.get(i));
}

System.out.println("foreach");
for (String text: list2) {
    System.out.println(text);
}

System.out.println("lambda");
list2.forEach(text -> System.out.println(text));

Pierwszy wykorzystuje zwykłą pętle for jest to zarazem najstarszy sposób pobieranie elementów z listy. Kolejny sposób wykorzystuje konstrukcja foreach a ostatni jest najmłodszy wykorzystuje lambdę.

Kolekcje w Javie – Zbiór(java.util.Set)

Zbiór przechowuje elementy, które się nie powtarzają. W przeciwieństwie do listy zbór nie posiada metody get do pobrania element ze zbioru. Jednak można pobrać elementy ze zbioru przy wykorzystaniu lambdy i foreach. Dokładnie tak samo, jak w przypadku listy. Deklarujemy zbór w następujący sposób:

Set<String> name = new HashSet<>();
name.add("Kasia");
name.add("Jan");
name.add("Krzyś");
name.add("Kasia");

Set<String> name1 = new TreeSet<>();
name1.add("Kasia");
name1.add("Jan");
name1.add("Krzyś");
name1.add("Maks");

Pierwszy zapis to podstawowy zapis implementacji kolekcji Set. Przechowywane elementy nie mają określonej kolejności. W przypadku drugiego zapisu tworzony zbiór jest przechowywany w postaci posortowanej.

Kolekcje w Javie – Mapa

Mapa w odróżnieniu od pozostałych kolekcji przechowuje odwzorowanie klucz – wartość. Jeżeli wykorzystujemy mapę to musimy pamiętać że klucze nie mogą się powtarzać. Jeżeli drugi raz jako klucz wpiszemy tę samą wartość, wartość wcześniejsza zostanie nadpisana(utracona). Inaczej ma się sprawa z wartościami przypisane do różnych kluczy. Tutaj wartości mogą się powtarzać.

Map<String, String> name = new HashMap<>();
name.put("Kasia","Białystok");
name.put("Jan","Warszawa");
name.put("Krzyś","Łomża");
name.put("Kasia","Warszawa");

System.out.println("foreach");
for (String key: name.keySet()) {
    System.out.println("key: "+key+", value: "+name.get(key));
}

System.out.println("lambda");
name.forEach((key, value) -> {
    System.out.println("key: "+key+", value: "+value)
});

W pierwszym elemencie deklarujemy mapę i uzupełniamy ja o wartości wykorzystujące metodę put oraz podając do tej metody zestaw klucz i wartość. Zmienia się również sposób pobierania danych w przypadku mapy. Ponieważ przy pętlach foreach pobieramy najpierw listę kluczy. Dopiero na jej podstawie jesteśmy w stanie pobrać wartości. W przypadku lambda dostajemy od razu zestaw klucz wartość.

Teraz już wiemy jak działają kolekcje w Javie i jak można ich użyć na przykład do pobierania informacji z takich elementów. Podsumowując kolekcje są bardzo użytecznymi elementami w języku ponieważ pozwalają na szybki dostęp do danych.

Przeczytaj pozostałe artykuły z serii Java

Zaszufladkowano do kategorii Java | Otagowano , , , , , , | Możliwość komentowania Kolekcje w Javie została wyłączona

Jak zrozumieć bazę danych

Znasz dobrze Excel lub inny arkusz kalkulacyjny i zaczyniasz się zastanawiać co mogło by ci pomóc w codziennej pracy. Kolejnym krokiem jest poznanie i rozpoczęcie używania bazy danych, ale jak zrozumieć bazę danych.

Większość nowoczesnych firm posiada bazy danych, w których przechowuje dane dotyczące sprzedaży, pracowników lub inne. Aby wykonać zestawienie najpierw musisz poprosić osobę z działu IT o udostępnienie ci odpowiednich danych i dopiero wtedy możesz rozpocząć analizę danych.

Nie myśl, że to nie możliwe i firma na pewno się nie zgodzi, bo możesz coś popsuć, to nie prawda. Administrator może tak skonfigurować twoje uprawnienia do bazy danych, że będziesz miał dostęp tylko do odczytu więc nic nie nadpiszesz. Dodatkowo możesz dostać dostęp tylko do interesujących cię danych aby zrobić statystyki sprzedaży lub inne zestawienia.

Excel

Na początku zaprezentuje prosty arkusz kalkulacyjny. Najlepiej zacząć od czegoś prostego a dopiero później brać się za trudniejsze rzeczy.

Jak widzimy na obrazku nasz arkusz zawiera kilka kolumn. Dwie pierwsze wyraźnie są informacjami o osobie dokonującej zakupu. Kolejne dwie to informację o dokonanej transakcji, kolejne trzy są towarem, który został zakupiony. To oczywiście powinieneś już znać więc przechodzimy dalej.

Baza danych

Teraz musimy na podstawie tego arkusza stworzyć bazę danych. W bazie danych podstawowym elementem przechowywania danych jest tabela. W odróżnieniu od arkusza kalkulacyjnego w bazie danych dane dotyczące osoby nie powinny się powtarzać. Taka sama sytuacja jest w przypadku transakcji i towarów. W tym przypadku podzielimy nasz arkusz na trzy tabele(karteczki)

  • Na pierwszej karteczce umieścimy imię i nazwisko.
  • Druga karteczka to faktura i data sprzedaży.
  • Trzecia karteczka to dane transakcji.

Jednak jak spojrzysz na nasze tabele(karteczki) to wyraźnie widać, że już nie wiadomo jak połączyć te tabele(karteczki), straciliśmy powiązania między danymi na każdej z tabel i dlatego straciliśmy logiczne dane, jakie mieliśmy zapisane w Excel.

Aby to naprawić należy przyswoić pierwszą z bardzo ważnych elementu budowy tabel w bazie danych. Chodzi oczywiście o klucz główny, który pomaga identyfikować elementy w tabeli.

Jednak po nadaniu klucza głównego nadal nie wiemy jak te dane powinny zostać połączone. Ten problem rozwiązuje klucz obcy. W danej tabeli wpisujemy jeden klucz główny i kilka lub wcale kluczy obcych aby odzyskać powiązania między tabelami.

No i proszę już teraz wiemy co z czym jest powiązane i możemy przejść do kolejnego etapu. Wiemy już jak z Excel zrobić bazę danych, ale teraz jak odwrócić ten proces i z danych zgromadzonych w tabelach wykonać właśnie takie zestawienie, które później możemy zaimportować do Excel.

SELECT o.imie, o.nazwisko, f.nrFaktury, f.data, t.nazwa, t,ilosc, t.cena, t.suma
FROM faktura as f
INNER JOIN osoba as o on f.osoba_id=o.id
INNER JOIN towar as t on t.faktura_id=f.id

Teraz udało się nam utworzyć z danych zgromadzonych w bazie danych arkusz. Oczywiście to nie wszystko, teraz możemy zmodyfikować nasze zapytanie i od razu pobrać odpowiednie dane jeszcze zanim pobierzemy dane do arkusza. Teraz stworzymy nowe zapytania, w które pobierzemy tylko dane dla klientek, które mają na imię Ania.

SELECT o.imie, o.nazwisko, f.nrFaktury, f.data, t.nazwa, t,ilosc, t.cena, t.suma
FROM faktura as f
INNER JOIN osoba as o on f.osoba_id=o.id
INNER JOIN towar as t on t.faktura_id=f.id
WHERE o.imie='Ania'

Więc jak zrozumieć bazę danych

Czy odpowiedziałem na pytanie, jak zrozumieć bazę danych, jeżeli nie to daj znać w komentarzach.

Zaszufladkowano do kategorii Baza danych, SQL | Otagowano , , , | Możliwość komentowania Jak zrozumieć bazę danych została wyłączona