Ponieważ JavaFX zyskuje na popularności jako de facto framework GUI Javy, prędzej czy później zastąpi Swing. JavaFX UI i JDBC mogą stanowić skuteczną kombinację podczas tworzenia aplikacji opartej na bazie danych, zwłaszcza w systemie offline lub wbudowanym. Ten artykuł zasadniczo pokazuje, jak można to zrobić na przykładowym scenariuszu.
Omówienie aplikacji JDBC
Ewolucja frameworka Java GUI opiera się teraz na bibliotece JavaFX. Zapewnia potężną, ale elastyczną alternatywę dla programowania GUI, w przeciwieństwie do istniejącego frameworka Swing i AWT. JavaFX dostarcza dużą tablicę lub elementy sterujące i komponenty, które pomagają w szybkim i efektywnym tworzeniu interfejsu GUI. Bardzo łatwo jest stworzyć aplikację desktopową, która współpracuje z bazą danych zaplecza. JDBC (połączenie z bazą danych Java) aplikacja ma przede wszystkim system baz danych zaplecza, taki jak MySQL, Derby, Oracle lub dowolna inna baza danych. Kod Java jest pisany w celu pobierania rekordów z jednej lub kilku tabel w bazie danych. SQL (ustrukturyzowany język zapytań) Zapytania są uruchamiane z kodu Java i wysyłane do silnika bazy danych w celu przetworzenia. Sterownik JDBC działa jako pośrednik między programem Java a bazą danych i interpretuje mnóstwo informacji tam iz powrotem, dzięki czemu zarówno niezrównana strona, taka jak baza danych, jak i program Java mogą pogodzić się z praktycznym rozwiązaniem. Baza danych nie ma żadnego pojęcia o kodzie Java, jego składni ani o niczym na ten temat. Po prostu rozumie SQL i może się tylko z nim komunikować. Z drugiej strony Java to OOP (Programowanie zorientowane obiektowo) języka i nie ma też pojęcia o SQL ani jego składni. Aby komunikacja była możliwa, dostawca bazy danych wraz z bazą danych dostarcza sterowniki natywne. Nazywa się to sterownikiem JDBC. Zwróć uwagę, że dostępne są cztery typy sterowników. Są one potocznie nazywane sterownikami typu 1, typu 2, typu 3 i typu 4. Sterowniki natywne są sterownikami typu 4 i są najczęściej używane. Są również bardziej wydajne niż inne typy. Program Java może zawierać te sterowniki JDBC jako zewnętrzną bibliotekę do programu Java, ponieważ są one zwykle dostępne w plikach archiwów JAR.
JavaFX w scenie
Każda aplikacja bazy danych wymaga interfejsu, aby użytkownik mógł wchodzić w interakcję z informacjami z bazy danych. Lepiej, jeśli jest to interfejs GUI, w którym nie musimy zniżać się do niskopoziomowego, zastraszającego interfejsu poleceń, ale uzyskać to, czego chcemy za pomocą jednego kliknięcia. W tym aspekcie JavaFX z JDBC może być zabójczą kombinacją, ponieważ zawiera sporo interesujących wizualnie komponentów GUI, które można wykorzystać do reprezentowania rekordów bazy danych w bardziej znaczący sposób. Na przykład rekordy mogą być wyświetlane w formie tabelarycznej za pomocą TableView kontrola. Lub możemy stworzyć formularz, aby dodać nowe rekordy do tabeli bazy danych. Dane wprowadzone przez użytkownika można zweryfikować za pomocą kodu Java przed wysłaniem do bazy danych. Silnik bazy danych zaplecza otrzymuje wytchnienie od sprawdzania poprawności danych i zablokowania przetwarzania z powodu błędu wejściowego. Co więcej, użytkownik końcowy może być laikiem, który ma niewielkie pojęcie o ograniczeniach danych wejściowych lub nie ma go wcale. Najlepiej zrobić to, gdy formularz wejściowy jest tworzony za pomocą TextField , Etykieta , Pole Combo i ListView kontrole w JavaFX. Zdarzenia generowane przez Przycisk a inne elementy sterujące są obsługiwane w taki sposób, aby użytkownik mógł swobodnie korzystać z interfejsu GUI.
W przykładowym scenariuszu
W poniższym ilustrowanym przykładzie zaimplementujemy ListView operacja wyszukiwania przez wpisanie tekstu w TextField . Wybrany element w ListView jest odpowiednio pobierany z bazy danych zaplecza i wyświetlany w TableView kontrola. Jest to więc przede wszystkim aplikacja typu „pobierz i wyświetl”. Inne operacje na bazie danych — takie jak wstawianie, usuwanie i aktualizowanie rekordów — nie są implementowane ze względu na ograniczenia rozmiaru. Byłoby miłym ćwiczeniem, aby wdrożyć je samodzielnie.
Tak więc, zanim zaczniemy, musimy stworzyć tabelę bazy danych i projekt Java. Użyjemy MySQL jako wewnętrznej bazy danych; możesz wybrać dowolny inny, ale upewnij się, że w pliku pom.xml znajdują się odpowiednie sterowniki plik. Oto część kodu SQL do tworzenia tabeli, wstawiania niektórych fikcyjnych danych i kilku innych operacji.
CREATE DATABASE addressbook; USE DATABASE addressbook; DROP TABLE IF EXISTS contact; CREATE TABLE contact( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, nick_name VARCHAR(20), address VARCHAR(128), home_phone VARCHAR(10), work_phone VARCHAR(10), cell_phone VARCHAR(10), email VARCHAR(100), birthday date, web_site VARCHAR(100), profession VARCHAR(100), PRIMARY KEY (id) ); INSERT INTO contact (name, nick_name, address, home_phone, work_phone, cell_phone, email, birthday, web_site,profession) VALUES ('Bruce Wayne', 'batman', 'XYZ Batcave', '9876543210', '6278287326', '9182872363', '[email protected]', '1976/02/03', 'batblog.com', 'Super Hero'); ... INSERT INTO contact (...) VALUES (...); Maven Project: pom.xml <project xmlns_xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.mano.jdbc.examples</groupId> <artifactId>JavaFXJDBCApp</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <name>JavaFXJDBCApp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding> UTF-8 </project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <groupId> org.apache.maven.plugins </groupId> <artifactId> maven-compiler-plugin </artifactId> <version>2.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/mysql/ mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> </dependencies> </project>
Teraz utwórzmy obiekt domeny, którego użyjemy zarówno w ListView i TableView ponieważ obaj są ze sobą spokrewnieni, jak stwierdzono w naszym przypadku. TableView będzie zawierać obserwowalną listę osób (ContactPerson ) na podstawie imienia i nazwiska wybranej osoby z ListView kontrola. Mamy też TextField do szybkiego wyszukiwania elementów (ContactPerson nazwa) zawarte w ListView . Po wybraniu określonego elementu z ListView , uruchamiane jest zapytanie SQL i pobierane są odpowiednie rekordy w celu wypełnienia TableView kontrolować odpowiednio.
Obiekt domeny:Osoba kontaktowa
Osoba kontaktowa klasa to nic innego jak reprezentacja POJO kontaktu atrybuty tabeli. Zawiera konstruktor i prosty getter-setter metody.
package org.mano.jdbc.examples; import java.util.Date; public class ContactPerson { private int id; private String name; private String nickName; private String address; private String homePhone; private String workPhone; private String cellPhone; private String email; private Date birthDate; private String webSite; private String profession; public ContactPerson() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getHomePhone() { return homePhone; }< public void setHomePhone(String homePhone) { this.homePhone = homePhone; } public String getWorkPhone() { return workPhone; } public void setWorkPhone(String workPhone) { this.workPhone = workPhone; } public String getCellPhone() { return cellPhone; } public void setCellPhone(String cellPhone) { this.cellPhone = cellPhone; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } public String getWebSite() { return webSite; } public void setWebSite(String webSite) { this.webSite = webSite; } public String getProfession() { return profession; } public void setProfession(String profession) { this.profession = profession; } }
Obiekt dostępu do danych:ContactDAO
ContactDAO to klasa obiektów dostępu do danych, która obejmuje przede wszystkim operacje dostępu do bazy danych. Implementuje DAO berło. Ten interfejs może nie być ważny w naszym przykładzie, ale może być dobrze wykorzystany, jeśli aplikacja zostanie rozszerzona o więcej klas obiektów dostępu do danych. Tutaj DAO interfejs zawiera ciąg połączenia, sterownik oraz nazwę użytkownika i hasło umożliwiające dostęp do bazy danych MySQL.
DAO.java
package org.mano.jdbc.examples; public interface DAO { public static final String DB_URL = "jdbc:mysql://localhost:3306/"+ "addressbook?zeroDateTimeBehavior=convertToNull"; public static final String DRIVER = "com.mysql.jdbc.Driver"; public static final String USER = "root"; public static final String PASS = "secret"; }
KontaktDAO.java
package org.mano.jdbc.examples; import java.sql.*; import java.util.ArrayList; import java.util.List; public class ContactDAO implements DAO { private ontactPerson createContactPerson(ResultSet rs) { ContactPerson p = new ContactPerson(); try { p.setId(rs.getInt("id")); p.setName(rs.getString("name")); p.setNickName(rs.getString("nick_name")); p.setAddress(rs.getString("address")); p.setHomePhone(rs.getString("home_phone")); p.setWorkPhone(rs.getString("work_phone")); p.setCellPhone(rs.getString("cell_phone")); p.setEmail(rs.getString("email")); p.setBirthDate(rs.getDate("birthday")); p.setWebSite(rs.getString("web_site")); p.setProfession(rs.getString("profession")); } catch (SQLException ex) { } return p; } public List<ContactPerson> getContacts() { String sql = "Select * from contact order by name"; List<ContactPerson> list = new ArrayList<>(); try { Class.forName(DRIVER); Connection con = DriverManager.getConnection (DB_URL, USER, PASS); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { ContactPerson p = createContactPerson(rs); list.add(p); } rs.close(); con.close(); } catch (ClassNotFoundException | SQLException ex) { } return list; } public List<ContactPerson> getContactsForName(String name) { String sql = "Select * from contact where name like '%" + name + "%'"; List<ContactPerson> list = new ArrayList<>(); try { Class.forName(DRIVER); Connection con = DriverManager.getConnection (DB_URL, USER, PASS); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { ContactPerson p = createContactPerson(rs); list.add(p); } rs.close(); con.close(); } catch (ClassNotFoundException | SQLException ex) { } return list; } }
Interfejs GUI JavaFX:ContactBrowser
W aplikacji JavaFX o nazwie ContactBrowser , wszystkie kontrolki konfigurujemy programowo. Można to również ustawić za pomocą narzędzi FXML lub narzędzi do budowania, takich jak Scene Builder. Ale, zdaniem skryby, można ich użyć, gdy zdobędzie się wystarczające doświadczenie w tym, co kryje się za kulisami JavaFX. GUI to przede wszystkim współdziałanie trzech elementów sterujących, takich jak TextField (pole wyszukiwania ), ListView (listView ) i TableView (kontaktTableView ). Kod nie wymaga wyjaśnień, z komentarzami podanymi w odpowiednich miejscach. Wyrażenie lambda jest używane wszędzie tam, gdzie ma to zastosowanie, aby zachować zwięzły kod. W razie potrzeby zapoznaj się z dokumentacją JavaFX API.
package org.mano.jdbc.examples; import javafx.application.Application; import javafx.beans.value.*; import javafx.collections.*; import javafx.collections.transformation.*; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.*; import javafx.scene.paint.Color; import javafx.stage.Stage; public class ContactBrowser extends Application { // List of contact table properties private String[] propertyName = {"id", "name", "nickName", "address", "homePhone", "workPhone", "cellPhone", "email", "birthDate", "webSite", "profession"}; private String[] propertyLabel = {"ID", "Name", "Nick Name", "Address", "Home Phone", "Work Phone", "Cell Phone", "Email", "Birth Date", "Website", "Profession"}; private ContactDAO contact = new ContactDAO(); private final GridPane gridPane = new GridPane(); private final Label lblName = new Label("Search by Name"); private final TextField searchField = new TextField(); private ObservableList<ContactPerson> observableNames; private FilteredList<ContactPerson> filteredData; private SortedList<ContactPerson> sortedData; private final ListView<ContactPerson> listView; TableView<ContactPerson> contactTableView = new TableView<>(); public ContactBrowser2() { lblName.setTextFill(Color.web("#0076a3")); observableNames = FXCollections.observableArrayList (contact.getContacts()); filteredData = new FilteredList<> (observableNames, p -> true); sortedData = new SortedList<>(filteredData); listView = new ListView<>(sortedData); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Address Book"); primaryStage.setMaximized(true); BorderPane borderPane = new BorderPane(); Scene scene = new Scene(borderPane,650,400,true); gridPane.setPadding(new Insets(10)); gridPane.setHgap(5); gridPane.setVgap(5); gridPane.add(lblName, 0, 0); gridPane.add(searchField, 0, 1); // Search TextField event handling searchField.textProperty() .addListener((observable, oldValue, newValue) -> filteredData.setPredicate(str -> { if (newValue == null || newValue.isEmpty()) return true; if (str.getName().toLowerCase().contains (newValue.toLowerCase())) return true; return false; })); listView.getSelectionModel().setSelectionMode (SelectionMode.SINGLE); listView.setPrefHeight(Integer.MAX_VALUE); // Sets a new cell factory to use in the ListView. // This throws away all old list cells and new ListCells // created with the new cell factory. listView.setCellFactory(listView-> { Tooltip tooltip = new Tooltip(); ListCell<ContactPerson> cell = new ListCell<ContactPerson>() { @Override public voidupdateItem(ContactPerson contactPerson, Boolean empty) { super.updateItem(contactPerson, empty); if (contactPerson != null) { setText(contactPerson.getName()); tooltip.setText(contactPerson.getNickName()); setTooltip(tooltip); } else setText(null); } }; return cell; }); gridPane.add(listView, 0, 2); // Create and initializing TableView ObservableList<ContactPerson> contactPeopleList = FXCollections.observableArrayList(); contactTableView.setItems(contactPeopleList); contactTableView.setColumnResizePolicy( TableView.CONSTRAINED_RESIZE_POLICY); for (int i = 0; i < propertyLabel.length; i++) { TableColumn<ContactPerson, Object> col = new TableColumn<>(propertyLabel[i]); col.setCellValueFactory(new PropertyValueFactory<>(propertyName[i])); contactTableView.getColumns().add(col); } borderPane.setCenter(contactTableView) borderPane.setLeft(gridPane); // TableView will populate from the contactPeopleList // contactPeopleList will have value according to the // item selected in the ListView listView.getSelectionModel() .selectedItemProperty() .addListener(new ChangeListener<ContactPerson>() { @Override public void changed( ObservableValue<? extends ContactPerson> observable, ContactPerson oldValue, ContactPerson newValue) { if (observable != null && observable.getValue() != null) { contactPeopleList.clear(); contactPeopleList.addAll( contact.getContactsForName (newValue.getName())); } } }); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch (args); } }
Wyjście
Rysunek 1: Wyjście kodu
Wniosek
Aplikacja JDBC z JavaFX zasadniczo oznacza, że framework JavaFX GUI był używany jako frontowy silnik programistyczny, a JDBC był używany do interakcji z wewnętrzną bazą danych. Mogą być różnych typów z N liczba zdefiniowanych w nich funkcjonalności. Podstawą jest aplikacja CRUD. Wdrożyliśmy część operacji wyszukiwania i wyświetlania. Oto, co możesz zrobić, aby go rozszerzyć:zaimplementuj Utwórz , Usuń i Aktualizacja operacje; możesz także dodawać nazwy z obrazami w ListView . Udanego kodowania 😉