Como o JavaFX está ganhando terreno como a estrutura GUI de fato do Java, ele substituirá o Swing mais cedo ou mais tarde. JavaFX UI e JDBC podem ser uma combinação eficaz ao criar um aplicativo orientado a banco de dados, especialmente em um sistema offline ou incorporado. Este artigo mostra essencialmente como isso pode ser feito com um cenário de exemplo.
Visão geral do aplicativo JDBC
A evolução da estrutura Java GUI agora se baseia na biblioteca JavaFX. Ele fornece uma alternativa poderosa e flexível ao desenvolvimento de GUI, em contraste com sua estrutura Swing e AWT existente. JavaFX fornece uma grande variedade de controles e componentes que ajudam na construção de uma interface GUI de forma rápida e eficaz. É muito fácil desenvolver um aplicativo de desktop que interage com o banco de dados back-end. A JDBC (Java Database Connectivity) aplicativo tem principalmente um sistema de banco de dados back-end, como MySQL, Derby, Oracle ou qualquer outro banco de dados. O código Java é escrito para buscar registros de uma ou mais tabelas no banco de dados. A SQL (Linguagem de Consulta Estruturada) as consultas são disparadas do código Java e enviadas ao mecanismo de banco de dados para processamento. O driver JDBC atua como um intermediário entre o programa Java e o banco de dados e interpreta a enxurrada de informações de um lado para outro, de modo que tanto a parte incomparável, como o banco de dados, quanto o programa Java possam se reconciliar em uma solução viável. O banco de dados não tem absolutamente nenhuma ideia sobre o código Java, suas sintaxes ou qualquer coisa sobre ele. Ele simplesmente entende SQL e pode se comunicar apenas com ele. Java, por outro lado, é uma OOP (Programação Orientada a Objetos) linguagem e também não tem idéia sobre SQL ou suas sintaxes. Para possibilitar a comunicação, o fornecedor do banco de dados fornece drivers nativos junto com o banco de dados. Isso é chamado de driver JDBC. Observe que existem quatro tipos de drivers disponíveis. Eles são coloquialmente chamados de drivers Tipo-1, Tipo-2, Tipo-3 e Tipo-4. Os drivers nativos são drivers Type-4 e são os mais usados. Eles também são mais eficientes do que outros tipos. Um programa Java pode incluir esses drivers JDBC como uma biblioteca externa no programa Java, pois eles geralmente vêm em arquivos JAR.
JavaFX na cena
Todo aplicativo de banco de dados requer uma interface para que o usuário possa interagir com as informações do banco de dados. Melhor, se for uma interface GUI onde não temos que nos rebaixar a uma interface de comando de baixo nível e intimidadora, mas obter o que queremos com o clique de um botão. Nesse aspecto, JavaFX com JDBC pode ser uma combinação matadora porque possui vários componentes de GUI visualmente interessantes que podem ser usados para representar registros de banco de dados de maneira mais significativa. Por exemplo, os registros podem ser exibidos em um formulário tabular com o TableView ao controle. Ou podemos criar um formulário para adicionar novos registros na tabela do banco de dados. Os dados inseridos pelo usuário podem ser verificados através do código Java antes de serem enviados ao banco de dados. O mecanismo de banco de dados de back-end tem uma pausa na validação de dados e no processamento interrompido devido a um erro de entrada. Além disso, o usuário final pode ser um leigo com pouca ou nenhuma ideia sobre as restrições dos dados de entrada. Isso é feito idealmente quando um formulário de entrada é criado com TextField , Etiqueta , ComboBox e ListView controles em JavaFX. Os eventos gerados pelo Botão e outros controles são manipulados de forma que o usuário fique à vontade ao interagir com a interface GUI.
Em um cenário de exemplo
No exemplo ilustrado a seguir, implementaremos um ListView operação de pesquisa por texto de entrada em um TextField . O item selecionado no ListView é obtido de acordo com o banco de dados back-end e exibido no TableView ao controle. Portanto, é principalmente um tipo de aplicativo de busca e exibição. Outras operações de banco de dados, como inserção, exclusão e atualização de registros, não são implementadas devido a restrições de tamanho. Seria um bom exercício para implementá-los você mesmo.
Portanto, antes de começarmos, devemos criar uma tabela de banco de dados e um projeto Java. Usaremos o MySQL como banco de dados back-end; você pode escolher qualquer outro, mas certifique-se de incluir os drivers apropriados em seu pom.xml Arquivo. Aqui está um pouco do código SQL para criar a tabela, inserir alguns dados fictícios e algumas outras operações.
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>
Agora, vamos criar um objeto de domínio que usaremos tanto em ListView e TableView porque ambos estão relacionados, como afirmado no nosso caso. O TableView conterá uma lista observável de pessoas (ContactPerson ) com base no nome da pessoa selecionada no ListView ao controle. Também temos um TextField para fazer uma pesquisa rápida de itens (ContactPerson name) contido no ListView . Na seleção de um item específico do ListView , uma consulta SQL é acionada e os registros relevantes são buscados para preencher o TableView controle em conformidade.
Objeto de domínio:ContactPerson
A Pessoa de contato classe nada mais é do que a representação POJO do contato atributos da tabela. Ele contém o construtor e o simples getter-setter métodos.
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; } }
Objeto de acesso a dados:ContactDAO
O ContatoDAO é uma classe de objeto de acesso a dados que inclui principalmente a operação de acesso ao banco de dados. Ele implementa o DAO interface. Essa interface pode não ser importante em nosso exemplo, mas pode ser bem usada se o aplicativo for estendido com mais classes de objetos de acesso a dados. Aqui, o DAO interface inclui uma cadeia de conexão, driver e nome de usuário e senha para acessar o banco de dados 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"; }
ContatoDAO.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; } }
Interface GUI JavaFX:ContactBrowser
No aplicativo JavaFX chamado ContactBrowser , configuramos todos os controles programaticamente. Isso também pode ser definido usando FXML ou ferramentas de utilitário de construção, como o Scene Builder. Mas, na opinião do escriba, eles podem ser usados uma vez que se tenha adquirido experiência suficiente sobre o que acontece nos bastidores do JavaFX. A GUI é basicamente uma interação de três controles, como um TextField (campo de pesquisa ), uma ListView (listView ) e TableView (contactTableView ). O código é autoexplicativo, com comentários nos locais apropriados. A expressão lambda é usada sempre que aplicável para manter o código conciso. Consulte a documentação da API JavaFX sempre que necessário.
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); } }
Saída
Figura 1: Saída de código
Conclusão
Um aplicativo JDBC com JavaFX significa essencialmente que a estrutura JavaFX GUI foi usada como o mecanismo de desenvolvimento de front-end e JDBC foi usado para a interação de banco de dados de back-end. Eles podem ser de variedades de tipos com N número de funcionalidades neles definidas. O básico é o aplicativo CRUD. Implementamos uma parte da operação de pesquisa e exibição. Aqui está o que você pode fazer para estendê-lo:implemente Criar , Excluir e Atualizar operações; além disso, você pode adicionar nomes com imagens no ListView . Boa codificação 😉