2 在RMI框架中通过自定义结果集类实现Multi-Tier框架
2.1 自定义函数返回类型
自定义MyResultSet类,通过嵌套的ArrayList来存放记录列表和字段列表。
2.2 应用服务器执行类的核心代码
//Get records list by data source name and SQL public MyResultSet getResultSet(String __dsName, String __sql) { …… //Get data source by name BasicDataSource bds = (BasicDataSource)m_dsMap.get(__dsName); …… ArrayList recordsList = null; MyResultSet myRS = null; try { //Get connection, statement and result set Connection conn = bds.getConnection(); Statement stat = FoolDB.getQueryStat(conn); ResultSet rs = FoolDB.openQuery(stat, __sql); //Initialize the space for result set int rowsCount = FoolDB.getRowsCount(rs); int colsCount = FoolDB.getColsCount(rs); …… recordsList = new ArrayList(rowsCount); ArrayList fieldsList = null; myRS = new MyResultSet(fieldsList, rowsCount, colsCount); //Read each record by lines while(FoolDB.moveNext(rs) == true) { //Initialize the space for fields set fieldsList = new ArrayList(colsCount); //Read each field by column for(int i = 1; i <= colsCount; ++i) { fieldsList.add(rs.getObject(i) ); } //Append fields list recordsList.add(fieldsList); } …… } //Return records set return (myRS); }
2.3 客户端调用代码
public DBClient(String __dsName, String __sql) throws RemoteException, MalformedURLException, NotBoundException { String urlPrefix = "rmi://192.168.1.147:1099/"; //Look up the remote object by URL Application app = (Application)Naming.lookup(urlPrefix + "MultiTier.Application.Server"); //Invoke the remote interface MyResultSet rs = app.getResultSet(__dsName, __sql); …… int recordsCount = rs.getRowsCount(); //Get the rows count of record set int fieldsCount = rs.getColsCount(); //Get the columns count of record set }
发送数据源名称和SQL语句给应用程序服务端,由应用程序服务器根据数据源名称获取数据源,并申请连接对象,执行查询后将结果集返回给服务端。
2.4 客户端(Solaris 8)执行结果
图5:客户端执行输出
2.5 实践总结
虽然实现了实践目标。但是美中不足的是,返回给客户端的数据集需要用户自己管理,而不能作为诸如ResultSet等公用型的数据集接口,这样可能会加重客户端的开发任务。通过上述的尝试,我们应该对RMI的应用有了更深刻的认识:
(1)在基本篇中提到过,不要考虑将“权力”下放到客户端,而是要尽可能把处理逻辑放在应用程序端。在实践1和2中,试图将DataSource和Connection等高连接服务放到客户端,那么对应的业务逻辑也将放于客户端,这样应用程序服务器就丧失了其使用意图,只是成了简单的目录服务。
(2)远程接口定义中返回值的类型必须为支持序列化的实体类,用户自定义类型也必须遵照此原则进行定义。
(3)对于应用程序服务端与客户端的接口要尽可能地设计轻巧和标准。所谓设计轻巧是为了减少应用程序服务器与客户端的交互次数,因为通过序列化机制在应用程序服务器和客户端传递数据集的开销是相当大的。另外接口的标准是为了接口输出的使用通用化。这样用户就可以避开很多细节来对数据集进行使用(例如XML技术,流应用等)。
相关文章: