Java RMI資料庫應用程式

在上一章中,我們創建了一個RMI圖形用戶介面應用程式的示例,客戶端調用伺服器端顯示GUI窗口(JavaFX)的方法。

在本章中,我們將以一個例子來看看客戶端程式如何檢索位於伺服器上的MySQL資料庫中的表的記錄。

假設在資料庫:testdb中有一個名稱為student的表,其表結構和數據如下所示 -

+----+--------+--------+------------+---------------------+
| ID | NAME   | BRANCH | PERCENTAGE | EMAIL               |
+----+--------+--------+------------+---------------------+
|  1 | Maxsu    | IT     |         85 | maxsu@xuhuhu.com    |
|  2 | Curry  | EEE    |         95 | curry123@gmail.com  |
|  3 | Alex | ECE    |         90 | alexs130@gmail.com |
+----+--------+--------+------------+---------------------+

創建資料庫和表如下語句 -

CREATE DATABASE IF NOT EXISTS testdb DEFAULT CHARSET utf8 COLLATE utf8_general_ci;

use testdb;

-- ----------------------------
-- Table structure for `student`
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL DEFAULT '',
  `branch` varchar(16) NOT NULL DEFAULT '',
  `percentage` float unsigned DEFAULT '0',
  `email` varchar(48) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', 'Maxsu', 'IT', '85', 'maxsu@xuhuhu.com');
INSERT INTO `student` VALUES ('2', 'Curry', 'EEE', '96', 'curry123@gmail.com');
INSERT INTO `student` VALUES ('3', 'Alex', 'ECE', '92', 'alexs130@gmail.com');

假設所使用的MySQL伺服器的用戶名是:root,其密碼是:123456

創建 Student 類

創建一個Student類,並創建settergetter方法,創建一個Java源代碼檔:Student.java,如下所示。

public class Student implements java.io.Serializable {
   private int id, percent;
   private String name, branch, email;

   public int getId() {
      return id;
   }
   public String getName() {
      return name;
   }
   public String getBranch() {
      return branch;
   }
   public int getPercent() {
      return percent;
   }
   public String getEmail() {
      return email;
   }
   public void setID(int id) {
      this.id = id;
   }
   public void setName(String name) {
      this.name = name;
   }
   public void setBranch(String branch) {
      this.branch = branch;
   }
   public void setPercent(int percent) {
      this.percent = percent;
   }
   public void setEmail(String email) {
      this.email = email;
   }
}

定義遠程介面

在這裏,我們定義一個名為Hello的遠程介面,Hello介面中有一個getStudents()方法。此方法返回一個包含Student類對象的列表。

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.*;

// Creating Remote interface for our application
public interface Hello extends Remote {
   public List<Student> getStudents() throws Exception;
}

開發實現類

創建一個類並實現上面創建的Hello遠程介面。

這裏我們實現遠程介面的getStudents()方法。當調用此方法時,它將檢索資料庫:students表中的記錄。使用Student類的setter方法設置對象的值並返回該對象列表。創建一個JAVA原始檔案:ImplExample.java 如下所示 -

import java.sql.*;
import java.util.*;

// Implementing the remote interface
public class ImplExample implements Hello {

   // Implementing the interface method
   public List<Student> getStudents() throws Exception {
      List<Student> list = new ArrayList<Student>();

      // JDBC driver name and database URL
      String JDBC_DRIVER = "com.mysql.jdbc.Driver";
      String DB_URL = "jdbc:mysql://localhost:3306/testdb";

      // Database credentials
      String USER = "root";
      String PASS = "123456";

      Connection conn = null;
      Statement stmt = null;

      //Register JDBC driver
      Class.forName("com.mysql.jdbc.Driver");

      //Open a connection
      System.out.println("Connecting to a selected database...");
      conn = DriverManager.getConnection(DB_URL, USER, PASS);
      System.out.println("Connected database successfully...");

      //Execute a query
      System.out.println("Creating statement...");

      stmt = conn.createStatement();
      String sql = "SELECT * FROM student_data";
      ResultSet rs = stmt.executeQuery(sql);

      //Extract data from result set
      while(rs.next()) {
         // Retrieve by column name
         int id  = rs.getInt("id");

         String name = rs.getString("name");
         String branch = rs.getString("branch");

         int percent = rs.getInt("percentage");
         String email = rs.getString("email");

         // Setting the values
         Student student = new Student();
         student.setID(id);
         student.setName(name);
         student.setBranch(branch);
         student.setPercent(percent);
         student.setEmail(email);
         list.add(student);
      }
      rs.close();
      return list;
   }
}

伺服器程式

RMI伺服器程式應實現遠程介面或擴展實現類。 在這裏,我們將創建一個遠程對象並將其綁定到RMI註冊表。

以下是本應用程式的伺服器程式。 在這裏,我們將擴展上述創建的類,創建一個遠程對象並使用綁定名稱為:hello ,將其註冊到RMI註冊表。創建一個JAVA原始檔案:Server.java 如下所示 -

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class Server extends ImplExample {
   public Server() {}
   public static void main(String args[]) {
      try {
         // Instantiating the implementation class
         ImplExample obj = new ImplExample();

         // Exporting the object of implementation class (
         //   here we are exporting the remote object to the stub)
         Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);

         // Binding the remote object (stub) in the registry
         Registry registry = LocateRegistry.getRegistry();

         registry.bind("Hello", stub);
         System.err.println("Server ready");
      } catch (Exception e) {
         System.err.println("Server exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

客戶端程式

以下是本應用程式的客戶端程式。 在這裏,我們獲取遠程對象並調用getStudents()方法。它從列表對象中檢索表 - student的行記錄並顯示它們。創建一個JAVA原始檔案:Client.java 如下所示 -

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;

public class Client {
   private Client() {}
   public static void main(String[] args)throws Exception {
      try {
         // Getting the registry
         Registry registry = LocateRegistry.getRegistry(null);

         // Looking up the registry for the remote object
         Hello stub = (Hello) registry.lookup("Hello");

         // Calling the remote method using the obtained object
         List<Student> list = (List)stub.getStudents();
         for (Student s:list)v {

            // System.out.println("bc "+s.getBranch());
            System.out.println("ID: " + s.getId());
            System.out.println("name: " + s.getName());
            System.out.println("branch: " + s.getBranch());
            System.out.println("percent: " + s.getPercent());
            System.out.println("email: " + s.getEmail());
         }
      // System.out.println(list);
      } catch (Exception e) {
         System.err.println("Client exception: " + e.toString());
         e.printStackTrace();
      }
   }
}

運行示例的步驟

以下是運行RMI示例的步驟。

注意:如果手動編譯,需要把上面代碼存放到目錄:F:\worksp\java_rmi\java-dbapp中,並創建一個目錄:F:\worksp\java_rmi\java-dbapp\libs,把下載的 mysql-connector-java-5.1.40-bin.jar 庫(下載地址:http://downloads.mysql.com/archives/c-j/ )放入到 F:\worksp\java_rmi\java-dbapp\libs 目錄中。

第一步 - 打開存儲所有程式的檔夾,並編譯所有Java檔,如下所示。

F:\worksp\java_rmi\java-dbapp> javac -Djava.ext.dirs=F:\worksp\java_rmi\java-dbapp\libs *.java

第二步 - 使用以下命令啟動rmi註冊表。

F:\worksp\java_rmi\java-dbapp> start rmiregistry

執行上面命令後,將在單獨的窗口中啟動一個rmi註冊表。

第三步 - 運行伺服器類代碼,如下所示。

F:\worksp\java_rmi\java-dbapp>java -Djava.ext.dirs=F:\worksp\java_rmi\java-dbapp\libs Server
Server ready

第三步 - 運行客戶端類檔,如下所示。

F:\worksp\java_rmi\java-dbapp>java -Djava.ext.dirs=F:\worksp\java_rmi\java-dbapp\libs Client

執行上面命令後,輸出結果如下 -

F:\worksp\java_rmi\java-dbapp>java -Djava.ext.dirs=F:\worksp\java_rmi\java-dbapp\libs Client
ID: 1
name: Maxsu
branch: IT
percent: 85
email: maxsu@xuhuhu.com
ID: 2
name: Curry
branch: EEE
percent: 96
email: curry123@gmail.com
ID: 3
name: Alex
branch: ECE
percent: 92
email: alexs130@gmail.com

F:\worksp\java_rmi\java-dbapp>

上一篇: Java RMI圖形介面應用程式 下一篇:無