sql >> Database teknologi >  >> RDS >> Database

Arbejde med JavaFX UI og JDBC Applications

Fordi JavaFX vinder terræn som Javas de-facto GUI-ramme, kommer det til at erstatte Swing før eller siden. JavaFX UI og JDBC kan være en effektiv kombination, når du opretter en databasedrevet applikation, især i et offline eller indlejret system. Denne artikel viser i det væsentlige, hvordan dette kan gøres med et eksempelscenarie.

En JDBC-applikationsoversigt

Udviklingen af ​​Java GUI-rammerne hviler nu på JavaFX-biblioteket. Det giver et kraftfuldt, men fleksibelt alternativ til GUI-udvikling, i modsætning til dets eksisterende Swing- og AWT-ramme. JavaFX leverer et stort array eller kontroller og komponenter, der hjælper med at opbygge en GUI-grænseflade hurtigt og effektivt. Det er meget nemt at udvikle en desktopapplikation, der interagerer med backend-databasen. En JDBC (Java Database Connectivity) applikationen har primært et back-end databasesystem såsom MySQL, Derby, Oracle eller enhver anden database. Java-kode er skrevet for at hente poster fra en eller flere tabeller i databasen. SQL (Structured Query Language) forespørgsler affyres fra Java-kode og sendes til databasemotoren til behandling. JDBC-driveren fungerer som et mellemled mellem Java-programmet og databasen og fortolker mængden af ​​information frem og tilbage, så både den umatchede part, såsom databasen, og Java-programmet kan forene sig til en brugbar løsning. Databasen har absolut ingen idé om Java-kode, dens syntakser eller noget om det. Det forstår simpelthen SQL og kan kun kommunikere med det. Java, på den anden side, er en OOP (Object Oriented Programming) sprog og har heller ingen idé om SQL eller dets syntakser. For at gøre kommunikation mulig, leverer databaseleverandøren native drivere sammen med databasen. Dette kaldes JDBC-driveren. Bemærk, at der er fire typer drivere tilgængelige. De kaldes i daglig tale Type-1, Type-2, Type-3 og Type-4-drivere. De oprindelige drivere er Type-4-drivere og er mest almindeligt anvendte. De er også mere effektive end andre typer. Et Java-program kan inkludere disse JDBC-drivere som et eksternt bibliotek i Java-programmet, da de almindeligvis findes i JAR-arkivfiler.

JavaFX ind i scenen

Hver databaseapplikation kræver en grænseflade, så brugeren kan interagere med databaseinformationen. Bedre, hvis det er en GUI-grænseflade, hvor vi ikke behøver at bøje os ned til en skræmmende kommandogrænseflade på lavt niveau, men får det, vi ønsker med et klik på en knap. I dette aspekt kan JavaFX med JDBC være en dræber kombination, fordi den har en lang række visuelt spændende GUI-komponenter, der kan bruges til at repræsentere databaseposter på en mere meningsfuld måde. For eksempel kan poster vises i tabelform med Tabelvisning styring. Eller vi kan oprette en formular for at tilføje nye poster til databasetabellen. Datainput af brugeren kan verificeres gennem Java-kode, før den sendes til databasen. Backend-databasemotoren får et pusterum fra at validere data og stoppet behandling på grund af en inputfejl. Desuden kan slutbrugeren være en lægmand med ringe eller ingen idé om begrænsningerne for inputdata. Dette gøres ideelt, når en inputformular oprettes med TextField , Etiket , ComboBox og ListView kontroller i JavaFX. Hændelser genereret af Knap og andre kontroller håndteres på en sådan måde, at brugeren er tryg, mens han interagerer med GUI-grænsefladen.

Ind i et eksempelscenarie

I det følgende illustrerede eksempel implementerer vi en ListView søgeoperation ved at indtaste tekst i et Tekstfelt . Det valgte element i ListView hentes tilsvarende fra back-end-databasen og vises i TableView styring. Så det er primært en app til at hente og vise. Andre databaseoperationer – såsom indsættelse, sletning og opdatering af poster – implementeres ikke på grund af størrelsesbegrænsninger. Det ville være en god øvelse at implementere dem selv.

Så før vi begynder, skal vi oprette en databasetabel og et Java-projekt. Vi bruger MySQL som back-end databasen; du kan vælge en hvilken som helst anden, men sørg for at inkludere passende drivere i din pom.xml fil. Her er noget af SQL-koden til at oprette tabellen, indsætte nogle dummy-data og nogle andre operationer.

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>

Lad os nu oprette et domæneobjekt, som vi vil bruge i både ListView og Tabelvisning fordi de begge er beslægtede, som anført i vores sag. Tabelvisning vil indeholde en observerbar liste over personer (ContactPerson ) baseret på den valgte persons navn fra ListView styring. Vi har også et TextField for at foretage en hurtig søgning efter emner (Kontaktperson navn) indeholdt i ListView . Ved valg af et specifikt element fra ListView , udløses en SQL-forespørgsel, og relevante poster hentes for at udfylde TableView kontrollere i overensstemmelse hermed.

Domæneobjekt:Kontaktperson

Kontaktpersonen klasse er intet andet end POJO-repræsentationen af ​​kontakten tabel attributter. Den indeholder konstruktøren og den simple getter-setter metoder.

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

Dataadgangsobjekt:ContactDAO

ContactDAO er en dataadgangsobjektklasse, der primært inkluderer databaseadgangsoperation. Den implementerer DAO interface. Denne grænseflade er muligvis ikke vigtig i vores eksempel, men den kan bruges, hvis applikationen udvides med flere dataadgangsobjektklasser. Her er DAO grænsefladen inkluderer en forbindelsesstreng, driver og brugernavn og adgangskode for at få adgang til MySQL-databasen.

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

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

JavaFX GUI-grænseflade:ContactBrowser

I JavaFX-applikationen med navnet ContactBrowser , sætter vi alle kontroller op programmatisk. Dette kan også indstilles ved hjælp af FXML eller builder-værktøjer såsom Scene Builder. Men efter skribentens mening kan de bruges, når man har fået nok erfaring med, hvad der foregår bag kulisserne i JavaFX. GUI'en er primært et samspil mellem tre kontroller, såsom et TextField (søgefelt ), en ListView (listevisning ), og Tabelvisning (contactTableView ). Koden er selvforklarende, med kommentarer givet på passende steder. Lambda-udtryk bruges, hvor det er relevant, for at holde koden kortfattet. Se JavaFX API-dokumentationen, hvor det er nødvendigt.

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

Output


Figur 1: Kodeoutput

Konklusion

En JDBC-applikation med JavaFX betyder i det væsentlige, at JavaFX GUI-rammerne blev brugt som front-end-udviklingsmotoren, og JDBC blev brugt til back-end-databaseinteraktionen. De kan være af forskellige typer med N antallet af funktioner defineret i dem. Det grundlæggende er CRUD-applikationen. Vi har implementeret en del af søge- og visningsfunktionen. Her er, hvad du kan gøre for at udvide det:implementer Opret , Slet og Opdater operationer; Du kan også tilføje navne med billeder i ListView . God kodning 😉


  1. Brug af tråde til at lave databaseanmodninger

  2. Sådan tilføjer du kommentarer til en tabel i Oracle SQL Developer?

  3. Udbyderen er ikke kompatibel med versionen af ​​Oracle-klientfejl ved brug af Oracle.DataClient

  4. Konverter 'datetime offset' til 'date' i SQL Server (T-SQL-eksempler)