`

JDO+JSP2.0开发Web应用向导 – 配置篇

阅读更多
  本文将主要介绍目前流行的JDO规范的应用开发过程。为简单起见,将会使用JSP2.0来进行页面部分的开发,因为其JSP EL可以大大简化页面的开发,节省调试时间,并增加页面的可读性。

  以前曾经在CSDN上发表过一篇关于用JDO开发数据库应用的文章,那只是基于数据库的简单的文本模式的程序,仅仅是为了表达清楚JDO开发的原理和基本过程,现在这篇文章,将更加注重实用性,向各位感兴趣的读者详细介绍用JDO来开发目前流行的基于Web的三层结构数据库应用的开发过程。


  在开始开发之前,我们需要先建立开发环境。这里先说明一下开发用到的第三方产品。

1 系统环境
1.1 MySQL及其JDBC驱动
  我们开发的Web应用是面向数据库的,当然需要一个底层的数据库支持。我们这里使用免费的数据库产品MySQL作为底层的关系数据库。

  先到{www.mysql.com}上,下载目前最新的4.0.16版本,我们下载那个19M大小的不带安装程序的ZIP包,我们将这个包解到C:\目录下,形成一个C:\ mysql-4.0.16目录(以后就用<mysql>来代表这个目录),然后运行<mysql>/bin/winMySQLadmin.exe,这样就将MySQL服务安装到本机上并启动就绪了。

  接下来的开发是基于Java的,我们还需要同样在www.mysql.com上下载最新的JDBC驱动:3.0.9版。我们将下载下来的ZIP包解开,其中的mysql-connector-java-3.0.9-stable\ 目录中的mysql-connector-java-3.0.9-stable-bin.jar文件就是我们需要的JDBC驱动jar文件了。为了方便,可以将其改名为mysql.jar文件,并放到某个目录中以备使用。

  为了测试MySQL JDBC的连接,可以去下载一个专门面向JDBC的数据库操纵工具:SquirrelSQL,它的网址是:{http://squirrel-sql.sourceforge.net}。这是一个免费的软件。注意连接mysql的时候有两个问题:

1. 数据库直接采用MySQL安装时自带的“test”库即可,没有用户名和密码。有些自定义的MySQL安装会将用户名设成“root”或“sa”,如果空用户名连不通,可以试试“root”或“sa”。

2. 为了能够使用中文,需要在连接MySQL的JDBC URL中设定使用GBK字符集的参数:
jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK

1.2 JDO与JDOGenie产品
  JDO作为我们开发Web应用的数据对象包装层,是本篇文章的核心。为尽可能简单和最快地配置起来JDO环境,我们采用目前最简单易上手的JDOGenie作为JDO Implementation。除了实现标准的JDO规范之外,这个产品还有以下特点与我们的开发过程有关:

1. 集成的图形配置界面workbench,基本上可以实现所有配置功能

2. 在集合框架上面,支持java.util.List。这是一个可选的JDO特性。

3. 支持自动维护的双向关系。这也是JDO2.0将要加入的特性,目前还没有其他JDO产品能够做到。

4. 支持Ant集成,可以在其集成配置界面中运行Ant脚本对源代码进行编译、类增强等工作

5. 支持查询结果集的size()方法,返回准确的符合条件的总记录数。(这个方法在一些JDO产品中将返回0或Integer.MAX_VALUE,这是JDO规范允许的。)

  我们先到JDOGenie的网站{www.jdogenie.com}上下载目前的最新版:2.2.0beta7,是一个ZIP包,解开到一个目录中就可以使用。我们假定这个解开成了C:\jdogenie-2.2.0beta7\目录,以后我们用<jdogenie>来代替C:\jdogenie-2.2.0beta7\目录。

  另外,在下载JDOGenie后还需要申请一个试用的License,根据页面的提示,我们需要填写自己的邮箱,和一些其它信息,提交申请后,会一个封带附件的邮件发过来,这个附件就是试用License,文件名是:jdogenie.license,注意这个附件文件一定要用邮件客户端程序(如Outlook Express或Foxmail)来保存,很多网友在网易的邮箱mail.163.com网站上通过IE浏览器保存这个附件时,这个文件的内容会被改变,不能使用。

  在运行JDOGenie之前,我们需要先在系统中安装好JDK,推荐最新的JDK1.4.2。安装好JDK后,要设置一个JDOGenie需要的环境变量:JAVA_HOME,它指向安装好的JDK的根目录,比如:C:\JDK1.4.2\。这个变量在下面将要提到的JSP服务器Resin中也需要。

  设置好JDK后,我们直接运行<jdogenie>\workbench.bat,就进入了JDOGenie的集成配置环境,如下图:


  简单介绍一下这个界面:

1. 顶部是菜单和工具条

2. 左边是基于JDO开发的几个工作区(不同职责的人员可能使用不同的工作区),依次是:

a) 树形图
  这里可以看到类及类的内部属性,方便设置。不过一般不大用

b) UML类图区
  这里面可以显示数据类之间的关系结构图

c) 类及类属性列表区,也是最主要的工作区
  这里列出本项目中用到的数据类及其属性的各种JDO相关配置,主要的配置工作也在这个区中完成

d) 数据库创建区
用于将对象模型转化为相应的数据库建表的SQL,并可生成数据库结构

e) 查询区,应用投入运行后做维护时很重要的工作区
  可以在这里进行JDOQL查询,并可对查询结果集中的对象进行属性改动,提交后,数据库中的数据会更新成改动后的数据。
  也可以在主这里进行SQL操作,比如某个类加了一个属性后在这里执行一个对该表添加字段的SQL操作。

f) 远程控制台
  主要是连接远程的JDOGenie引擎,并观察服务器运行状况的工作区,可以查看哪些JDOQL以及生成的SQL运行了多少次,平均占用时间是多少,以便进行相应的优化(如添加索引、改进查询代码等)

3. 底部是状态条,当某个操作有错误时,状态条上会以红色显示最新的错误描述,点击状态条右边第一个按钮可以查看详细的错误信息。状态条右方显示当前JDOGenie工作台占用了多少内存,如果发现太多内存占用,估计是垃圾对象太多,可以点击最右边的垃圾回收按钮进行内存释放。

1.3 Ant:Java批处理工具
  作为Java开发中的批处理工具(类似C/C++中的Make工具,主要用于编译、环境设置、文件组织等等),Ant是Apache组织对Java世界最大的贡献之一,现在已经成为面向Java开发的批处理方面事实上的标准。关于Ant的介绍文章很多,在{www.CSDN.net}可以找到一大堆,这里也不多介绍了。我们先去Ant的网站{http://ant.apache.org}下载最新版:1.5.4,下载下来的是一个ZIP包,解开到某个目录下即可。这里假定解开到C:\ apache-ant-1.5.4\目录中,下面采用<ant>来代替C:\apache-ant-1.5.4目录。

  注意,有些HTTP代理对{http://ant.apache.org/}首页上的一些脚本有过滤,导致有些用户可能访问这个页面时无法看到内容,这时,可以直接访问{http://ant.apache.org/bindownload.cgi} 来下载Ant1.5.4。

  为了以后直接通过DOS命令行处理的方便,我们建议在系统中配置PATH环境变量,将<ant>/bin/目录加到其中,这样就可以在命令行状态直接输入“ant”来运行“<ant>/lib/ant.bat”命令了。

  Ant是一个Java开发的产品,也是依赖于前面提到的JAVA_HOME环境变量的,Ant通过它找到JDK,从而运行用户编写的Ant批处理脚本。

  现在Ant安装好了,我们再打开JDOGenie,配置一下与Ant的集成:选择菜单“FileàWorkbench Settings…”,进行JDOGenie的环境配置界面,我们在其中设定Ant的入口程序ant.bat的路径,如图:


  这里笔者的Ant是安装在D:\BAK\ant目录下的,读者需要根据自己的实际情况设置自己的<ant>/bin/ant.bat路径。其它设置建议保持不动。

1.4 JSP与Resin服务器
  为简单易懂,本文将会以JSP2.0标准来编写JSP页面,JSP2.0定义了一个非常有用的数据输出方式:JSP EL(JSP Expression Language),可以通过标准JavaBean的getXXX()/isXXX()和setXXX()来实现Java对象数据的输出,并且,JSP2.0还纳入了一套标记库:JSTL,里面包含很多常用的JSP页面处理机制,如循环、条件化显示等等。关于JSP2.0的功能介绍,也可到{www.CSDN.net}上去搜索“JSP 2.0”的相关文章。

  目前JSP2.0规范还未正式出台,还处于ProposedFinalDraft-3阶段,不过很快将会正式发布。支持JSP2.0的服务器有Tomcat5、Resin3等等,出于方便、易维护的目的,我们选用Resin作JSP服务器。先到Resin网站{www.caucho.com}上下载最新的3.0.4版。下载下来的是一个ZIP包,解开到某个目录下即可使用。假定我们将包中内容解到C:\下,形成一个C:\ resin-3.0.4\目录,以后我们使用<resin>来代表“C:\ resin-3.0.4”目录。

  完成以上工作后,我们进入<resin>/bin目录,运行其中的httpd.exe程序,就可以看到Resin服务器启动了。如果希望将Resin安装成为系统的一项服务,可以使用httpd.exe –install安装,并用net start resin来启动Resin服务。不过为了方便地查看Resin服务器的输出日志,我们不建议安装Resin为系统服务,而建议运行httpd.exe来直接启动Resin。Resin服务器有以下特点:

1. 自动检测WEB应用的发布和更新
  通过对<resin>/webapps/下的子目录进行监测,可以动态地发布或取消某个web应用,也可以监测某个WEB应用的WEB-INF/web.xml的更新来自动重新发布该应用

2. 自动编译更新过的java文件,如果Resin检测到某个应用的WEB-INF/classes/下的java源文件被更新,则会自动编译该文件

3. 检测JSP文件的更新,如果某个JSP页面被更新过,则Resin会重新将它编译。(这个功能多数JSP服务器都有)


  Resin运行起来后,我们打开Internet Explorer浏览器,输入:{http://localhost:8080/} ,就可以看到Resin的主页面,表示Resin已经成功运行,如图:

2 Web应用:论坛
  在下面这两章中,我们将会经历一个论坛项目的开发和维护过程,从最初的非常简单的需求,到开发、运行,然后再经历一系列的需求变更和功能改进,来看看使用JDO是如何达到软件的快速开发与维护和应用的随需应变的。并且,还会涉及到一些性能优化和传统JDBC开发很难实现的老问题(如字符串字段长度限制等)。

2.1 准备工作
  在开始开发之前,我们必须先弄清楚一些基本的概念,并按J2EE对Web应用的要求建立相应的运行环境。

2.1.1 认识JDO的开发过程 关于JDO的开发流程,以前的文章和网上一些资料也详细介绍过,这里简单地重复一下:
  先编写代表数据对象的类,编译生成.class文件,再编写描述该类中每个属性的保存细节的元数据:.jdo文件,然后根据.jdo文件对.class文件进行增强(Enhance),这个数据类就可以在代码中通过JDO的API进行调用了。图示如下:

2.1.2 建立符合J2EE中WebApp规范的应用目录结构
  为了减少与Resin的整合配置,我们将论坛应用直接放到<resin>/webapps/下,建立一个名为bbs的子目录。这样,就可以通过在服务器地址后面加入“/bbs/”来访问这个WEB应用了。

  在bbs目录中,我们按J2EE规范建立一个“WEB-INF”子目录,然后在WEB-INF中再建立“classes”和“lib”两个子目录,将MySQL的JDBC驱动mysql.jar和JDOGenie的支持包<jdogenie>/lib/目录下的jdogenie.jar和jta.jar两个文件复制到这个<resin>/webapps/bbs/WEB-INF/lib目录中,作为本应用依赖的第三方组件,并将<jdogenie>/license/jdogenie.license文件复制到<resin>/webapps/bbs/WEB-INF/classes/目录下。这些配置就是将jdogenie整合到bbs应用中。

  接下来,我们开始确定bbs应用的Java类的包结构。简单起见,我们将源文件都放到“jdobbs”包中,也就是说,这个应用中涉及的Java源代码都会以“package jdobbs;”开头。

  这些目录都建好以后,我们得到下面的目录结构:

  我们先在bbs目录下放一个index.jsp文件:


<title>JDO BBS on ${pageContext.request.serverName}</title>
您现在的位置:<b>JDO BBS 首页</b>

<h3>欢迎访问JDOBBS!</h3>
<p>本系统采用JDO + JSP 2.0 完成<p>

<p>您的浏览器类型是:${header['user-agent']}
<p>您的IP地址是:${pageContext.request.remoteAddr}

  然后将Resin启动,看看效果:

  好!现在我们的第一个JSP页面就已经完成了。该页面代码中用到的“${pageContext.request.serverName} ”、“${header['user-agent']}”和“${pageContext.request.remoteAddr}”都是JSP2.0中定义的JSP EL表达式。

2.1.3 一个处理JDO资源的工具类:jdobbs.Sys
  我们先来写一个非常关键的工具类:jdobbs.Sys,这个类负责处理一些基本的JDO 存储管理器获取、资源释放、线程同步方面的事务。关于其中的每个细节,都可以用一大篇文章来说明(详情见{http://www.jdocentral.com/forums/index.php?s=8bf08748ea2b95fe52e0d25c7a489732&act=SF&f=11}中的相关讨论),这里为了简单起见,只简单地描述一下这个工具类的目标: 1. 保证每个JSP页面请求的服务端线程中所有的业务逻辑方法共享同一个javax.jdo.PersistenceManager,除非在处理过程中间显式地关闭当前的PersistenceManager。这将采用java.lang.ThreadLocal接口实现

2. 保证每个页面请求结束后,处理请求过程中涉及的JDO资源全部被释放(即关闭用到的PersistenceManager)。这将采用javax.servlet.Filter接口实现


  我们来看看下面的Sys.java源码:


package jdobbs;

import javax.jdo.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;

public class Sys extends ThreadLocal implements Filter {

/** 获取PersistenceManagerFactory */
public static PersistenceManagerFactory pmf() {
if(pmf == null) {
Properties p = new Properties();
InputStream is = Sys.class.getResourceAsStream("/jdobbs.jdogenie");
try {
p.load(is);
} catch(IOException ex) {
throw new RuntimeException("初始化PersistenceManagerFactory时配置文件读取失败!",ex);
}
pmf = JDOHelper.getPersistenceManagerFactory(p);
}

return pmf;
}

/** 获取PersistenceManager
* 通过使用ThreadLocal对象,使同一线程中每次调用本方法,都会返回同一PM对象。
*/
public static PersistenceManager pm() {
if(threadLocal == null) {
threadLocal = new Sys();
}
return (PersistenceManager)threadLocal.get();
}

/** 用于释放本次线程中使用到的JDO资源
* @return 是否有未完成的Transaction,便于后台日志区别记录
*/
public static boolean cleanupResource() {
return threadLocal != null && threadLocal.cleanup();
}

private static PersistenceManagerFactory pmf;

//============= 以下是ThreadLocal的相关方法==============
private static Sys threadLocal; //一个用于保证同一线程只访问同一PM对象的控制器

/**
* 获取一个与当前线程相关的PersistenceManager
* @return 一个PersistenceManager类型的对象,调用者需要强制转换一下类型。
*/
public Object get() {
PersistenceManager pm = (PersistenceManager)super.get();
if(pm == null || pm.isClosed()) {
pm = pmf().getPersistenceManager();
set(pm);
}

return pm;
}

/**
* 释放所有与本线程相关的JDO资源
* @return 是否有未完成的Transaction,便于后台日志区别记录
*/
public boolean cleanup(){
PersistenceManager pm = (PersistenceManager)super.get();
if(pm == null) return false;
if(pm.isClosed()) {
set(null); return false;
}

boolean tsActive = false;
try {
Transaction ts = pm.currentTransaction();
tsActive = ts.isActive();
if(tsActive) ts.rollback();

} finally {
set(null);
pm.close();
}

return tsActive;
}
//============= 以上是ThreadLocal的相关方法==============

//============= 以下是JSP Filter的相关方法==============
public void init(FilterConfig p0) throws ServletException {}
public void destroy() {}

/** JSP页面(Servlet)处理的过滤器方法,用于JSP执行完毕后检测并释放用到的JDO资源 */
public void doFilter(ServletRequest req, ServletResponse res, FilterChain
  fc) throws ServletException,IOException {
try {
fc.doFilter(req,res);
} finally {
cleanupResource();
}
}
//============= 以上是JSP Filter的相关方法==============

}


  简单地说,这个类提供了一个静态的pm()方法,可以获取一个JDO的存储管理器PersistenceManager,这个方法将是以后的代码中用到最多的方法。
  其中的Sys. pmf()用于获取PersistenceManagerFactory,这个方法中用到了一个配置文件:jdobbs.jdogenie,这个文件是我们下面将要生成的JDOGenie的配置文件,也就是将在workbench中产生应用配置文件,其中包括数据库连接地址、用户、密码信息,以及一些性能调节的设置。这个配置文件jdobbs.jdogenie将被放置在bbs/WEB-INF/classes/目录下,以便程序读取。

  这个Sys类使用了Servlet的过滤接口来保证每个JSP执行完毕后相关的JDO资源得以释放。因此,编译这个类时,一定要将Servlet2.4的支持包包含在CLASSPATH中,这个包即是“<resin>/lib/j2sdk-24.jar”文件。为了以后编译和进行其它工作的方便,我们编写一个Ant脚本作为执行各种批处理(包括编译)的工具。

2.1.4 配置JSP过滤器
  为了让前面的JSP Filter生效,我们需要将其配置到我们的Web应用中去,准确地说,就是创建(或更改)bbs/WEB-INF/web.xml文件,我们更改该文件后,看看它的源代码:web.xml

<web-app>


<filter>

<filter-name>JDO_Resource_Cleaner</filter-name>

<filter-class>jdobbs.Sys</filter-class>

</filter>


<filter-mapping>

<filter-name>JDO_Resource_Cleaner</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>


</web-app>


  这段内容保证了每个JSP页面请求处理完后,Sys.cleanup()方法将得到执行,以检测并清除用到的JDO资源。

2.1.5 Ant脚本
  按Ant的标准,我们编写一个名为“build.xml”的脚本,并且,为了配置上的方便,我们将这个文件放到bbs/WEB-INF/目录下。

  我们看看这个Ant脚本的源代码:build.xml

<project name="jdobbs" default="enhance">

<property name="resin" location="D:/resin-3.0.4" />


<path id="cp">

<pathelement path="${resin}/lib/jsdk-24.jar" />

<pathelement path="classes" />

<fileset dir="lib" includes="*.jar" />

</path>


<target name="compile">

<javac srcdir="classes" classpathref="cp" debug="true" />

</target>


<target name="enhance" depends="compile" description="Enhance the compiled classes">

<taskdef resource="jdogenie.tasks" classpathref="cp" />

<jdo-enhance project="${ant.project.name}.jdogenie" outputdir="classes" />

</target>


</project>


  将这个文件放到bbs/WEB-INF/目录下后,我们开启一个DOS命令行窗口,并进入该目录,运行一下:“ant compile”,将会看到如下结果:

D:\resin-3.0.4\webapps\bbs\WEB-INF>ant compile

Buildfile: build.xml


compile:

[javac] Compiling 1 source file to D:\resin-3.0.4\webapps\bbs\WEB-INF\classes


BUILD SUCCESSFUL

Total time: 2 seconds

D:\resin-3.0.4\webapps\bbs\WEB-INF>


  这个结果表示我们的Ant脚本已经成功运行了。如果你看到的结果是:

'ant' 不是内部或外部命令,也不是可运行的程序

或批处理文件。

  那就说明你的Ant没有配置好(比如你开了DOS窗口后才去更改系统的PATH环境变量),这方面的问题参见前面的Ant安装与配置进行解决。

  脚本的内容这里不一一解释了,请参考Ant的帮助。这里只说明一下:“enhance”批处理中通过jdogenie.jar中的Ant任务定义,使用了一个“jdo-enhance”任务,这个任务就是用来增强类代码的。


  好了,进行了以上这些准备工作,为确信以上的工作都没有出现错误,我们再次从浏览器访问一下首页,结果与最开始的首页完全一样,符合预期。


  接下来,我们就可以开始进行真正的JDO分析和设计了。

2.2 功能需求
  我们最初的需求很简单,就是让网友可以在这个系统中交流,以发贴、回复的形式,简单地看,可以说这是一个留言本系统。我们要达到以下目标: 1. 网友进入主页时,系统列出目前所有的主题,按时间顺序从近到远排列。

2. 网友可以在主页下方的发贴表单中发表新主题,包括标题和内容

3. 其它网友在主页的贴子列表中点击某个标题可以阅读这个主题的详细内容,包括所有的回贴内容。所有回贴按照时间顺序排列在主题主贴后面

4. 可以在主题详细内容页面尾部的回贴表单中回复这个主题

5. 每个网友发表主题或贴子时,系统需要记录该贴子发表时的客户端IP地址

6. 系统提供一个高级搜索功能,让网友可以根据时间、主题标题、内容或回复内容、IP搜索主题

2.3 分析、数据对象模型与JDO集成
  通过对需求的分析,我们发现,系统中需要存储的信息就是网友提交的主题或者回复。主题和回复都需要记录发贴的网友的IP地址,都有文字内容,但二者又稍有不同,主题可以有一个标题,而回复不需要(目的是为了方便回贴),另外,一个回复贴子一定是针对一个主题的。

  从面向对象的角度出发,我们将以上的数据包装成为下列的对象模型:

  (后面我们会看到这个图是如何弄出来的) 

2.3.1 编写数据类源码
  我们根据贴子的共性,编写一个基类:Post(贴子),代表所有的主题和回复,具有贴子所具备的几个基本属性。而主题类我们用Topic来表示,它从Post继承;回复类我们用Reply来表示,它有一个属性:topic,表示所回复的主题。主题和回复之间具有一对多关系,体现在Topic.replies和Reply.topic属性上。为了JSP2.0中的JSP EL的访问,我们给每个属性加上getter/setter(很多IDE工具都提供自动添加getter/setter的功能)。

  下面看看这三个文件的源代码(注意,都放在WEB-INF/classes/jdobbs/目录下):

贴子类Post.java:

package jdobbs;


import java.util.*;


/**

* 网友所发表的贴子,包括话题和回复

*/

public class Post {


/** 贴子内容 */

String content;


/** 贴子内容的长度 */

int length;


/** 发贴时客户机器的IP地址 */

String ip;


/** 发表本贴的时间 */

Date postTime;


public String getContent() {

return content;

}


public void setContent(String value) {

content = value;

}


public int getLength() {

return length;

}


public void setLength(int value) {

length = value;

}


public String getIp() {

return ip;

}


public void setIp(String value) {

ip = value;

}


public Date getPostTime() {

return postTime;

}


public void setPostTime(Date value) {

postTime = value;

}

}


主题类Topic.java:

package jdobbs;


import java.util.*;


/**

* 话题

*/

public class Topic extends Post {


/** 标题 */

String title;


/** 回复数 */

int replyCount;


/** 所有回复 */

List replies;


/** 最后更新,即最后被回复的时间 */

Date lastUpdate;


public String getTitle() {

return title;

}


public void setTitle(String value) {

title = value;

}


public int getReplyCount() {

return replyCount;

}


public void setReplyCount(int value) {

replyCount = value;

}


public List getReplies() {

return replies;

}


public void setReplies(List value) {

replies = value;

}


public Date getLastUpdate() {

return lastUpdate;

}


public void setLastUpdate(Date value) {

lastUpdate = value;

}

}


回复类Reply.java:

package jdobbs;


/**

* 回复

*/

public class Reply extends Post {


/** 所回复的话题 */

Topic topic;


public Topic getTopic() {

return topic;

}


public void setTopic(Topic value) {

topic = value;

}

}


  为了在下面使用JDOGenie工具来配置JDO环境,我们先在build.xml所在目录中运行一下编译任务:ant compile,编译这几个类。

2.3.2 配置JDOGenie,自动创建system.jdo元数据文件、自动建数据库,等等
  接下来,我们用JDOGenie来实现这个对象模型。注意,接下来这几步很重要!

  我们进入<jdogenie>/目录,运行workbench.bat,开始我们的JDO之旅。在主窗口中,我们通过菜单“FileàNew Project…”新建一个JDOGenie项目(这个项目实际上就是JDOGenie的配置文件),在出现的项目文件对话框中,我们选择<resin>/webapps/bbs/WEB-INF/classes/目录,并在文件名输入栏中输入项目名称(也就是配置文件的名称):“jdobbs.jdogenie”,注意,请输入完整文件名。如图:

  点击确定后,我们将看到一个项目配置设置的对话框。在这个配置对话框的左边列出配置项,右边则每项的配置内容。注意,带目录图标的“Project”和“Datastore”也是配置项。我们将在这个对话框中逐项地配置必须的信息:

1. 首先出现的是Project属性设置,即左边的Project项,在此项中,我们将“Non-transactional read”检查框选中,这样可以不用声明事务就直接通过存储管理器(PersistenceManager)访问数据库中的对象。如图:

2. 接下来是Ant的集成配置,目的是便于直接在工作台中调用Ant完成数据类的编译和增强。我们需要输入ant.bat和build.xml所在的路径,以便调用。如图:


  当然,我们也可以总是手工地在命令行调用Ant,这只需要将上图中的“Disable Ant”选中即可。

3. CLASSPATH设置。这里需要加入数据类的根路径和MySQL的JDBC包,如图:

4. 指定Metadata文件。按照JDO规范的要求,必须用.jdo结尾的文件(也称元数据或描述符)来描述需要存储的数据类。我们选择使用CLASSPATH根目录下的system.jdo文件来描述本系统中所有需要存储的数据类。先选择配置对话框左边的“JDO Meta Data Files”,出现如下对话框:

  点击按钮“New”在WEB-INF/classes/下新建一个system.jdo文件,如图:

  点击“保存”按钮,回到配置对话框:

5. 在“Project”部分的剩下几个配置项主要用于性能优化等方面的调节,我们暂时不考虑。现在直接点击“Datastore”项,进入数据库连接信息配置项,如图:

  点击“Choose”按钮,选择MySQL类型的数据库,然后在URL栏中输入到本机MySQL数据库的连接:“jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=GBK”,该URL中的GBK设置保证MySQL处理中文时不会乱码。配置好后,界面如下:

  现在,我们可以点击下方的“Test”按钮来检测数据库是否能连通(在此之前,请先检查一下MySQL是否已经运行)。如果不能连通,请检查前面的配置是否正确(Classpath配置中是否加入了mysql.jar,URL是否输入正确)


  到此为止,“Datastore”部分剩下的几项配置都可暂不理会,直接点击最下方的“OK”按钮关闭配置对话框。这时出现的是一个空的界面,如图:

  在这里,简单介绍一下JDOGenie的界面,左边是几个大按钮,代表各个方面的功能(前面已经介绍过),从上到下依次是:类树、类图、类列表、数据库结构、JDO查询、远程控制台。后面会介绍这些功能。

  我们现在将前面编写的数据类添加到项目中,这个步骤将生成JDO规范中要求的.jdo元数据文件。在上面的界面的上半部分的类列表中点击右键,在弹出菜单中选择“Add Classes…”,这时系统会列出从CLASSPATH中找到的.class类文件,我们选择其中的三个:Post、Topic、Reply:

  确定后,系统提示放入哪个元数据文件中,并且列出了前面创建的“system.jdo”文件。直接点击“OK”即可。我们将看到主窗口变成了下面的样子:

  工具条上的第四个按钮“JDO Metadata Compile”变成了红色,表示system.jdo中的信息中有歧义,点一下这个按钮看看详细原因:

  原来是系统不知道Topic类中的replies列表(List)的元素类型,在主窗口中选中Topic类,在界面下半部分的类属性列表中,在replies属性行上点击右键,选择“Field Properties…”,进入replies属性设置的对话框,在对话框中,我们需要设置两项:第一项,在“Element Type”中选择jdobbs.Reply类,表示replies列表的元素是Reply对象;第二项,在“Inverse field”中选择“topic”,表示Topic.replies与Reply.topic是一对双向关系,任何一边的改动都会影响到另一边。如图:

  设置好后,点击这个对话框右上角的“”按钮关闭它,现在在主窗口中,工具条上的第四个按钮已经变成绿色()了,表示元数据已经没有问题了。我们保存一下项目:“File->Save”,现在就可以增强我们的数据类了。选择菜单“BuildàCompile & Enhance”或者点击工具条上的第五个按钮“”,我们将看到成功编译和增强的信息:

  下面我们需要为我们的数据类建立相应的数据表,我们点击一下左边的大按钮“ Database schema operations…”,系统会列出当前的数据类所需要的数据表结构,这里我们只看到一个表,因为我们的三个类相互之间是继承关系,JDOGenie对继承的类用同一个表来表示。我们选择菜单“BuildàRecreate Schema”,在数据库中生成这个表结构(如果是以后改变了类,就不能再重建了,而需要在JDO查询区“Queries”中用ALTER TABLE的SQL语句来解决,否则会丢失数据):

  以上的一系列配置过程,就是我们集成JDO的过程,乍一看,好象配置非常复杂,其实前面这一系列过程很快就可以完成,理解了JDO的原理后会觉得很简单。以后,这个JDOGenie的工作台workbench.bat就是我们的工作环境了。我们进一步更改类源码后,只需要在这里点击一下编译按钮“”,就可以将最新的源文件编译并增强了。如果增加了更多的数据类,也只需要在这个工作台中将新的类加入到项目中(即元数据中)即可。

  最后,我们回想一下前面提到的数据类图,该图实际上也是在JDOGenie的工作台中生成的。我们点击左边的大按钮“ Class and E/R diagrams”进入类图区,在窗口中点右键,选择“Choose Classes…”,将所有的数据类都加入到图中,就会看到包含Post、Topic、Reply三个类的类图,对位置稍加调整,就可以得到前面的类图了,如图:

  好了,以上所介绍的是JDOGenie的工作台图开操作界面的诸多细节,实际上,我们还没有涉及JDO开发中的核心部分:API的使用。不过相信经过以上的介绍,读者对作为一个JDO实现的JDOGenie也有了比较全面的认识了。然而,对于JDO开发来说,不同的产品有不同的配置工具和配置操作,各有特色,比如KodoJDO的数据库是可以配置为在运行时动态生成和动态与数据类模型同步的,这一点深受开发人员喜爱。可喜的是,JDOGenie很快也将加进这一非常有利于快速开发和维护的特性。

  在我们开始真正的JDO开发之旅之前,我们先休息一会儿,回顾一下前面提到过的各个层次的服务器,包括数据库、JSP服务器、JDO产品等等。在本文的《开发篇》中,将给读者揭开JDO的神秘面纱,让读者看清楚开发过程中的每一个细节……

  本文的版权属于笔者本人,但欢迎转载,前提是注明出处和原作者。另外,欢迎在我的专栏中查看我的另几篇文章,并提出宝贵意见!





对该文的评论 人气:2948 
      KevinAAA (2004-3-31 17:01:19) 

写的真的很不错,值得收藏!

      sqcool2000 (2004-3-10 17:28:27) 

我按照说明做了,创建表的时候出现一个小问题,提示已经成功,但是就是没有表真正生成。我没有写Sys.java,是不是这里有问题呢

      fkpwolf (2003-12-13 15:47:32) 

写的如此详细,一个字,好!

      sun2bin (2003-12-12 13:14:29) 

EJB效率不足,配置、调试麻烦,适合数据重要但时间无所谓的大公司 Hibernate免费且用户多,功能也挺强,不过配置麻烦,开发也有些烦琐,而性能则不知道如何 JDO使用开发简单,维护方便,不过目前状况是各家特点不一,产品差异还较大,标准的JDO1.0功能有限。

      jenny_cai (2003-12-8 13:51:59) 

高手是怎样练成的,就是这样练成的。希望能解释一下各种ORM的优点和不足。ENTITY EJB,HIBERNATION,JDO,随更好?[img][/img]
分享到:
评论

相关推荐

    Spring in Action(第二版 中文高清版).part2

    7.4 保护Web应用程序 7.4.1 代理Spring Security的过滤器 7.4.2 处理安全上下文 7.4.3 提示用户登录 7.4.4 处理安全例外 7.4.5 强制Web安全性 7.4.6 确保一个安全的通道 7.5 视图层安全 7.5.1 有条件地渲染...

    Spring in Action(第二版 中文高清版).part1

    7.4 保护Web应用程序 7.4.1 代理Spring Security的过滤器 7.4.2 处理安全上下文 7.4.3 提示用户登录 7.4.4 处理安全例外 7.4.5 强制Web安全性 7.4.6 确保一个安全的通道 7.5 视图层安全 7.5.1 有条件地渲染...

    Spring in Action(第2版)中文版

    7.4保护web应用程序 7.4.1代理springsecurity的过滤器 7.4.2处理安全上下文 7.4.3提示用户登录 7.4.4处理安全例外 7.4.5强制web安全性 7.4.6确保一个安全的通道 7.5视图层安全 7.5.1有条件地渲染内容 7.5.2...

    电力系统中基于MATLAB的价格型需求响应与电价弹性矩阵优化

    内容概要:本文详细介绍了如何利用MATLAB进行价格型需求响应的研究,特别是电价弹性矩阵的构建与优化。文章首先解释了电价弹性矩阵的概念及其重要性,接着展示了如何通过MATLAB代码实现弹性矩阵的初始化、负荷变化量的计算以及优化方法。文中还讨论了如何通过非线性约束和目标函数最小化峰谷差,确保用户用电舒适度的同时实现负荷的有效调节。此外,文章提供了具体的代码实例,包括原始负荷曲线与优化后负荷曲线的对比图,以及基于历史数据的参数优化方法。 适合人群:从事电力系统优化、能源管理及相关领域的研究人员和技术人员。 使用场景及目标:适用于希望深入了解并掌握价格型需求响应机制的专业人士,旨在帮助他们更好地理解和应用电价弹性矩阵,优化电力系统的负荷分布,提高能源利用效率。 其他说明:文章强调了实际应用中的注意事项,如弹性矩阵的动态校准和用户价格敏感度的滞后效应,提供了实用的技术细节和实践经验。

    一级医院医疗信息管理系统安装调试技术服务合同20240801.pdf

    一级医院医疗信息管理系统安装调试技术服务合同20240801.pdf

    表5 文献综述.doc

    表5 文献综述.doc

    36W低压输入正激电源, 正激变压器设计方法步骤及谐振电感的设计方法,主要讲诉了正激电源变压器测的输入输出参数,按输入的条件设计相关的变压器的参数,同时将输出电感的设计方法一并例出,详细的设计步骤

    36W低压输入正激电源 变压器电感设计

    基于YOLOv8的深度学习课堂行为检测系统源码(含检测图片和视频)

    基于YOLOv8的深度学习课堂行为检测系统源码,软件开发环境python3.9,系统界面开发pyqt5。在使用前安装python3.9,并安装软件所需的依赖库,直接运行MainProgram.py文件即可打开程序。模型训练时,将train,val数据集的绝对路径改为自己项目数据集的绝对路径,运行train.py文件即可开始进行模型训练,内含项目文件说明,以及检测图片和视频。

    odbc-oracle zabbix模版原版

    odbc_oracle zabbix模版原版

    基于纳什谈判理论的风光氢多主体能源系统合作运行方法——综合能源交易与优化模型

    内容概要:本文探讨了利用纳什谈判理论来优化风光氢多主体能源系统的合作运行方法。通过MATLAB代码实现了一个复杂的优化模型,解决了风电、光伏和氢能之间的合作问题。文中详细介绍了ADMM(交替方向乘子法)框架的应用,包括联盟效益最大化和收益分配谈判两个子任务。此外,还涉及了加权残差计算、目标函数构造、可视化工具以及多种博弈模式的对比等功能模块。实验结果显示,合作模式下系统总成本显著降低,氢能利用率大幅提升。 适合人群:从事能源系统研究的专业人士、对博弈论及其应用感兴趣的学者和技术人员。 使用场景及目标:适用于需要优化多主体能源系统合作运行的场合,如工业园区、电网公司等。主要目标是提高能源利用效率,降低成本,增强系统的灵活性和稳定性。 其他说明:代码中包含了丰富的可视化工具,能够帮助研究人员更好地理解和展示谈判过程及结果。同时,提供了多种博弈模式的对比功能,便于进行性能评估和方案选择。

    C#与Halcon联合编程实现高效视觉几何定位与测量框架

    内容概要:本文详细介绍了如何利用C#与Halcon联合编程构建高效的视觉几何定位与测量框架。主要内容涵盖模板创建与匹配、圆测量、数据持久化以及图像采集等方面的技术细节。首先,通过创建形状模板并进行匹配,实现了工件的精确定位。接着,针对圆形物体的测量,提出了动态ROI绘制、亚像素边缘提取和稳健圆拟合的方法。此外,还讨论了模板管理和图像采集的最佳实践,确保系统的稳定性和高效性。最后,强调了Halcon对象的内存管理和错误处理机制,提供了实用的优化建议。 适合人群:具备一定编程基础,尤其是对C#和Halcon有一定了解的研发人员和技术爱好者。 使用场景及目标:适用于工业生产线上的自动化检测设备开发,旨在提高工件定位和尺寸测量的精度与效率。主要目标是帮助开发者掌握C#与Halcon联合编程的具体实现方法,从而构建稳定可靠的视觉检测系统。 其他说明:文中提供了大量实战代码片段和调试技巧,有助于读者快速理解和应用相关技术。同时,作者分享了许多实际项目中的经验和教训,使读者能够避开常见陷阱,提升开发效率。

    QT6 C++视频播放器实现(基于QGraphicsVideo)

    QT视频播放器实现(基于QGraphicsView)

    评估管线钢环焊缝质量及其对氢脆的敏感性.pptx

    评估管线钢环焊缝质量及其对氢脆的敏感性.pptx

    机器学习(预测模型):专注于 2024 年出现的漏洞(CVE)信息数据集

    该是一个在 Kaggle 上发布的数据集,专注于 2024 年出现的漏洞(CVE)信息。以下是关于该数据集的详细介绍:该数据集收集了 2024 年记录在案的各类漏洞信息,涵盖了漏洞的利用方式(Exploits)、通用漏洞评分系统(CVSS)评分以及受影响的操作系统(OS)。通过整合这些信息,研究人员和安全专家可以全面了解每个漏洞的潜在威胁、影响范围以及可能的攻击途径。数据主要来源于权威的漏洞信息平台,如美国国家漏洞数据库(NVD)等。这些数据经过整理和筛选后被纳入数据集,确保了信息的准确性和可靠性。数据集特点:全面性:涵盖了多种操作系统(如 Windows、Linux、Android 等)的漏洞信息,反映了不同平台的安全状况。实用性:CVSS 评分提供了漏洞严重程度的量化指标,帮助用户快速评估漏洞的优先级。同时,漏洞利用信息(Exploits)为安全研究人员提供了攻击者可能的攻击手段,有助于提前制定防御策略。时效性:专注于 2024 年的漏洞数据,反映了当前网络安全领域面临的新挑战和新趋势。该数据集可用于多种研究和实践场景: 安全研究:研究人员可以利用该数据集分析漏洞的分布规律、攻击趋势以及不同操作系统之间的安全差异,为网络安全防护提供理论支持。 机器学习与数据分析:数据集中的结构化信息适合用于机器学习模型的训练,例如预测漏洞的 CVSS 评分、识别潜在的高危漏洞等。 企业安全评估:企业安全团队可以参考该数据集中的漏洞信息,结合自身系统的实际情况,进行安全评估和漏洞修复计划的制定。

    QML Combobox 自动过滤,输入字符串后自动匹配

    博客主页:https://blog.csdn.net/luoyayun361 QML ComboBox控件,输入关键字后自动过滤包含关键字的列表,方便快速查找列表项

    【人工智能领域】人工智能技术发展历程、核心原理及应用指南:涵盖机器学习、深度学习、NLP和计算机视觉的全面介绍

    内容概要:本文全面介绍了人工智能技术的发展历程、核心技术原理、应用方法及其未来趋势。首先阐述了人工智能的定义和核心目标,随后按时间顺序回顾了其从萌芽到爆发的五个发展阶段。接着详细讲解了机器学习、深度学习、自然语言处理和计算机视觉等核心技术原理,并介绍了使用现成AI服务和开发自定义AI模型的应用方法。此外,还展示了智能客服系统、图像分类应用和智能推荐系统的具体实现案例。针对普通用户,提供了使用大模型的指南和提问技巧,强调了隐私保护、信息验证等注意事项。最后展望了多模态AI、可解释AI等未来发展方向,并推荐了相关学习资源。; 适合人群:对人工智能感兴趣的初学者、技术人员以及希望了解AI技术应用的普通大众。; 使用场景及目标:①帮助初学者快速了解AI的基本概念和发展脉络;②为技术人员提供核心技术原理和应用方法的参考;③指导普通用户如何有效地使用大模型进行日常查询和任务处理。; 其他说明:本文不仅涵盖了AI技术的基础知识,还提供了丰富的实际应用案例和实用技巧,旨在帮助读者全面理解人工智能技术,并能在实际工作中加以应用。同时提醒读者关注AI伦理和版权问题,确保安全合法地使用AI工具。

    本学习由 Matrix 工作室制作并开发,包括算法与数据结构的学习路线和各种题解

    本学习由 Matrix 工作室制作并开发,包括算法与数据结构的学习路线和各种题解。

    基于智慧图书馆基础业务流程Axure11高保真原型设计

    本项目致力于构建基于微服务架构的智慧图书馆管理平台,重点突破多校区图书馆异构系统间的数据壁垒。通过建立统一数据治理规范、部署智能分析模块、重构业务流程引擎,系统性实现以下建设目标:构建跨馆业务数据的标准化整合通道,实施容器化部署的弹性资源管理体系,开发具备机器学习能力的业务辅助决策系统,打造可量化评估的管理效能提升模型,最终形成支持PB级数据处理的分布式存储体系与全维度数据资产图谱。

    mysql中慢sql分析

    根据processlist查询出慢sql 1.修改配置文件中的mysql链接 2.目前是15秒执行一次获取执行时间在5秒上的sql,可以在配置中修改 3.执行后查出的慢sql会记录到log文件夹中以日期命名的txt文件中,可自行查验

    全域通航 低空经济服务平台建设实施方案.pptx

    全域通航 低空经济服务平台建设实施方案.pptx

Global site tag (gtag.js) - Google Analytics