JDBC - Podstawy pracy z bazą danych

Zanim zaczniecie czytać dalszą część kursu, musicie mieć dostęp do jakiejś bazy danych. Aktualnie nie ma artykułu na naszej stronie o bazach danych, gdyż to jest tematyka związaną stricte z Javą, ale mogę obiecać, że wprowadzenie jak zainstalować i kilka podstaw opiszę już wkrótce. Dla samodzielnych zuchów proponuje spróbować samemu zainstalować sobie bazę danych na dysku (na potrzeby kursu wystarczy MySQL ). W razie ewentualnych pytań, zapraszam na forum. Zaczynamy!

Teraz gdy już wiemy, jak przekazywać zmienne do naszej aplikacji webowej, należy coś z tymi danymi robić. Aplikacje webowe mają za zadanie przetwarzać dane, które otrzymują od klientów oraz zapisywać je w bazach danych, skąd później są wyciągane, przetwarzane w różnoraki sposób i zwracane do klienta. Oczywiście to tylko jeden z wielu scenariuszy jaki może się wydarzyć. Idea jest jedna. Aplikacja webowa jest pośrednikiem danymi (zawartymi w bazie danych), a klientami, którzy ich potrzebują. Na początek, by nasza aplikacja stała się takim pośrednikiem, wykorzystamy JDBC.

**JDBC,**czyli Java DataBase Conectivity - jest to interfejs pozwalający na ustanowienie połączenia do bazy danych z poziomu aplikacji napisanej w Javie. Biblioteki, których potrzebujemy, zawierają pakiety java.sql.* i są w taki sam sposób dostępny jak kolekcje w pakietach java.util.* .

trans-updatingMultipleDataases

Klientemi mogą być : przeglądarki internetowe, telefony komórkowe, inne aplikacje webowe, telewizory a nawet routery (jak się je odpowiednio przerobi).

Servlet- komponent odpowiedzialny za komunikacje z klientem za pomocą protokołu http.

Bazami danychmogą być : serwer MySQL, SQLite, Oracle Database bądź inna relacyjna baza danych. Dla naszych potrzeb wystarczy MySQL, ze względu na prostotę instalacji i konfiguracji.

Widzimy tutaj, żę JDBC jest wstanie pracować z różnymi bazami danych. Dzieje się tak, gdyż wystarczy podać dla JDBC odpowiedni sterownik obsługujący dany typ bazy danych. I już, nic więcej nas nie interesuje. Skoro my będziemy pracować na bazie danych MySQL, skorzystamy ze sterownika "com.mysql.jdbc.driver".

Tyle teorii, zobaczmy jak to będzie wyglądać w praktyce.

Napiszemy sobie teraz prostą aplikację, która będzie zapisywała artykuły bloga przesyłane przez użytkowników za pomocą prostego formularzu.

Nasz artykuł będzie posiadał 4 pola:

  • id - określa unikalny identyfikator artykułu w bazie danych
  • title - tytuł artykułu
  • text - tekst artykułu
  • date - data powstania artykułu
public class Article {
 
 	private int id;
 	private String title;
 	private String text;
 	private Date date;
 
 // getters and setters
 
 ...
 
 }

Kurs Java EE i Jakarta EE

Jak pisałem wyżej, Servlet ma zadanie pobrać artykuł z http POST i przekazać go do JDBC :

public class GetArticleServlet extends HttpServlet {
 
 	private static final long serialVersionUID = 5397405593623536498L;
 
 	/**
 	 * Parser, który ma za zadanie przetwarzanie
 	 * źródła posiadającego artykuł. Źródłem może 
 	 * być np HttpRequest
 	 */
 	private ArticleParser articleParser;
 
 	/**
 	 * DAO - typ klasy odpowiadający za połączenie
 	 * aplikacji ze źródłem danych, np. bazą danych.
 	 * To tutaj będzie znajdować się implementacja
 	 * JDBC.
 	 */
 	private ArticleDAO articleDAO;
 
 	//inicjalizacja komponentów
 	public GetArticleServlet() {
 		articleParser = new ArticleParser();
 		articleDAO = new ArticleDAO();
 	}
 
 	//pobieranie artykułu z http POST
 	public void doPost(HttpServletRequest request,
             HttpServletResponse response)	throws ServletException, IOException {
 
 		//Wykorzystaj parser do artykułów i pobierz artykuł z requesta
 		Article article = articleParser.parseArticleFromRequest(request);
 
 		//zapisz artykuł do bazy danych
 		articleDAO.save(article);
 	}
 }

Widzimy tutaj nowy byt - DAO . Od tej pory zawszę będziemy nazywać komponenty naszej aplikacji za pomocą słowo DAO, które odpowiadają za komunikacje z bazą danych. W naszym wypadku jest to articleDAO, które odpowiada za operacje na obiektach klasy Article.

DAO oznacza data access object, czyli miejsce wymiany danych między naszą aplikacją, a jakimś zewnętrznym bytem (jak np. baza danych MySQL).

public class ArticleDAO {
 
 	/**
 	 * Tutaj należy zdefiniować użytkownika, hasło, adres oraz
 	 * sterownik do bazy danych z którą zamierzamy się połączyć.
 	 */
 	private final static String DBURL = "jdbc:mysql://127.0.0.1:3306/blog";
 	private final static String DBUSER = "root";
 	private final static String DBPASS = "****";
 	private final static String DBDRIVER = "com.mysql.jdbc.Driver";
 
 	//obiekt tworzący połączenie z bazą danych.
 	private Connection connection;
 	//obiekt pozwalający tworzyć nowe wyrażenia SQL
 	private Statement statement;
 	//zapytanie SQL
 	private String query;
 	//parser zapytań SQL dla obiektów klasy Article
 	private SQLArticleParser sqlArticleParser;
 
 	public ArticleDAO() {
 		//inicjalizacja parserów
 		sqlArticleParser = new SQLArticleParser();
 	}
 
 	public void save(Article article) {
 		query = sqlArticleParser.createSaveQuery(article);
 
 		try {
 			Class.forName(DBDRIVER).newInstance();
 			connection = DriverManager.getConnection(DBURL, DBUSER, DBPASS);
 			statement = connection.createStatement();
 			statement.executeUpdate(query);
 
                         //zwolnienie zasobów i zamknięcie połączenia
                         statement.close();
                         connection.close();
 		} catch (InstantiationException | IllegalAccessException
 				| ClassNotFoundException | SQLException e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
 	}
 }

Widzimy tutaj na początku 4 zmienne odpowiadające za połączenie z bazą danych. Musimy zdefiniować tutaj użytkownika oraz hasło dla niego, jakie podaliśmy przy tworzeniu bazy danych, adres serwera bazy danych oraz nazwę sterownik.

Następnie inicjalizuję sobie parser dla artykułów, który będzie mi generować zapytania w języku SQL dla artykułów.

Metoda "save" przyjmuje jako parametr "article", który zapijemy do bazy. Na początku metody buduję "query", który uzyskuje za pomocą napisanego przeze mnie parsera. Query wygenerowane przez sqlArticleParse będzie miało postać "INSERT INTO article VALUE (NULL, 'title', 'text');". Następnie inicjalizujemy sterownik "com.mysql.jdbc.Driver" oraz ustanawiamy połączenie z bazą danych za pomocą klasy DriverManager podając parametry. Następnie inicjalizujemy obiekt "statement" wykonujący wyrażenia sql za pomocą metody executeStatement(query) lub executeQuery(query) (w zależności od wykonywanego zapytania). Na końcu zamykam połączenie, ponieważ nie przewiduje więcej operacji związanych z bazą danych.

To wszystko, widzimy tutaj że nie ma jakiejś dużej filozofii. Jedynie co tutaj może się zmienić, to zapytanie query, jakie wykonujemy przez statement. Query będzie się zmieniało w zależności od tego, czy chcemy pobrać, zapisać, aktualizować czy usuwać dane, a aby wiedzieć jak tworzyć efektywne query, należy poznać podstawy języka SQL. Oczywiście rozwiązanie które wam zaprezentowałem, jest bardzo trywialne i należy je stosować tylko w przypadku jednorazowej wymiany danych z bazą danych. W przypadku aplikacji opartej na bazie danych, gdzie wymiana danych jest bardzo istotnym elementem, należy korzystać z bibliotek bądź nawet frameworków, które takie działania wspierają (np. framework Hibernate, o którym będę pisał już w krótce).

Dodatek:

SqlarticleParser:

public class SQLArticleParser {
 
 	//Metoda tworząca zapytanie SQL zapisujące artykul do bazy
 	public String createSaveQuery(Article article) {
 		String query = "";
 
 		/**
 		 * Dodaj do tabeli "articles" wartości id, title i text.
 		 * id jest nullem, ponieważ pole id jest autoinkrementowane
 		 * przez bazę danych.
 		 * INSERT INTO articles VALUES (NULL, 'title', 'text');
 		 */	
 		query = "INSERT INTO articles VALUES (NULL, '" + article.getTitle() + "', '" + article.getText() +"');";
 
 		return query;
 	}
 }

Zadania do realizacji:

  • Rozszerz możliwości aplikacji o wczytywanie, usuwanie i aktualizacji artykułów.
  • Dodaj klasę "Autor" i połącz go z artykułem.

Tips & Tricks:

  • Wykonując zapytanie wykorzystaj klase "ResultSet", którą można wykorzystać jako kolekcji wierszy z tabeli, przykład:
ResultSet result = statement.executeQuery("SELECT id, name From articles");
 while(result.next()) {
     int id = result.getInt("id");
     String name = result.getString("name");
 }

Postaram się w jak najszybciej stworzyć kurs, jak zainstalować i skonfigurować bazę danych MySQL.

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.

Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.

Arek

Świetny kurs, czekamy na więcej z JavyEE

KOLO

Szukam pomocy w poprawie kodu żródłowego pliku, który zapisuje dane do bazy danych. Przeniosłem serwis na serwer w netart.pl i nie działa prawidłowo, na poprzednim serwerze działało ok - tam był apache system. Oczywiście odpłatnie poszukuję eksperta który pomoż znaleźć błąd w kodzie pliku. Pozdrawiam

Sivter

Witam chciałbym połączyć mój servlet z baza oracle database i mam pytanie czy przebiega to adekwatnie do tego przykładu czy moze inaczej ?

Paweł

Proszę o pomoc. Przy próbie uruchomienia kodu mam błąd: HTTP Status 405 - HTTP method GET is not supported by this URL type Status report message HTTP method GET is not supported by this URL description The specified HTTP method is not allowed for the requested resource.