Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Một ứng dụng RMI truy xuất CSDL

Ứng dụng sau đây demo dùng RMI và truy xuất CSDL:

Chúng ta tao thư mục databaseRMI để lưu ứng dụng của mình.

Tạo interface AccessDBInterface.java có nội dung sau

import java.rmi.Remote;
import java.rmi.RemoteException;
import javax.sql.rowset.WebRowSet;

public interface AccessDBInterface extends Remote{
public WebRowSet GetTable(String tableName) throws RemoteException;
public int ExecUpdateSQL(String sql)throws RemoteException;
}

compile interface này. Sau đó tạo 2 thư mục server và client rồi copy tập tin AccessDBInterfac.class vào cả 2 thư mục đó.

====================================================

Phía Server:

1>Tạo file implements với tên AccessDBImpl.java có nội dung sau

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.sql.rowset.*;
import com.sun.rowset.*;

public class AccessDBImpl extends UnicastRemoteObject implements AccessDBInterface {

private Connection con;
private Statement stmt;

public AccessDBImpl() throws RemoteException {
try {
Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);
con = DriverManager.getConnection(“jdbc:odbc:test”);
stmt = con.createStatement();
} catch (Exception e) {
e.printStackTrace();
}
}

public WebRowSet GetTable(String tableName) throws RemoteException {
WebRowSet rs = null;
try {
String sql = “select * from ” + tableName;
ResultSet r = stmt.executeQuery(sql);
rs=new WebRowSetImpl();
rs.populate(r);
} catch (Exception e) {
e.printStackTrace();
}
return rs;
}

public int ExecUpdateSQL(String sql) throws RemoteException {
//int x=stmt.executeUpdate(sql);
return 0;
}
}

2>Tạo server AccessDBServer.java với nội dung sau

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.rowset.WebRowSet;

public class AccessDBServer {

public static void main(String []args){
try {
java.rmi.registry.LocateRegistry.createRegistry(1099);
AccessDBInterface acc=null;
acc=new AccessDBImpl();
Context ctx =new InitialContext();
ctx.bind(“rmi:acc”, acc);
System.out.println(“Server is running…”);

/*try {
AccessDBImpl db=new AccessDBImpl();
WebRowSet rs=db.GetTable(“DimCurrency”);
while(rs.next())
{
System.out.println(rs.getString(1));
}
}
catch (Exception ex) {
ex.printStackTrace();
}*/

} catch (Exception e) {
e.printStackTrace();
}
}
}
3> Build các file

4>Tạo file Server.bat để thực thi với nội dung sau:

java AccessDBServer

5>Runserver

Lưu ý: Ở đây sử dụng 1 DSN kết nối SQL-Server đến DB

28 Responses to “Một ứng dụng RMI truy xuất CSDL”

  1. Võ Minh Việt said

    thầy ơi, cho em hỏi là sao em chỉ lấy được các giá trị có kiểu là varchar(), còn các dữ liệu khác ví dụ như nvarchar(), hay Bit() thì nó ko lấy ra được, thầy giúp em với. Thanks

  2. Hồng Hạnh said

    Chào thầy, em cũng đang làm về rmi dùng truy xuất SQL Server, nhưng sao khi lấy dữ liệu ra từ SQL thì không hiển thị được tiếng Việt, mặc dù đã gán kiểu dữ liệu là nvarchar. Mong thầy giúp đỡ.

  3. Cao Tuyen said

    trong class client em truy cap toi server bang cach:
    String url=”//localhost/CALSERVER”;
    CalServerImpl remoteObject =(CalServerImpl)Naming.lookup(url);
    Khi run bang cmd thi okie. Nhung khi e chay bang Netbeans 6.7.1 thi no bao loi:connection: Connection refused to host: localhost; nested exception is: java.net.ConnectException: Connection refused: connect.
    Mong moi nguoi chi giup em.

  4. vovanhai said

    Bạn chú ý file client.policy

  5. vinhla said

    em lam 1 project chay rmi ket noi CSDl tu MySQL nhung khong hiu sao co loi mong moi nguoi giup do.
    1. em tao lop Categories
    public class Categories {
    String CatID, CatName;
    public void setCatID(String CatID) {
    this.CatID = CatID;
    }
    public void setCatName(String CatName) {
    this.CatName = CatName;
    }
    public String getCatID() {
    return CatID;
    }
    public String getCatName() {
    return CatName;
    }
    2. em tao 1 interface
    public interface CategoriesITF {
    public String insertCat(String CateID, String CateName) throws java.rmi.RemoteException;
    // De xoa du lieu trong bang Categories
    public int deleteCat(String CateID) throws java.rmi.RemoteException;
    // De cap nhat du lieu trong bang Categories
    public int updateCat(String CateID, String CateName) throws java.rmi.RemoteException;
    // De Select du lieu tu bang Categories
    public java.util.Vector selectCat (String CateID) throws java.rmi.RemoteException;
    public java.util.Vector selectCat () throws java.rmi.RemoteException;
    }
    3. em tao tiep 1 class:
    import java.rmi.RemoteException;
    import java.util.Vector;
    import java.sql.*;
    public class CategoriesIMP extends java.rmi.server.UnicastRemoteObject implements CategoriesITF{
    public CategoriesIMP() throws java.rmi.RemoteException{
    super();
    }
    public String insertCat(String CateID, String CateName) throws RemoteException {
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    Connection CateCon = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/craysystem”,”root”,”12345″);
    CateCon.createStatement().executeUpdate(“INSERT INTO Categories VALUES (‘”+CateID+”‘,'”+CateName+”‘)”);
    return “Insert Successful”;
    } catch (Exception e) {
    System.out.println(e.toString());
    return “Insert Failures”;
    }
    }
    public int deleteCat(String CateID) throws RemoteException {
    int i=0;
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    Connection CateCon = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/craysystem”,”root”,”12345″);
    i=CateCon.createStatement().executeUpdate(“delete from Categories where cateID='”+CateID+”‘”);
    return i;
    } catch (Exception e) {
    System.out.println(e.toString());
    return i;
    }
    }
    public int updateCat(String CateID, String CateName) throws RemoteException {
    int i = 0;
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    Connection CateCon = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/craysystem”,”root”,”12345″);
    i = CateCon.createStatement().executeUpdate(“update Categories set cateName='”+CateName+”‘”+”where cateID='”+CateID+”‘”);
    return i;
    } catch (Exception e) {
    System.out.println(e.toString());
    return i;
    }
    }
    public Vector selectCat(String CateID) throws RemoteException {
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    Connection CateCon = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/craysystem”,”root”,”12345″);
    java.util.Vector vt= new java.util.Vector();
    java.sql.ResultSet res = CateCon.createStatement().executeQuery(“select * from Categories where cateID='”+CateID+”‘”);
    while(res.next())
    {
    Categories Cate = new Categories();
    Cate.setCatID(res.getString(1));
    Cate.setCatName(res.getString(2));
    vt.add(Cate);
    }
    return vt;
    }
    catch (Exception e) {
    Vector vto = null;
    System.out.println(e.toString());
    return vto;
    }
    }
    public Vector selectCat() throws RemoteException {
    try {
    Class.forName(“com.mysql.jdbc.Driver”).newInstance();
    Connection CateCon = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/craysystem”,”root”,”12345″);
    java.util.Vector vt= new java.util.Vector();
    java.sql.ResultSet res = CateCon.createStatement().executeQuery(“select * from Categories”);
    while(res.next())
    {Categories Cate = new Categories();
    Cate.setCatID(res.getString(1));
    Cate.setCatName(res.getString(2));
    vt.add(Cate);
    }
    return vt;
    } catch (Exception e) {
    Vector vto = null;
    System.out.println(e.toString());
    return vto;
    }
    }
    }
    4. tao file chay server
    import java.rmi.registry.LocateRegistry;
    /**
    *
    * @author vinhniit
    */
    public class RunServer {
    public static void main(String[] args) {
    try {
    //Automatic in one JVM
    LocateRegistry.createRegistry(1099);
    CategoriesIMP CateImp = new CategoriesIMP();
    java.rmi.Naming.rebind(“CategoriesCRUD”, CateImp);
    System.out.println(” Registed Categories”);

    } catch (Exception ex) {
    System.out.println(ex.toString());
    }
    }
    5. ve phia client em lam 1 form co 1 combobox dung de chua categoriesID
    em load doan code nay khi chay file cleint

    try {
    //Load Item CategoriesID
    System.out.println(“1”);
    ServerCray.CategoriesITF serverCate = (CategoriesITF) java.rmi.Naming.lookup(“CategoriesCRUD”);
    java.util.Vector vt = serverCate.selectCat();
    int i=0;
    CatItem.removeAllItems();
    while(i<vt.size())
    {
    Categories Cate = (Categories)vt.get(i);
    i++;
    CatItem.addItem(Cate.getCatID());
    }
    } catch (Exception e) {
    System.out.println(e.toString());
    }
    thi no bao loi
    1
    java.lang.ClassCastException: $Proxy0 cannot be cast to ServerCray.CategoriesITF

  6. Dung said

    xin thay huong dan em truy xuat CSDL voi RMI. em dang mac ket voi truy xuat csdl thong qua RMI co su dung cac frame java. vi du em muon tao mot frame Login co su dung mot comboBox de load ten cac cua hang. nhung em chua biet phai lam nhu the nao vi csdl va cac phuong thuc nam tren Server. bang csdl cua em gom 2 bang cuaHang(IdCH, Ten) va User(IdUser, Username,Pass,IdCH).

    em chua hieu lam ve file policy. xin thay va cac ban chi gium em.

  7. Võ Văn Hải said

    Em kết nối cơ sở dữ liệu như bình thường sau đó đổ vào 1 collection nào đó (chẳng hạn ArrayList, HashMap, HashSet,…) ở dạng object rồi làm việc.

  8. minh tran said

    Nhờ thầy và các bạn giải quyết hộ e bài nay.Thaks thầy và các bạn.
    Sử dụng kỹ thuật RMI để thực hiện giải quyết các yêu cầu sau:
    Bài 01: Client gửi đến Server 1 dãy số nguyên. Server thực hiện
    a. Tính tổng dãy số đó
    b. Sắp xếp dãy số đó theo thứ tự tăng dần
    c. Tìm số các phần tử chẵn, lẻ trong dãy
    d. Đảo ngược dãy số
    e. Xóa các phần tử chia hết cho 3
    Sau đó gửi trả lại cho Client
    Yêu cầu viết CT thực hiện kết quả trên màn hình Client

  9. kenxing said

    Hiện nay em đang học về lập trình phân tán hướng đối tượng! em đang làm bài có liên wan về RMI và xử lý CSDL (em dùng access). nhưng em vẫn còn kẹt ở chỗ load dữ liệu cũng như thao tác dữ liệu trên giao diện bên client! xin thay va cac ban chi gium em.
    Có thể liên lạc với mọi người wa mail: thanhtam0711@live.com

  10. Võ Văn Hải said

    Mỗi bảng em tạo tương ứng 1 object, xong em dùng 1 collection(ArrayList) chẳng hạn để chứa tập các obj – records. Sau đó gửi cho client.

  11. kenxing said

    em cám ơn thầy ạ 😀

  12. kenxing said

    Thầy ơi, cho em hỏi là trong Giao diện bên Client em có 1 hàm Load csdl lên giao diện:
    public void Load() throws NotBoundException, IOException
    {
    inf_hanghoa inf_hh = (inf_hanghoa) Naming.lookup(“rmi://localhost:1099/inf_hanghoa”);
    rs = inf_hh.selecthanghoa();
    this.dt.setNumRows(0);
    try
    {
    while(rs.next())
    {
    String []row = {rs.getString(1),rs.getString(2)};
    this.dt.addRow(row);
    }

    }
    catch(Exception e)
    {
    System.out.println(e.toString());
    }
    }

    Bây giờ em mún gọi lại hàm Load() này, thì em gọi thế nào vậy Thầy! vì em gọi bằng this.Load() thì nó báo lỗi là “unreported exception java.rmi.NotBoundException; must be caught or declared to be thrown”… Lỗi này báo ở chỗ mà em gọi this.Load() đó thầy 😦 mong thầy giúp em 😦

  13. Võ Văn Hải said

    Bạn thêm try/cacth vào khi gọi.

  14. Võ Văn Hải said

    Bạn thêm try/catch vào khi gọi.

  15. lctoai said

    ko hiểu sao copy code trên nó cứ bị lỗi
    rs=new WebRowSetImpl();
    bây giờ theo yêu cầu đề tài là làm 1 ứng dụng bán hàng trực tuyến, em upload (insert được) nhưng ko biết cách nào để show dử liệu mà mình select,
    nếu làm ứng dụng chạy nền web thì cần các bước như thế nào

  16. Võ Văn Hải said

    Chạy trên eclipse thì phải dùng JDK thay vì JRE mới có WebRowSetImpl (vào Windows-References, chọn Java->Installed JREs, thêm vào JDK nhé)

  17. huy_langtu said

    Em đang làm project quản lý bán vé máy bay dùng cơ chế RMI kết nối với sql server.
    trên server em đăng ký registry cổng 2011.kết nối với sql qua cổng 1433.khi chay thi báo lỗi: access denied(“java.net.SocketPermission””localhost:1433″”connect.resolve”).
    Em không biết khắc phục thế nào nhờ thầy giúp đỡ!

  18. Võ Văn Hải said

    Mở SQL Server Configuration Manager lên (trong start menu), sao đó chọn SQL ??? Network Configuration, chọn instance cần enable TCP, double click lên TCP/IP sao đó chọn enabled=Yes, đổi cổng về 1433.
    Chúc thành công!

  19. huy_langtu said

    em kết nối csdl thi được nhưng làm rmi thi nó lỗi!

  20. Võ Văn Hải said

    chuyển đối tượng ResultSet về Collection rồi chuyển.

  21. huy_langtu said

    Em chưa hiểu Thầy có thể nói cụ thể không ạ?
    Em cám ơn Thầy!

  22. Tii Le said

    Thầy ơi,
    Cho em hỏi muốn truyền image qua RMI thì thực hiện như thế nào ạ.?

  23. lctoai said

    Thầy cho em hỏi cái ResultSet, trong Impl em viết 1 hàm connect SQL rồi trả về 1 ResultSet sau đó ở JFrame em tạo 1 Combobox và duyệt từng ResultSet gán vào, nhưng nó báo lỗi dữ quá. Thầy xem giúp em với
    public ResultSet getAllProducts() throws Exception{
    Connection con;
    String url=”sun.jdbc.odbc.JdbcOdbcDriver”;
    Class.forName(url);
    String dbURL = “jdbc:odbc:qlsp”;
    con=DriverManager.getConnection(dbURL);
    ResultSet rs;

    Statement stmt=con.createStatement();
    String sql=”select * from Sanpham”;
    rs=stmt.executeQuery(sql);
    System.out.print(“Client request to Connection…”);

    return rs;
    }
    Add combobox :
    try{
    AccessDBInterface service= (AccessDBInterface)Naming.lookup(“rmi://localhost/myfactory”);
    ResultSet rs;
    rs=service.getAllProducts();

    while (rs.next())
    {
    DSSanPham.addItem(rs.getString(“msSP”));

    }
    }
    catch (Exception ex) {
    ex.printStackTrace();

    }
    Và đây là lỗi

    java.rmi.UnmarshalException: error unmarshalling return; nested exception is:
    java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: sun.jdbc.odbc.JdbcOdbcResultSet
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:191)
    at AccessDBImpl_Stub.getAllProducts(Unknown Source)
    at QuanLi.(QuanLi.java:40)
    at QuanLi$2.run(QuanLi.java:252)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: sun.jdbc.odbc.JdbcOdbcResultSet
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
    at sun.rmi.server.UnicastRef.unmarshalValue(UnicastRef.java:324)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:173)
    … 17 more
    Caused by: java.io.NotSerializableException: sun.jdbc.odbc.JdbcOdbcResultSet
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at sun.rmi.server.UnicastRef.marshalValue(Unknown Source)
    at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at sun.rmi.transport.Transport$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

  24. Le Ngoc Manh said

    Thầy ơi em có bài tập về lập trình mạng này khó quá ,em làm mãi không được , em mới học lên không hiểu rõ lắm , nhờ Thầy và các bạn làm giúp em bài này với .

    Đề :

    Viết chương trình RMI minh họa từ điển trực tuyến. Server chứa nội dung từ điển Anh-Việt. Client sẽ nhập từ tiếng Anh rồi tra nghĩa tương ứng trên server

  25. Võ Văn Hải said

    Trong RMI, đối tượng muốn truyền qua mạng phải là object Serializable. Trong khi đó ResultSet thì không phải. Nó phải duy trì 1 kết nối liên tục qua connection. Trong ví dụ tôi phải chuyển nó qua WebRowset thấy không?
    1 cách khác là bạn đưa nó vào 1 collection rồi truyền.

  26. tranvantoiok said

    Các bác giúp em với. Em đang làm báo cáo môn “lập trình phân tán hướng đối tượng” bằng công nghệ .NET Remoting được xây dựng trên kiến trúc đa tầng với các giao diện như: class giao tiếp csdl, Admin, Teamleader Internal,(Dùng visual studio để thiết kế), Teamleader External(Dùng Java dể thiết kết), Customer(Dùng webservice để thiết kêt) các bác pro nào có bài tương tự post cho em học hỏi!
    thank nhiều!

  27. sam said

    thầy cho em hỏi chương trình truy xuất dữ liệu qua 2 máy thì làm thế nào ah, em thay cái localhost thành địa chỉ ip của máy. nhưng không thể thực hiện được yêu cầu từ server

  28. thành said

    thầy giáo em đang làm tiểu luận về Rmi về truy cập dữ liệu cở sở web bằng Rmi mà em ko biết làm thế nào mong thầy giáo hướng dẫn

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.