ApacheDerby构建脱机Ajax_第1页
ApacheDerby构建脱机Ajax_第2页
ApacheDerby构建脱机Ajax_第3页
ApacheDerby构建脱机Ajax_第4页
ApacheDerby构建脱机Ajax_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Apache Derby 构建脱机 Ajax人们非常喜爱Ajax应用程序,以至于他们十分乐于使用Ajax应用程序而不想使用等效的桌面程序。但惟一的问题是出现在网络无法访问的时候怎么办。这是必须要用脱机功能的场景。Apache Derby是支持Ajax应用程序实现脱机访问的优秀选择。了解如何使用Apache Derby作为本地数据库,该数据库可以实现Ajax应用程序的脱机使用。先决条件和系统要求本文将使用Apache Derby作为客户端数据库。Derby可以单独下载,但是也被绑定到Java?6中并被称为Java DB。在本文中,我们将把Derby V与Java 5和Java 6

2、结合使用。我们将利用Java Applet在浏览器中启用Derby并且使用JavaScript访问Applet。因此,强烈建议熟悉Java Applet和JavaScript。Derby允许使用普通JDBC和SQL,因此需要熟悉这些内容(请参阅参考资料)。回页首Apache Derby Apache Derby是任何一个Java应用程序都可以使用的嵌入式数据库。它是非常有用的工具,因此绑定在Java Platform,Standard Edition(Java SE)V6中。虽然嵌入式数据库的应用不计其数,但是许多人都不知道用Derby可以实现的一些客户端功能。我们将通过构建一个简单的地址本应

3、用程序研究其中一些应用。我们将从利用Apache Derby的Java Applet开始,最终实现一个使用Derby作为缓存的基于Ajax的应用程序。数据访问对于一篇有关数据库技术的文章,应当首先从数据库代码开始讨论。首先,让我们定义用于存储联系人的简单的表模式,如下所示:图1.Contact表您可以设想更复杂的联系人模式,如添加多个电话号码、地址等。但是,对于我们的应用程序来说,使用目前的这种模式刚刚好。当然,存在一个与Contact表相对应的Java类。在本例中,我们将遵循Active Record模式并用能够执行所有数据库操作的类封装数据库行。其代码如下所示:清单1.DE Contact

4、DE类public class Contactprivate Integer id;private String firstName;private String lastName;private String email;public static List Contact getContacts(String clause)if(clause=null)clause=;String sql=SELECT_SQL+clause;Connection conn=DbManager.getConnection();List Contact contacts=new ArrayList Conta

5、ct();tryResultSet cursor=conn.createStatement().executeQuery(sql);while(cursor.next()Contact c=new Contact();c.setId(cursor.getInt(1);c.setFirstName(cursor.getString(2);c.setLastName(cursor.getString(3);c.setEmail(cursor.getString(4);contacts.add(c);catch(SQLException e)e.printStackTrace();return co

6、ntacts;public static List Contact getAllContacts()return Contact.getContacts(null);public static Contact getContact(String clause)List Contact results=Contact.getContacts(clause);if(results=null|results.size()!=1)return null;else return results.get(0);public void save()if(id=null)insert();else updat

7、e();public void delete()Connection conn=DbManager.getConnection();String sql=delete from Contact where id=?;tryPreparedStatement ps=conn.prepareStatement(sql);ps.setInt(1,id);ps.executeUpdate();System.out.println(Deleted contact id=+id);catch(SQLException e)e.printStackTrace();private void insert()C

8、onnection conn=DbManager.getConnection();tryPreparedStatement ps=conn.prepareStatement(INSERT_SQL,PreparedStatement.RETURN_GENERATED_KEYS);ps.setString(1,firstName);ps.setString(2,lastName);ps.setString(3,email);ps.executeUpdate();ResultSet autoRs=ps.getGeneratedKeys();if(autoRs.next()id=autoRs.getI

9、nt(1);System.out.println(Contact saved new id=+id);catch(SQLException e)e.printStackTrace();private void update()Connection conn=DbManager.getConnection();tryPreparedStatement ps=conn.prepareStatement(UPDATE_SQL);ps.setString(1,firstName);ps.setString(2,lastName);ps.setString(3,email);ps.setInt(4,id

10、);ps.executeUpdate();System.out.println(Contact updated with id=+id);catch(SQLException e)e.printStackTrace();该类将完成很多任务,但是所有内容都非常简单。它有与数据库列对应的字段及用于每个字段的常用存取器(getter和setter)。它拥有执行所有创建/更新/删除(CReate Update Delete,CRUD)操作及其附带SQL查询的方法。例如,查询联系人的方法是静态方法,因此可以执行类似DE Contact.getAllContacts()DE的操作。保存和删除操作是实例方法

11、,因此对个别联系人调用这些方法。此处没有显示查询,因为查询是标准的SQL。该类还有常用的getter和setter,但是为了简短起见并未显示(请参阅下载以获得完整的代码清单)。该类将用Derby构造基本的客户端存储。首先,我们将使用它作为Applet UI的一部分,但是稍后该Applet将把它用于JavaScript。注意,对于每个方法,我们将调用实用程序类DE DbManagerDE以获得连接。清单2.DE DbManagerDE类package org.developerworks.addressbook;import java.sql.Connection;import java.sql

12、.DriverManager;import java.sql.SQLException;public class DbManagerstatictryClass.forName(org.apache.derby.jdbc.EmbeddedDriver);catch(ClassNotFoundException e)e.printStackTrace();public static Connection getConnection()tryConnection conn=DriverManager.getConnection(jdbc:derby:contacts;create=true);re

13、turn conn;catch(SQLException e)e.printStackTrace();return null;这是所有特定于Derby的代码所在的位置。实际上,并不是特别特定于Derby。我们使用的是嵌入式数据库,但是我们处理它的方式和通过JDBC访问的其他数据库一样。我们将在类的静态初始化器中把DE EmbeddedDriverDE用于驱动程序类。另外对于DE getConnectionDE方法,我们将添加额外的参数DE create=trueDE来告诉Derby在数据库尚不存在时创建数据库。注意,不需要像使用JDBC那样用到用户名或密码-这是使用嵌入式数据库的优点之一。您看

14、到了所有的数据访问代码。它看起来非常类似于在任何一个应用程序中都可以看到的数据库代码;而数据库刚好是嵌入式Derby数据库。您可以设想为应用程序创建其他模型,这样可以存储专用于应用程序的数据,但是位于客户端。让我们查看一个利用清单2中所示的数据访问代码的简单应用程序。Applet UI首先使用一个非常简单的Applet,该Applet将使用数据访问代码。清单3.Applet UI代码public class AddressBookApplet extends JAppletprivate static final long serialVersionUID=1L;private static

15、final String columns=First Name,Last Name,Email,Id;public AddressBookApplet()this.setLayout(new GridLayout(1,0);JPanel panel=buildUi();this.add(panel);public Contact addContact(String firstName,String lastName,String email)Contact c=new Contact();c.setFirstName(firstName);c.setLastName(lastName);c.s

16、etEmail(email);c.save();return c;public void deleteContact(Integer id)Contact c=new Contact();c.setId(id);c.delete();public Object loadContacts()List Contact book=Contact.getAllContacts();Object contacts=new Objectbook.size()4;int cnt=0;for(Contact contact:book)contactscnt+=contact.toArray();return

17、contacts;private JPanel buildUi()JPanel panel=new JPanel();panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS);final DefaultTableModel dataModel=createDataModel();final JTable table=createTable(dataModel);/Lots of Swing/UI Code omitted for brevityprivate JTable createTable(final DefaultTableModel

18、dataModel)final JTable table=new JTable(dataModel);table.setPreferredScrollableViewportSize(new Dimension(500,70);table.setFillsViewportHeight(true);return table;private DefaultTableModel createDataModel()Object contacts=loadContacts();final DefaultTableModel dataModel=new DefaultTableModel(contacts

19、,columns);return dataModel;这段代码大部分是构建UI的典型Swing代码。所有UI代码都是在位于类底部的私有方法中完成的。DE buildUiDE方法处理Swing组件的创建,但是为了简短起见而省略了大部分内容。更有趣的是三个公共方法(除了构造函数之外):DE addContactDE、DE deleteContactDE和DE loadContactsDE。这三个方法实质上都是先前开发的数据访问代码的包装器。实际上,我们不需要将Applet用于最终应用程序的UI,但是它提供了测试代码的简单方法。如果使用的是Eclipse,则只需在DE AppletDE类上右键单击并

20、选择Run As Java Applet。图2.在Eclipse中作为Java Applet运行Eclipse在这里并不神秘,它只是使用JDK的Applet Viewer。如果使用的不是Eclipse,则可以在命令行中调用此程序。不管采用哪种方法,您都应当会得到类似图3的内容。图3.使用Applet Viewer运行Applet添加和删除联系人以测试应用程序。这是开发和测试稍后使用JavaScript访问的客户端数据库代码的简单方法。Applet UI是一个近乎完美的单元测试。我们几乎可以获取它并将其添加到Web页面中,但并不完全如此。首先,有一些安全注意事项需要处理。安全性我们将为Apple

21、t中使用的JAR设置签名。如果这里继续遵循计划,有一件事好到令人难以置信。Derby将给我们提供嵌入到客户机中的持久数据库(所有内容都存储在客户机中)。它有几分像HTTP Cookie,但是众所周知,那些Cookie在每个域中不可以超过4 KB。客户机中的Derby数据库的限制是什么?答案是要么很多,要么很少。默认情况下,Applet无法访问本地文件系统,因此Derby无法在客户机中存储任何数据。那么使用Derby是做白日梦么?幸运的是,它不是。关键是您必须给Applet设置数字签名。有签名的Applet将获得本地文件系统的访问权,这样如果数据来自有签名的Applet,则Derby可以持久存储

22、这些数据。我们只需给Applet设置签名。清单4.给Applet设置签名$keytool-genkey-alias sigs-keystore sigstore-keypass password-storepass password What is your first and last name?Unknown:Michael What is the name of your organizational unit?Unknown:developerWorks What is the name of your organization?Unknown:IBM What is the name

23、 of your City or Locality?Unknown:San Jose What is the name of your State or Province?Unknown:CA What is the two-letter country code for this unit?Unknown:US Is CN=Michael,OU=developerWorks,O=IBM,L=San Jose,ST=CA,C=US correct?no:yes$jarsigner-keystore sigstore-storepass password-keypass password-sig

24、nedjar addrbook.jar derby.jar sigs Warning:The signer certificate will expire within six months.正如您所见,我们使用两个JDK工具给Applet(技术上是包含Applet的JAR)设置签名。首先,使用DE keytoolDE创建用于保存生成的加密密钥的密钥库。还可以使用它执行创建SSL证书之类的任务。在拥有密钥后,结合使用该密钥与DE jarsignerDE工具来给JAR设置签名。注意,我们包括了Derby JAR,以及包含自定义代码的addrbook JAR。最终获得了一个自签名Applet的示例

25、。这对于开发来说没问题,但是通常不适用于任何面向用户的代码。在这种情况下,您将需要来自受信任提供商(如VeriSign)的密钥/证书。关键原因是因为需要在客户机中存储数据,我们需要执行这些附加步骤才能符合Java语言的客户端安全模型。牢记这些安全事项并且拥有一颗可以正常工作的Applet后,我们现在已经准备好从JavaScript使用Applet。回页首带有JavaScript的Applet可以将Applet用于Web应用程序中的所有内容,但是在Web应用程序的UI中使用标准的HTML和JavaScript更加常见。我们仍然可以这样做并且使用Applet作为访问嵌入式Derby数据库的方法。只

26、需在JavaScript与Applet之间完成一些集成。集成Applet创建代码以实现JavaScript与Java Applet之间的通信听起来可能十分棘手,或者听上去像是某种新技术。实际上,这类集成从Netscape Navigator时代起就一直在进行,并且在那时使用的技术仍然起作用。首先,让我们查看仅用于将Applet嵌入到页面中的HTML代码。清单5.嵌入Applet的代码applet alt=Address Book Appletname=addrBookAppletcode=org.developerworks.addressbook.AddressBookAppletwidth

27、=400height=200archive=addrbook.jar,derby.jar/applet这是非常标准的Applet嵌入代码。它将应用不推荐使用的DE applet DE标记。它仍然受跨浏览器支持。它是可以与Microsoft和Mozilla浏览器结合使用的惟一标记。因此如果不需要使用它,则需要使用JavaScript来判断浏览器(确定用户在使用哪种浏览器)。如果是Internet Explorer,则将使用DE object DE标记。否则,将DE embed DE标记与嵌套的DE param DE标记结合用于height、width和archive属性之类的内容。此外,如果使用

28、DE object DE标记,则还需要一个可编写脚本的参数以允许JavaScript调用Applet的Java方法。如果使用DE applet DE标记,则不需要这样做。您应当知道的另一个属性是DE MAYSCRIPTDE。此属性用于授予Applet权限以在页面中执行JavaScript。此属性会非常有用,但是在本例中不需要它。我们将使用JavaScript访问Applet(JavaScript将调用Applet的Java方法)。但是,该Applet将不会调用JavaScript,因此不需要DE MAYSCRIPTDE属性。那么如何从JavaScript中调用那些Java方法?清单6.从Jav

29、aScript中调用Java function saveContact(firstName,lastName,email)var applet=document.addrBookApplet;var newContact=applet.addContact(firstName,lastName,email);addContactToUi(newContact);在DE saveContactDE函数中执行的第一个操作是获得Applet中的句柄,方法是使用Applet的名称(清单5中的DE nameDE属性)。我们将在其中直接调用DE addContactDE方法,然后它将在清单6的代码中返回一

30、个新DE ContactDE对象。我们将把该对象传递给另一个JavaScript函数以用新联系人更新UI。不需要更多内容。就是这样简单。可以将Applet仅用于持久性,并且可以将JavaScript用于所有其他内容。使用没有头文件的Applet现在可以使Applet没有头文件(就是一个没有UI的代码库)。为此,只需删除清单3中的所有UI并且只在顶部保留那些公共方法。需要略微调整UI嵌入代码。清单7.没有头文件的UI HTML applet alt=Headless Appletname=headlessAppletcode=org.developerworks.addressbook.Head

31、lesAppletwidth=1height=1archive=addrbook.jar,derby.jar/applet此处惟一有趣的是把宽度和高度都设为1。这实际上将使Applet在页面中不可见。因此,最终用户根本不知道页面中有一个Applet。它将是一个不可见的helper。当然,如果更改Applet的名称,则还需要调整JavaScript,这是另外一处需要修改的内容。我们已经准备好使用此客户端持久化工具来进一步增强Web应用程序。回页首创建Ajax缓存Applet能够执行用Ajax可以完成的许多相同操作,并且如我们所见,Applet可以完成更多操作。在本例中,我们只对多出来的操作感兴趣

32、。Applet可以与服务器进行通信,但是我们将坚持用Ajax完成该操作。使用Derby作为嵌入式客户端数据库能够使我们完成单独用Ajax无法完成的操作。更为重要的是:可以将Derby用作存储来自服务器的数据的强大客户端缓存。使用Derby作为缓存下面是我们的想法:在服务器中保存联系人,而所有添加和删除之类的操作都通过Ajax调用完成。但是,将在客户机中的Derby中保存相同信息并将其用作缓存。因此,可以从Derby中载入所有联系人。清单8.从Derby缓存中载入联系人function init()var book=document.headlessApplet.loadContacts();v

33、ar i=0;var contact=;for(i=0;i book.length;i+)contact=firstName:booki0,lastName:booki1,email:booki2,id:booki3;addContactToUi(contact);该函数将从Applet中载入联系人,然后进行遍历以将每个联系人添加到UI中。这是在页面首次装入时调用的代码。通常,我们将从服务器中获得联系人,并且等待服务器响应会导致产生延迟。使用Derby缓存就不会产生延迟。但是,需要确保服务器与Derby缓存中的联系人之间保持同步。保持同步必须确保缓存是准确的,因此需要确保它与服务器同步。完成此操作的最简单方法是向服务器发送异步更新并且在处理期间,更新缓存和应用程序的UI。清单9.添加联系人function addContact()var contact=;var firstName=document.getElementById(firstName).value;var lastName=document.getElementById(lastName).value;var email=docu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论