sql >> Databasteknik >  >> RDS >> Database

Arbeta med JavaFX UI och JDBC Applications

Eftersom JavaFX vinner mark som Javas de-facto GUI-ramverk kommer det att ersätta Swing förr eller senare. JavaFX UI och JDBC kan vara en effektiv kombination när du skapar en databasdriven applikation, särskilt i ett offline eller inbäddat system. Den här artikeln visar i huvudsak hur detta kan göras med ett exempelscenario.

En översikt över JDBC-applikationer

Utvecklingen av Java GUI-ramverket vilar nu på JavaFX-biblioteket. Det ger ett kraftfullt men ändå flexibelt alternativ till GUI-utveckling, i motsats till dess befintliga Swing- och AWT-ramverk. JavaFX tillhandahåller ett stort array eller kontroller och komponenter som hjälper till att bygga ett GUI-gränssnitt snabbt och effektivt. Det är mycket enkelt att utveckla en skrivbordsapplikation som interagerar med back-end-databasen. En JDBC (Java Database Connectivity) applikationen har i första hand ett back-end databassystem som MySQL, Derby, Oracle eller någon annan databas. Java-kod skrivs för att hämta poster från en eller flera tabeller i databasen. SQL (Structured Query Language) frågor avfyras från Java-kod och skickas till databasmotorn för bearbetning. JDBC-drivrutinen fungerar som en mellanhand mellan Java-programmet och databasen och tolkar mängden information fram och tillbaka, så att både den omatchade parten, såsom databasen, och Java-programmet kan förenas med en fungerande lösning. Databasen har absolut ingen aning om Java-kod, dess syntaxer eller något om det. Den förstår helt enkelt SQL och kan bara kommunicera med den. Java, å andra sidan, är en OOP (Object Oriented Programming) språk och har ingen aning om SQL eller dess syntaxer heller. För att möjliggöra kommunikation, tillhandahåller databasleverantören inbyggda drivrutiner tillsammans med databasen. Detta kallas JDBC-drivrutinen. Observera att det finns fyra typer av drivrutiner tillgängliga. De kallas i vardagsspråk Typ-1, Type-2, Type-3 och Type-4 förare. De inbyggda drivrutinerna är typ 4-drivrutiner och används oftast. De är också mer effektiva än andra typer. Ett Java-program kan inkludera dessa JDBC-drivrutiner som ett externt bibliotek i Java-programmet, eftersom de vanligtvis finns i JAR-arkivfiler.

JavaFX in i scenen

Varje databasapplikation kräver ett gränssnitt så att användaren kan interagera med databasinformationen. Bättre, om det är ett GUI-gränssnitt där vi inte behöver böja oss ner till ett lågnivå, skrämmande kommandogränssnitt utan får vad vi vill ha med ett klick på en knapp. I den här aspekten kan JavaFX med JDBC vara en mördande kombination eftersom den har ett stort antal visuellt spännande GUI-komponenter som kan användas för att representera databasposter på ett mer meningsfullt sätt. Till exempel kan poster visas i tabellform med TableView kontrollera. Eller så kan vi skapa ett formulär för att lägga till nya poster i databastabellen. Datainmatningen av användaren kan verifieras genom Java-kod innan den skickas till databasen. Back-end-databasmotorn får en paus från att validera data och avstannat bearbetning på grund av ett inmatningsfel. Dessutom kan slutanvändaren vara en lekman med liten eller ingen aning om begränsningarna för indata. Detta görs helst när ett inmatningsformulär skapas med TextField , Etikett , ComboBox och ListView kontroller i JavaFX. Händelserna som genereras av Knapp och andra kontroller hanteras på ett sådant sätt att användaren är bekväm när han interagerar med GUI-gränssnittet.

In i ett exempelscenario

I följande illustrerade exempel implementerar vi en ListView sökoperation genom att mata in text i ett Textfält . Det valda objektet i listvyn hämtas därefter från backend-databasen och visas i TableView kontrollera. Så det är i första hand en app för hämtning och visning. Andra databasoperationer – såsom infogning, radering och uppdatering av poster – implementeras inte på grund av storleksbegränsningar. Det skulle vara en trevlig övning att implementera dem själv.

Så innan vi börjar måste vi skapa en databastabell och ett Java-projekt. Vi kommer att använda MySQL som back-end-databasen; du kan välja vilken som helst annan men se till att inkludera lämpliga drivrutiner i din pom.xml fil. Här är lite av SQL-koden för att skapa tabellen, infoga lite dummydata och några andra 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>

Låt oss nu skapa ett domänobjekt som vi kommer att använda i båda ListView och TableView eftersom de båda är släkt, som sagts i vårt fall. TableView kommer att innehålla en observerbar lista över personer (ContactPerson ) baserat på den valda personens namn från ListView kontrollera. Vi har också ett Textfält för att göra en snabb sökning av objekt (Kontaktperson namn) som finns i ListView . Vid val av ett specifikt objekt från ListView , en SQL-fråga aktiveras och relevanta poster hämtas för att fylla i TableView kontrollera därefter.

Domänobjekt:ContactPerson

Kontaktpersonen klass är inget annat än POJO-representationen av kontakten tabellattribut. Den innehåller konstruktorn och enkla 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;
   }
}

Dataåtkomstobjekt:ContactDAO

ContactDAO är en dataåtkomstobjektklass som primärt inkluderar databasåtkomstoperation. Den implementerar DAO gränssnitt. Det här gränssnittet kanske inte är viktigt i vårt exempel men kan komma till god användning om applikationen utökas med fler dataåtkomstobjektklasser. Här, DAO gränssnittet innehåller en anslutningssträng, drivrutin och användarnamn och lösenord för att komma åt 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änssnitt:ContactBrowser

I JavaFX-applikationen som heter ContactBrowser , ställer vi in ​​alla kontroller programmatiskt. Detta kan också ställas in med hjälp av FXML eller byggverktyg som Scene Builder. Men enligt skribentens åsikt kan de användas när man har fått tillräckligt med erfarenhet av vad som händer bakom kulisserna i JavaFX. Det grafiska gränssnittet är i första hand ett samspel av tre kontroller, till exempel ett TextField (sökfält ), en ListView (listView ), och TableView (contactTableView ). Koden är självförklarande, med kommentarer på lämpliga platser. Lambda-uttryck används där det är tillämpligt för att hålla koden kortfattad. Se JavaFX API-dokumentationen där det behövs.

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

Utdata


Figur 1: Kodutgång

Slutsats

En JDBC-applikation med JavaFX betyder i huvudsak att JavaFX GUI-ramverket användes som front-end-utvecklingsmotorn och JDBC användes för back-end-databasinteraktionen. De kan vara av olika typer med N antal funktioner definierade i dem. Det grundläggande är CRUD-applikationen. Vi har implementerat en del av sök- och visningsfunktionen. Här är vad du kan göra för att utöka den:implementera Skapa , Ta bort och Uppdatera operationer; Du kan också lägga till namn med bilder i ListView . Glad kodning 😉


  1. Hur skapar man en SQL Server-funktion för att sammanfoga flera rader från en underfråga till ett enda avgränsat fält?

  2. Hur kan jag använda Date Datatype i sql-servern?

  3. MySQL skapa vy, ersätt vy och släpp vy uttalanden med exempel

  4. PostgreSQL-accent + skiftlägesokänslig sökning