Jak stworzyć "mini bazę danych" w Javie?

Jak stworzyć "mini bazę danych" w Javie?
ES
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 lat
  • Postów:11
0

Witam. Na początku roku zacząłem uczyć się Javy z ksiażki "Java. Przewodnik dla początkujących. Wydanie VI" H. Schildta. Programy i ćwiczenia w tej książce są dość krótkie, a muszę do końca przyszłego tygodnia zrobić jakiś większy projekt w Javie na zaliczenie przedmiotu na studiach (daruje sobie tłumaczenie, dlaczego dopiero teraz zacząłem xd).

Muszą zrobić program, który ma być czymś w rodzaju "Menadżera Hotelarstwa", tj. użytkownik powinien mieć możliwość:

  • dodawania hoteli
  • rejestrowania w nich gości (przed rejestracją wybiera się hotel, następnie wpisuje się dane gościa, nr pokoju, date początku i końca pobytu, cenę za pokój itd)
  • dodawania pracowników do hotelu (powinno działać podobnie jak z gościem, ale trochę inne dane, tj. pensja, okres zatrudnienia itd).
  • program powinien zawierać odpowiednią obsługę błędów (czyli nie mogą być dwa hotele o tej samej nazwie, nie można dodać gościa do nie istniejącego hotelu, data początku pobytu w hotelu nie może być za datą końca pobytu itd.)
  • wyświetlanie listy hoteli, pracowników i gości z danego hotelu
  • możliwość usunięcia całego hotelu i zaktualizowanie listy hoteli
  • program ma być obsługiwany w konsoli i ma mieć stworzone odpowiednie menu, w którym jest możliwość wyboru konkretnych opcji, a także powrót do poprzedniej części menu

Kiedyś napisałem w zasadzie identyczny program, tyle że napisany w C techniką programowania proceduralnego, więc mam ogólną koncepcje, jak się za to zabrać. Tylko mam jeden problem, a mianowicie jak zrobić "bazę danych", które będzie przechowywać wszystkie informacje. Mogę ją zrobić w dowolny sposób, nie muszę jej tworzyć w jakimś stricte języku baz danych. Mam dwa pomysły:

  1. Zapisywać dane w plikach z rozszerzeniem .txt (ewentualnie w plikach binarnych, tak jak to zrobiłem w C). Np. mógłbym (nie jestem pewny, czy tak się da) zapisywać zawartość jakiegoś tam obiektu klasy, który jest hotelem i potem to odczytywać z pliku. Zaletą tego rozwiązania będzie to, że po zamknięciu programu baza danych nie przepadnie i po ponownym uruchomieniu programu będzie można ją odczytać, jednak nie jest to wymagane.

  2. Zapisywać dane w jakimś kontenerze. Nie wiem, jakiejś dynamicznej tablicy, która będzie przechowywać dane i w razie potrzeby powiększać się w trakcie działania programu w celu zwiększenia ilości danych (oczywiście wymagany jest też odczyt tych danych), jednak po wyłączeniu programu, wszystkie dane przepadną.

I teraz pytanie, które rozwiązanie będzie lepsze i prostsze dla takiego laika jak ja. W sumie ogarniam tylko pierwszą połowę materiału z książki Schildta, czyli typy danych i operatory, instrukcje sterujące, klasy, metody, obiekty, a także dziedziczenie, interfejsy, pakiety i wyjątki. Obsługi plików nie ogarniam, ale jest to raczej prosta "baza danych", to z pomocą internetu powinienem być w stanie to zrobić. Może mi ktoś doradzić, które z dwóch powyższych rozwiązań dotyczącego zapisywania danych będzie lepszym wyborem?

I jeszcze jedno: załóżmy, że wybrałbym opcję nr 2. Czy w Javie jest jakiś mechanizm pozwalający na stworzenie dynamicznej tablicy obiektów jakiejś tam klasy, która będzie się dynamicznie powiększać w trakcie działania programu? Pamiętam, że w C++ można zrobić tablicę "vector" i następnie za pomocą instrukcji "push_back" dynamicznie powiększało się rozmiar tablicy np. w jakiejś pętli, w zależności od tego, jak dużej tablicy potrzebowaliśmy. Czy da się coś takiego zrobić w Javie?

Wiem, że trochę się rozpisałem, ale liczę na Waszą pomoc. Dzięki.

E9
  • Rejestracja:ponad 8 lat
  • Ostatnio:dzień
  • Postów:216
2

Obydwie opcje są oczywiście jak najbardziej wykonalne. Dobrze zauważyłeś, że w pierwszej plusem jest to że dane będą dostępne po zakończeniu działania programu. Na początek jednak wydaje mi się że spokojnie możesz oprzeć się na drugiej opcji, czyli zapisaniu danych w jakiejś dynamicznej kolekcji, np. HashMapie.

Poszedłbym jednak o krok dalej, pisałeś że znasz interface, więc napisz taki w którym zdefiniujesz opcje które będziesz wykonywać na swoich obiektach, np.

Kopiuj
public interface HotelDatabase {
    public UUID save(Hotel hotel);
}

I możesz dorobić do niego kilka implementacji, na początek np.

Kopiuj
public class InMemoryDatabase implements HotelDatabase {
    private HashMap<UUID, Hotel> hotelHashMap = new HashMap<>();

    public UUID save(Hotel hotel) {
        UUID uuid = UUID.randomUUID();
        hotelHashMap.put(uuid, hotel);
        return uuid;
    }
}

A gdy zdecydujesz, że chcesz zapisywać obiekty w pliku, zrobisz nową implementację tego interface, np. FileDatabase, czy MysqlDatabase i w kodzie aplikacji jedynie wstawisz go zamiast InMemoryDatabase.

Co do pytania o dynamiczne kolekcje, polecam google i java collections.

edytowany 1x, ostatnio: Emdzej93
zyxist
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 6 lat
  • Postów:101
2

Witaj! Jeśli chcesz poćwiczyć Javę, to faktycznie pomysł z implementacją całego modelu danych po stronie Javy jest bardzo dobry.

Oba podane przez Ciebie sposoby można bardzo dobrze połączyć. Jak zapewne już wiesz, w Javie (prawie) wszystko to obiekty i klasy. Utwórz sobie kilka klas reprezentujących Twoje hotele, itd. i operuj na nich. Biblioteka standardowa Javy posiada API kolekcji wraz z implementacjami takich struktur danych, jak listy czy mapy (pary klucz-wartość), których możesz użyć:

Kopiuj
Map<Integer, Hotel> hotels = new LinkedHashMap<>();
hotels.put(1, new Hotel("Foo"));
hotels.put(2, new Hotel("Bar"));

Hotel someHotel = hotels.get(2);

Druga rzecz, czyli jak radzić sobie z zapisywaniem i odczytywaniem danych. Jest taka biblioteka do Javy o nazwie Jackson, która pozwala konwertować Twoje obiekty na format JSON i w drugą stronę. Jest ona dość prosta w użyciu. W Twoich klasach używasz adnotacji do tego, aby oznaczyć, które pola klasy (i jak) mają zostać zapisane, np.

Kopiuj
public class Hotel {
   @JsonProperty
   private String name;
   @JsonProperty
   private String address;
}

Następnie możesz to konwertować na format JSON i vice versa:

Kopiuj
Hotel someHotel = hotels.get(2);

ObjectMapper objectMapper = new ObjectMapper(); // może być jeden na całą aplikację
objectMapper.writeValue(new File("hotel.json"), someHotel);

Hotel anotherHotel = objectMapper.readValue(new File("anotherHotel.json"), Hotel.class);

Dodam, że nie musisz każdego hotelu zapisywać oddzielnie, możesz też od razu zapisać całą mapę ze wszystkimi hotelami i Jackson sobie z tym doskonale poradzi.


edytowany 1x, ostatnio: zyxist
ES
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 lat
  • Postów:11
0

Wielkie dzięki za odpowiedzi. Rozumiem, że opcja nr 2, czyli zapisywanie tych hoteli i informacji o nich w jakimś kontenerze, który będzie się dynamicznie powiększać w trakcie działania programu, będzie łatwiejsze i szybsze do zrobienia dla początkującego, niż zapis tych danych w pliku? Tak jak pisałem wcześniej, zapis danych do pliku i możliwość ich odczytania po ponownym uruchomieniu programu nie jest konieczny. Zależy mi po prostu na tym, aby jak najłatwiej i jak najszybciej zrobić ten program.

zyxist
  • Rejestracja:ponad 7 lat
  • Ostatnio:około 6 lat
  • Postów:101
2

Powtórzę raz jeszcze: możesz mieć zarówno opcję nr 1, jak i 2:

  1. w trakcie działania programu pracujesz na kontenerach,
  2. na początku wczytujesz zawartość kontenerów z JSON-a przy pomocy biblioteki Jackson, a na końcu ją tam zapisujesz. Właściwie to po każdej modyfikacji możesz zapisywać zawartość kontenera do JSON-a.

ES
Ale chodzi mi po prostu o to, który sposób jest łatwiejszy. Czyli nr 2 jest prostsza?
Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Futurama
  • Postów:887
1

Nr 2 jest zdecydowanie prostszy.
Wyżej zostało zaproponowane używanie JSONa do zapisu danych. Uważam, że w Twoim wypadku to zły pomysł.
Dlaczego?
Nie wiesz prawie nic o Javie:

Pamiętam, że w C++ można zrobić tablicę "vector" i następnie za pomocą instrukcji "push_back" dynamicznie powiększało się rozmiar tablicy np. w jakiejś pętli, w zależności od tego, jak dużej tablicy potrzebowaliśmy. Czy da się coś takiego zrobić w Javie?

a użycie dodatkowej biblioteki wiąże się najprawdopodobniej z nauką korzystania narzędzia typu Maven/Gradle (można to zrobić ręcznie, ale uważam, że jest z tym jeszcze więcej zabawy).
Kluczem tutaj jest czas, jak zostało podkreślone, więc nie ma się co bawić.
Jeśli punkt nr 1 nie jest wymagany to nawet na niego nie patrz. Możesz zrobić interfejs tak jak @Emdzej93 napisał i powiedzieć prowadzącemu, że udostępniasz interfejs, który w ramach potrzeby może służyć jako bramka do rozwinięcia projektu.

Jeśli chcesz robić punkt 1 warto zastanowić się jakie masz opcje. Ja myślę o 2 najprostszych:

  1. Zapis do pliku tekstowego. Definiujesz własny format, np.
Kopiuj
H[Nazwa Hotelu]
P[Imię pracownika][Nazwisko]...
G[Imię gościa][Nazwisko][Numer pokoju]...
(jakiś znak/ciąg znaków kończący sekcję)

Wymyślone na poczekaniu, oczywiście można to zrobić lepiej. Jeśli dane nie są poprawnie sformatowane to informujesz, że dane zostały naruszone i nie wczytujesz (ewentualnie analiza, gdzie wystąpił błąd, ale to zajmuje czas).
2. Każda klasa modelująca dane (hotel, gość, pracownik, etc. - wszystko co zamierzasz trzymać) implementuje interfejs Serializable (to wystarczy).
Zapisujesz np. listę hoteli, które mają w sobie wszystkie wymagane dane w taki sposób. Szybko i łatwo. Plik można bez problemu wczytać na początku działania programu.

Good luck!


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
ES
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 5 lat
  • Postów:11
0
Burdzi0 napisał(a):

Możesz zrobić interfejs tak jak @Emdzej93 napisał i powiedzieć prowadzącemu, że udostępniasz interfejs, który w ramach potrzeby może służyć jako bramka do rozwinięcia projektu.

No ok, ale i tak musi być możliwość odczytania zapisanych już hoteli w programie po wybraniu odpowiedniej opcji. Czyli po stworzeniu tego interfejsu i zaimplementowaniu go w jakiejś klasie i tak muszę gdzieś zapisywać te dane.

Emdzej93 wspomniał coś o zapisywaniu tego w dynamicznej kolekcji, tzw. HashMapie. To dobry pomysł?

Burdzi0
  • Rejestracja:prawie 9 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Futurama
  • Postów:887
1

Tak, trzymaj je w czymkolwiek Ci wygodnie, tj. dowolnej kolekcji, która będzie Ci pasowała do implementacji. Kolekcje typu Hash* korzystają z hash code, dzięki czemu ma to przełożenie na performance, ale mając 3 czy 10 hoteli nie zauważysz różnicy w wydajności programu. Zastanów się czy potrzebujesz bardziej listy (jakaś implementacja interfejsu List z biblioteki Javy), kolejki (Queue), seta (Set, ale pamiętaj, że set nie trzyma duplikatów) czy mapy (Map) i użyj. One wszystkie mają (zazwyczaj bo nie znam każdej implementacji na pamięć) rozszerzalną pamięć (zachowanie analogiczne do vectora). Jeśli chcesz właśnie coś na kształt vector z Cpp to chyba najbliżej jest ArrayList<>. Kolekcje w Javie są generyczne i nie myl tego z szablonami z cpp (mają podobieństwa, ale szablony != generyki).


Bite my shiny metal ass!
Life throws you an error code like that, you don't have the luxury of a ZnVja2luZw== pop-up explanation *Robię projekty studenckie, pisz priv ;) *
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)