sql >> Base de Datos >  >> RDS >> Database

Trabajar con la interfaz de usuario JavaFX y las aplicaciones JDBC

Debido a que JavaFX está ganando terreno como el marco GUI de facto de Java, tarde o temprano reemplazará a Swing. JavaFX UI y JDBC pueden ser una combinación eficaz al crear una aplicación basada en bases de datos, especialmente en un sistema fuera de línea o integrado. Este artículo muestra esencialmente cómo se puede hacer esto con un escenario de ejemplo.

Una descripción general de la aplicación JDBC

La evolución del marco de la GUI de Java ahora se basa en la biblioteca JavaFX. Proporciona una alternativa poderosa pero flexible al desarrollo de GUI, en contraste con su marco Swing y AWT existente. JavaFX proporciona una gran variedad de controles y componentes que ayudan a construir una interfaz GUI de manera rápida y efectiva. Es muy fácil desarrollar una aplicación de escritorio que interactúe con la base de datos de back-end. Un JDBC (conectividad de base de datos Java) La aplicación tiene principalmente un sistema de base de datos back-end como MySQL, Derby, Oracle o cualquier otra base de datos. El código Java se escribe para obtener registros de una o más tablas en la base de datos. El SQL (lenguaje de consulta estructurado) las consultas se activan desde el código Java y se envían al motor de la base de datos para su procesamiento. El controlador JDBC actúa como intermediario entre el programa Java y la base de datos e interpreta la ráfaga de información de un lado a otro, de modo que tanto la parte no coincidente, como la base de datos, y el programa Java puedan reconciliarse en una solución viable. La base de datos no tiene ni idea sobre el código Java, su sintaxis ni nada al respecto. Simplemente entiende SQL y solo puede comunicarse con él. Java, por otro lado, es un POO (Programación Orientada a Objetos) lenguaje y tampoco tiene idea sobre SQL o sus sintaxis. Para hacer posible la comunicación, el proveedor de la base de datos proporciona controladores nativos junto con la base de datos. Esto se llama el controlador JDBC. Tenga en cuenta que hay cuatro tipos de controladores disponibles. Se denominan coloquialmente controladores de tipo 1, tipo 2, tipo 3 y tipo 4. Los controladores nativos son controladores de tipo 4 y son los más utilizados. También son más eficientes que otros tipos. Un programa Java puede incluir estos controladores JDBC como una biblioteca externa en el programa Java, ya que comúnmente vienen en archivos JAR.

JavaFX en la escena

Cada aplicación de base de datos requiere una interfaz para que el usuario pueda interactuar con la información de la base de datos. Mejor, si se trata de una interfaz GUI en la que no tenemos que rebajarnos a una interfaz de comandos intimidante de bajo nivel, sino obtener lo que queremos con un clic de un botón. En este aspecto, JavaFX con JDBC puede ser una excelente combinación porque tiene una gran cantidad de componentes GUI visualmente interesantes que se pueden usar para representar registros de bases de datos de una manera más significativa. Por ejemplo, los registros se pueden mostrar en forma tabular con TableView control. O bien, podemos crear un formulario para agregar nuevos registros a la tabla de la base de datos. La entrada de datos por parte del usuario puede verificarse a través del código Java antes de enviarse a la base de datos. El motor de base de datos de back-end obtiene un respiro de la validación de datos y el procesamiento estancado debido a un error de entrada. Además, el usuario final puede ser un profano con poca o ninguna idea sobre las limitaciones de los datos de entrada. Esto se hace idealmente cuando se crea un formulario de entrada con TextField , Etiqueta , Cuadro combinado y Vista de lista controles en JavaFX. Los eventos generados por Button y otros controles se manejan de tal manera que el usuario se siente cómodo mientras interactúa con la interfaz GUI.

En un escenario de ejemplo

En el siguiente ejemplo ilustrado, implementaremos un ListView operación de búsqueda por texto de entrada en un TextField . El elemento seleccionado en ListView se obtiene en consecuencia de la base de datos de back-end y se muestra en TableView control. Por lo tanto, es principalmente un tipo de aplicación de búsqueda y visualización. Otras operaciones de la base de datos, como la inserción, eliminación y actualización de registros, no se implementan debido a restricciones de tamaño. Sería un buen ejercicio implementarlos tú mismo.

Entonces, antes de comenzar, debemos crear una tabla de base de datos y un proyecto Java. Usaremos MySQL como la base de datos de back-end; puede elegir cualquier otro, pero asegúrese de incluir los controladores apropiados en su pom.xml expediente. Aquí hay parte del código SQL para crear la tabla, insertar algunos datos ficticios y algunas otras operaciones.

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>

Ahora, creemos un objeto de dominio que usaremos tanto en ListView y TableView porque ambos están relacionados, como se afirma en nuestro caso. El TableView contendrá una lista observable de personas (Persona de contacto ) basado en el nombre de la persona seleccionada de ListView control. También tenemos un TextField para realizar una búsqueda rápida de artículos (ContactPerson nombre) contenido en el ListView . Al seleccionar un elemento específico de ListView , se activa una consulta SQL y se recuperan los registros relevantes para completar el TableView controlar en consecuencia.

Objeto de dominio:Persona de contacto

La Persona de contacto la clase no es más que la representación POJO del contacto atributos de la tabla. Contiene el constructor y getter-setter simple 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 acceso a datos:ContactDAO

El ContactoDAO es una clase de objeto de acceso a datos que incluye principalmente la operación de acceso a la base de datos. Implementa el DAO interfaz. Esta interfaz puede no ser importante en nuestro ejemplo, pero puede ser útil si la aplicación se amplía con más clases de objetos de acceso a datos. Aquí, el DAO La interfaz incluye una cadena de conexión, un controlador y un nombre de usuario y contraseña para acceder a la base de datos 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";
}

ContactoDAO.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;
   }
}

Interfaz GUI de JavaFX:ContactBrowser

En la aplicación JavaFX llamada ContactBrowser , configuramos todos los controles programáticamente. Esto también se puede configurar usando FXML o herramientas de utilidad de construcción como Scene Builder. Pero, en opinión del escriba, se pueden usar una vez que uno haya adquirido suficiente experiencia sobre lo que sucede detrás de escena en JavaFX. La GUI es principalmente una interacción de tres controles, como un TextField (campo de búsqueda ), un Vista de lista (vista de lista ) y TableView (contactTableView ). El código se explica por sí mismo, con comentarios en los lugares apropiados. La expresión lambda se usa siempre que sea aplicable para mantener el código breve. Consulte la documentación de la API de JavaFX cuando sea necesario.

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);
   }
}

Salida


Figura 1: Salida de código

Conclusión

Una aplicación JDBC con JavaFX esencialmente significa que el marco de la GUI de JavaFX se usó como motor de desarrollo frontal y JDBC se usó para la interacción de la base de datos de back-end. Pueden ser de variedades de tipos con N número de funcionalidades definidas en ellos. La básica es la aplicación CRUD. Hemos implementado una parte de la operación de búsqueda y visualización. Esto es lo que puede hacer para extenderlo:implementar Crear , Eliminar y Actualizar operaciones; también, puede agregar nombres con imágenes en el ListView . Feliz codificación 😉