JavaFXはJavaの事実上のGUIフレームワークとして定着しつつあるため、遅かれ早かれSwingに取って代わる予定です。 JavaFX UIとJDBCは、特にオフラインまたは組み込みシステムでデータベース駆動型アプリケーションを作成する場合に効果的な組み合わせになります。この記事では、基本的に、シナリオ例を使用してこれを行う方法を示します。
JDBCアプリケーションの概要
Java GUIフレームワークの進化は、現在JavaFXライブラリに依存しています。既存のSwingおよびAWTフレームワークとは対照的に、GUI開発に代わる強力で柔軟な代替手段を提供します。 JavaFXは、GUIインターフェースを迅速かつ効果的に構築するのに役立つ大規模な配列またはコントロールとコンポーネントを提供します。バックエンドデータベースと対話するデスクトップアプリケーションを開発するのは非常に簡単です。 JDBC(Java Database Connectivity) アプリケーションには、主にMySQL、Derby、Oracle、またはその他のデータベースなどのバックエンドデータベースシステムがあります。 Javaコードは、データベース内の1つ以上のテーブルからレコードをフェッチするように記述されています。 SQL(構造化クエリ言語) クエリはJavaコードから実行され、処理のためにデータベースエンジンに送信されます。 JDBCドライバーは、Javaプログラムとデータベースの間の仲介役として機能し、情報のボレーを前後に解釈するため、データベースなどの比類のないパーティとJavaプログラムの両方が実行可能なソリューションに調整できます。データベースは、Javaコード、その構文、またはそれについて何もまったく知りません。 SQLを理解するだけで、SQLとのみ通信できます。一方、Javaは OOP(オブジェクト指向プログラミング) 言語であり、SQLやその構文についても何も知りません。通信を可能にするために、データベースベンダーはデータベースとともにネイティブドライバーを提供しています。これはJDBCドライバーと呼ばれます。使用可能なドライバーには4つのタイプがあることに注意してください。これらは、口語的にType-1、Type-2、Type-3、およびType-4ドライバーと呼ばれます。ネイティブドライバーはタイプ4ドライバーであり、最も一般的に使用されます。また、他のタイプよりも効率的です。 Javaプログラムは、これらのJDBCドライバーを外部ライブラリとしてJavaプログラムに含めることができます。これは、通常、JARアーカイブファイルで提供されるためです。
シーンへのJavaFX
すべてのデータベースアプリケーションには、ユーザーがデータベース情報を操作できるようにするためのインターフェイスが必要です。より良いのは、それが低レベルの威圧的なコマンドインターフェイスに身をかがめる必要がなく、ボタンをクリックするだけで必要なものを取得できるGUIインターフェイスの場合です。この点で、JavaFXとJDBCは、データベースレコードをより意味のある方法で表現するために使用できる、視覚的にエキサイティングなGUIコンポーネントを多数備えているため、キラーな組み合わせになる可能性があります。たとえば、レコードは TableViewを使用して表形式で表示できます。 コントロール。または、データベーステーブルに新しいレコードを追加するためのフォームを作成することもできます。ユーザーが入力したデータは、データベースに送信する前にJavaコードで確認できます。バックエンドデータベースエンジンは、データの検証と入力エラーによる処理の停止から休憩を取ります。さらに、エンドユーザーは、入力データの制約についてほとんどまたはまったく理解していない素人である可能性があります。これは、入力フォームが TextFieldで作成されるときに理想的に行われます。 、ラベル 、コンボボックス 、および ListView JavaFXのコントロール。 ボタンによって生成されたイベント およびその他のコントロールは、ユーザーがGUIインターフェイスを操作しているときに安心できるように処理されます。
シナリオ例へ
次の図の例では、 ListViewを実装します。 TextFieldの入力テキストによる検索操作 。 ListViewで選択されたアイテムは、それに応じてバックエンドデータベースからフェッチされ、 TableViewに表示されます。 コントロール。したがって、これは主にフェッチと表示の種類のアプリケーションです。レコードの挿入、削除、更新などの他のデータベース操作は、サイズの制約のために実装されていません。それらを自分で実装するのは良い練習になるでしょう。
したがって、始める前に、データベーステーブルとJavaプロジェクトを作成する必要があります。 MySQLをバックエンドデータベースとして使用します。他のものを選択することもできますが、 pom.xmlに適切なドライバーを含めるようにしてください。 ファイル。これは、テーブルを作成し、ダミーデータを挿入し、その他の操作を行うためのSQLコードの一部です。
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>
それでは、両方の ListViewで使用するドメインオブジェクトを作成しましょう。 およびTableView 私たちの場合に述べたように、それらは両方とも関連しているからです。 TableView 観察可能な人々のリストが含まれます( ContactPerson ) ListViewから選択した個人の名前に基づく コントロール。 TextFieldもあります アイテムをすばやく検索するには( ContactPerson 名前) ListViewに含まれています 。 ListViewから特定のアイテムを選択した場合 、SQLクエリが実行され、関連するレコードがフェッチされて TableViewにデータが入力されます。 それに応じて制御します。
ドメインオブジェクト: ContactPerson
ContactPerson クラスは、連絡先のPOJO表現に他なりません。 テーブル属性。コンストラクターと単純なgetter-setter が含まれています メソッド。
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; } }
データアクセスオブジェクト: ContactDAO
ContactDAO 主にデータベースアクセス操作を含むデータアクセスオブジェクトクラスです。 DAOを実装します インターフェース。このインターフェースは、この例では重要ではないかもしれませんが、アプリケーションがより多くのデータアクセスオブジェクトクラスで拡張されている場合に役立つ可能性があります。ここで、 DAO インターフェイスには、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"; }
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インターフェース: ContactBrowser
ContactBrowserという名前のJavaFXアプリケーション内 、プログラムですべてのコントロールを設定します。これは、FXMLまたはSceneBuilderなどのビルダーユーティリティツールを使用して設定することもできます。しかし、筆記者の意見では、JavaFXの舞台裏で十分な経験を積んだら、それらを使用することができます。 GUIは主に、 TextFieldなどの3つのコントロールの相互作用です。 ( searchField )、 ListView ( listView )、および TableView ( contactTableView )。コードは自明であり、適切な場所にコメントが付けられています。ラムダ式は、コードを簡潔に保つために適用可能な場合は常に使用されます。必要に応じて、JavaFXAPIのドキュメントを参照してください。
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); } }
出力
図1: コード出力
結論
JavaFXを使用するJDBCアプリケーションは、基本的に、JavaFX GUIフレームワークがフロントエンド開発エンジンとして使用され、JDBCがバックエンドデータベースの相互作用に使用されたことを意味します。 Nのさまざまなタイプにすることができます それらで定義された機能の数。基本はCRUDアプリケーションです。検索・表示操作の一部を実装しました。これを拡張するためにできることは次のとおりです。作成を実装する 、削除 、および更新 オペレーション;また、 ListViewで画像付きの名前を追加することもできます 。ハッピーコーディング😉