RMI+JDBC远端数据库的访问
前期准备
(1).确保JDK已经安装,并将其bin路径配置到环境变量path中
(2).创建MySQL数据库,数据库名为rmidb
1. 编写DBmanager类,访问mysql数据库,实现创建表,录入成绩,查询成绩等操作。
建立Java工程RMIServer,创建包com.rmiDB,新建类DBmanager,添加mysql-connector-java-5[1].0.8.zip驱动包
package com.rmiDB;
import java.io.Serializable; import java.sql.*;
public class DBManager { private static final String userName = "root"; private static final String password = ""; private static final String dburl="jdbc:mysql://localhost:3306/rmiDB?useUnicode=true&characterEncoding=utf8"; private static final String driver="com.mysql.jdbc.Driver"; private static Connection conn = null; private static ResultSet rs = null; private static Statement stmt = null;
public static Connection getConn(){ try{ Class.forName(driver); conn = DriverManager.getConnection(dburl,userName,password); }catch(ClassNotFoundException e){ System.out.println("没有找到数据库驱动程序"); }catch(SQLException e){ System.out.println("数据库连接时出现异常,可能由于数据库服务未启动造成,请先启动数据库服务"); } return conn; }
public static void createTable(){ String sql = "create table stu(stuNo varchar(10),stuName varchar(10),grade float);"; conn = getConn(); try{ stmt = conn.createStatement(); stmt.execute(sql); stmt.close(); conn.close(); }catch(SQLException e){ e.printStackTrace(); } }
public static void insert(Student stu){ String sql = "insert into stu values('"+stu.getStuNo()+"','"+stu.getStuName()+"',"+stu.getGrade()+")"; conn = getConn(); try{ stmt = conn.createStatement(); stmt.executeUpdate(sql); stmt.close(); conn.close(); }catch(SQLException e){ e.printStackTrace(); } }
public static Student getStu(String stuNo){ String sql = "select * from stu where stuNo = "+stuNo; conn = getConn(); Student stu = new Student(); try{ stmt = conn.createStatement(); rs = stmt.executeQuery(sql); if(rs.next()){ stu.setStuNo(rs.getString(1)); stu.setStuName(rs.getString(2)); stu.setGrade(rs.getFloat(3)); } stmt.close(); conn.close(); }catch(SQLException e){ e.printStackTrace(); } return stu; }
public static class Student implements Serializable{ private String stuNo=""; private String stuName=""; private float grade=0.0f; public Student(){} public String getStuNo() { return stuNo; } public void setStuNo(String stuNo) { this.stuNo = stuNo; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public float getGrade() { return grade; } public void setGrade(float grade) { this.grade = grade; } } } |
2.定义服务接口DataService。提供创建表,录入成绩,查询成绩等操作(尽量与DBmanager类中的操作定义成同样的形式)
新建接口DataService,内容如下:
package com.rmiDB;
import java.rmi.Remote; import java.rmi.RemoteException; import com.rmiDB.DBManager.Student;
public interface DBServer extends Remote{ public void createTable() throws RemoteException; public void insert(Student stu)throws RemoteException; public Student getStu(String stuNo)throws RemoteException;
} |
3.实现服务DataServiceImpl。对实现创建表,录入成绩,查询成绩等操作。实现过程中可直接使用DBmanager类。
package com.rmiDB;
import java.rmi.server.*; import java.rmi.*; import com.rmiDB.DBManager.Student;
public class DBServerImpl extends UnicastRemoteObject implements DBServer{ private static final long serialVersionUID = -7777277221L; public DBServerImpl() throws RemoteException{ super(); } @Override public void createTable() throws RemoteException{ DBManager.createTable(); } @Override public Student getStu(String stuNo) throws RemoteException{ return DBManager.getStu(stuNo); } @Override public void insert(Student stu) throws RemoteException{ DBManager.insert(stu); } } |
4.编写部署类DeployServer
package com.rmiDB;
import java.rmi.*; import java.rmi.registry.LocateRegistry;
public class DeployServer{ public DeployServer(){ }
public static void main(String[] args) { try{ DBServer ds = new DBServerImpl(); LocateRegistry.createRegistry(1111); Naming.rebind("//localhost:1111/ds",ds); System.out.println("RMI服务器正在运行..."); }catch(Exception e){ e.printStackTrace(); } } }
|
5.使用DataService接口,实现客户端 RmiHelloClient.java。
建立Java工程RMIClient,创建包com.rmiClient,新建类RmiHelloClient,内容如下:
package com.rmiClient;
import java.rmi.*; import com.rmiDB.*; import com.rmiDB.DBManager.Student;
public class RmiHelloClient{ public static void main(String[] args) { try{ DBServer ds = (DBServer)Naming.lookup("//120.95.133.79:1111/ds"); ds.createTable(); Student stu = new Student(); stu.setStuNo("2012014315"); stu.setStuName("王凯"); stu.setGrade(99.9f); ds.insert(stu); Student stu2 = ds.getStu("2012014315"); System.out.println("学号: "+stu2.getStuNo()); System.out.println("姓名: "+stu2.getStuName()); System.out.println("成绩: "+stu2.getGrade()); }catch(Exception e){ e.printStackTrace(); } } }
|
工程目录结构为:
6.测试运行
运行DeployServer.java启动服务器
运行RmiHelloClient.java启动客户端
客户端会将客户端的数据传给服务器并保存到数据库中,客户端再从数据库中读取出来
数据库显示:
客户端显示:
7.两台电脑之间访问测试
在两台电脑之间测试运行进行RMI通信,一台电脑做服务器,另一台电脑做客户机。
为了方便起见(一般只要将客户端要依赖的类打包即可),将服务器的工程Export成一个jar包.
在客户机的工程上添加这个jar包
新建工程RMIClient2,新建RmiHelloClient2类,代码如下:
package com.rmiClient2;
import java.rmi.*; import rmiserver.DateServer; import rmiserver.Student;
public class RmiHelloClient2 { public static void main(String[] args) { try{ DateServer ds = (DateServer)Naming.lookup("//120.95.133.79:1111/ds"); ds.createTable(); Student stu = new Student(); stu.setStuNo("2012014315"); stu.setStuName("王凯"); stu.setGrade(99.9f); ds.insert(stu); Student stu2 = ds.getStu("2012014315"); System.out.println("学号: "+stu2.getStuNo()); System.out.println("姓名: "+stu2.getStuName()); System.out.println("成绩: "+stu2.getGrade());
}catch(Exception e){ e.printStackTrace(); } }
} |
这里要注意客户端代码中所使用的类名要与服务器(jar包)中的一致,在客户端代码中import相应的类。
然后启动服务器,再启动客户端程序。客户端就会将数据传给服务器并保存到服务器的数据库中,客户端再从数据库中读取出来
服务器端数据库显示:
注意事项:
1.运行RMI程序前(服务器和客户机都要进行),在路径:java安装路径\jre\lib\security中,找到java.policy文件,
在末行添加:permission java.security.AllPermission “”, “”;
2.在本机既做服务器又做客户机时,因为工程RMIClient要调用工程RMIServer中的类,因此在工程RMIClient中的properties–>Java Build Path –> Projects –> Add RMIServer。