您的位置:首页 > 编程语言 > Java开发

用Java EE 5实现的网上书店实例

2008-01-08 09:43 483 查看

用JavaEE5实现的网上书店实例

李力(ada.li@sun.com)

2007/10/23
本教程介绍了如何使用NetBeansIDE以及GlassFish构建一个典型的JavaEE5应用实例.该实例模拟网上书店,主要实现的是对订单的管理。用户可以购买图书,并修改订单.该实例覆盖了JavaDB,JPA(JavaPersistenceAPI),EJB3.0,JSF等技术应用.

目录

第一部分:环境准备


网上书店体系结构



教程使用环境



配置SunJavaSystemApplicationServer


第二部分:数据准备


创建数据库和表



创建表



配置JDBC资源


第三部分:实现JPA层与EJB层


创建企业项目



JPA



创建持久性单元



创建实体类



EJB



创建会话Bean


第四部分:实现Web层


Web



创建Servlet



测试



JSF与VisualWebPack



创建VisualWeb项目



浏览商品



查询订单



生成订单



删除订单


问题及解决
参考

网上商店说明

网上商店实现了商品浏览,用户可以进行订单查询,生成订单以及删除订单等操作。



教程使用环境

JavaSE5(或更高版本)



NetBeansIDE5.5.1中文版



NetBeansIDE5.5.1VisualWebPack中文版



SunJavaApplicationServerPE9.0UpdateRelease1(或更高版本)


配置SunJavaSystemApplicationServer

如果安装的NetBeansIDE与SunJavaSystemApplicationServer捆绑在一起,则表明已在IDE中注册了应用服务器,不需要对其进行配置。如果单独下载并安装了SunJavaSystemApplicationServer,则必须为IDE配置可用的应用服务器。
配置单独安装的服务器:


安装NetBeansIDE和SunJavaSystemApplicationServer后,启动IDE。



在“运行环境”窗口中,右键单击“服务器”节点,然后从弹出式菜单中选择“添加服务器”。



在“添加服务器实例”向导中,从“服务器”下拉列表中选择"SunJavaSystemApplicationServer",然后单击“下一步”。



输入应用服务器的安装位置,然后单击“下一步”。



缺省应用服务器域domain1的缺省用户名和口令如下:


用户名:admin



口令:adminadmin



请注意,如果在此处指定一个口令,则系统会将其存储在用户目录中,这可能会产生安全隐患。如果未在此处指定口令,则会在需要时提示您输入口令值。



单击“完成”。


创建数据库

在这节中使用SunJavaSystemApplicationServer捆绑的Derby数据库,完成创建数据库,创建表,建立数据库连接池,建立数据库资源等。
创建Derby数据库


启动NetBeansIDE后,如果尚未启动数据库服务器,请选择“工具”>“JavaDB数据库”>“启动JavaDB服务器”。



选择“工具”>“JavaDB数据库”>“创建JavaDB服务器”。



在“创建JavaDB服务器”输入如下信息:




数据库名称:bookshop



用户名:book



口令:book






图一:创建bookshop数据库


NetBeansIDE会自动在”运行环境”>”数据库”接点下建立bookshop的数据库连接。
图:bookshop数据库连接



如果bookshop数据库的jdbc节点标记显示为连接中断

,并且无法展开该节点,则表明IDE未连接到该数据库。要连接bookshop数据库,请右键单击bookshop数据库的jdbc节点,。如果出现“连接”对话框,请输入
book
作为口令,选中“在此会话期间记住口令”,然后单击“确定”。



如果未出现bookshop的数据库连接,在“运行环境”窗口中,右键单击“数据库”,然后从弹出式菜单中选择“新建连接”以打开“新建数据库连接”对话框。



从“名称”下拉列表中选择"JavaDB(Network)"。



在“数据库URL”文本框中,键入jdbc:derby://localhost:1527/bookshop。



将“用户名”设置为book,将“口令”设置为book,然后单击“确定”。



在建立连接后,请单击“确定”以关闭对话框。




2:新建bookshop数据库连接

创建表

到这一步,bookshop数据库是全新的,因此它是空的。现在,开始添加表和数据。NetBeansIDE可以使用表向导来逐个创建表,这个教程里使用SQL脚本.
使用SQL脚本创建表


右键单击bookshop数据库下的表节点,然后从弹出式菜单中选择”执行命令”




在新打开的”SQL命令1”窗口中,输入以下SQL。
点击”运行SQL”按钮,运行成功的话,可以在bookshop数据库连接的"表"节点,看到新生成三个表。



createtable"BOOK"."CUSTOMER"


(


"CUSTOMER_ID"CHAR(12)notnullprimarykey,


"CUSTOMER_NAME"VARCHAR(30),


"EMAIL"VARCHAR(40)


);




insertintocustomervalues('ada','AdaLi','ada.li@sun.com');




insertintocustomervalues('joey','JoeyShen','joey.shen@sun.com');




insertintocustomervalues('michael','MichaelLi','tao.li@sun.com');






createtable"BOOK"."PRODUCT"


(


"PRODUCT_ID"INTEGERnotnullprimarykey,


"PRODUCT_NAME"VARCHAR(100),


"PURCHASE_COST"DECIMAL(12,2)


);




insertintoproductvalues(1,'Java(TM)EE5Tutorial',34.64);




insertintoproductvalues(2,'JavaEE5DevelopmentusingGlassfishApplicationServer',32.50);




insertintoproductvalues(3,'EnterpriseJavaBeans3.0',31.49);




insertintoproductvalues(4,'SunCertifiedEnterpriseArchitectforJavaEEstudyGuide',32.99);




insertintoproductvalues(5,'JavaMEGameProgramming',49.99);






createtable"BOOK"."PURCHASE_ORDER"


(


"ORDER_NUM"INTEGERnotnullprimarykey,


"CUSTOMER_ID"CHAR(12)notnull,


"PRODUCT_ID"INTEGERnotnull,


"QUANTITY"SMALLINT


);




insertintoPURCHASE_ORDERvalues(1,'ada',1,1);




insertintoPURCHASE_ORDERvalues(2,'ada',5,1);




insertintoPURCHASE_ORDERvalues(3,'joey',2,2);









CUSTOMER



PRODUCT



PURCHASE_ORDER





右键单击表或列,然后从弹出式菜单中选择“查看数据”,可以查看表和列中的数据。


配置JDBC连接池和JDBC资源

数据库连接池是服务器为特定的数据库提供的一组可重用的连接。请求数据库连接的应用程序将从该池中获取连接。当应用程序关闭某个连接后,该连接将会返回到连接池中。连接池属性可能随数据库供应商的不同而有所不同。一些公共属性包括数据库名称的URL、用户名和口令等。
建立数据库连接池时,还将创建JDBC资源(也称为数据源)。JDBC资源为应用程序提供了数据库连接。通常,应用程序所访问的每个数据库都至少有一个JDBC资源。一个数据库可以有多个JDBC资源。
下面介绍如何在SunJavaSystemApplication上配置JDBC连接池和JDBC资源
1.启动SunJavaSystemApplication,在NetBeansIDE的”运行环境”窗口中的”服务器”节点下,右键单击”SunJavaSystemApplication”,选择”启动”
2.在浏览器地址窗口中,输入”http://localhost:4848”,出现管理控制台登录界面.缺省的管理员/密码:admin/adminadmin



配置JDBC连接池

接下来,将为bookshop数据库创建一个JDBC连接池,并定义数据库连接的特性。


在管理控制台的左窗格中,展开“资源”>"JDBC",然后选择“连接池”。



在“连接池”页中,单击“新建”以创建新的连接池。



在“创建连接池”向导的第一步,输入和选择如下内容。
名称:bookshopPool
资源类型:javax.sql.XADataSource
数据库供应商:JavaDB

点击"下一步按钮"。



在“创建连接池”向导的第二步,找到属性部分,修改以下属性值。
DatabaseName:bookshop
User:book
Password:book
ServerName:localhost
PortNumber:1527







属性设置完成后,点击同一页面"ping"按钮,测试设置是否正确。如果正确,会显示"Ping成功"的信息.



点击"完成"按钮,在SunJavaApplicationServer中创建bookshopPool连接池.


配置JDBC资源

必须为bookshop创建一个JDBC资源,以便让部署后的应用程序能够通过它连接到bookshop数据库。


在管理控制台的左窗格中,展开“资源”>"JDBC",然后选择“JDBC资源”。“资源”>"JDBC">“JDBC资源”页将在右窗格中打开。



单击“新建”。用于创建新JDBC资源的页将出现在右窗格中,输入或选择如下内容。
JNDI名称:jdbc/bookshopDS
池名称:bookshopPool



点击"确定"按钮,在SunJavaApplicationServer中创建JDBC资源jdbc/bookshopDS.





NetBeansIDE中可以直接创建JDBC连接池和JDBC资源



如果要将应用程序部署到SunJavaSystemApplicationServer,则在IDE中使用“新建文件”向导可以轻松地建立数据库连接池和所需的数据源。通过在IDE中打开“新建文件”向导,选择“Sun资源”类别,然后选择要创建的资源类型,可以为应用程序创建JDBC资源和连接池。使用“新建文件”向导可以执行以下操作:


通过从现有数据库连接或连接的数据库中提取连接信息,创建连接池。



使用现有连接池创建JDBC资源,或在向导内创建新的连接池


当使用“新建文件”向导建立连接池时,IDE将基于指定的连接生成所需的文件。在将应用程序部署到服务器时,会在SunJavaSystemApplicationServer中注册资源。
如果要将应用程序部署到SunJavaSystemApplicationServer以外的服务器,则需要通过编辑资源的源文件来建立资源。

创建企业项目

NetBeansIDE中,选择“文件”>“新建项目”(Ctrl-Shift-N)。从"企业"类别中选择“企业应用程序”,然后单击“下一步”。



将项目命名为BookshopApp,将服务器设置为"SunJavaSystemApplicationServer",将JavaEE版本设置为"JavaEE5",然后单击“完成”。



在NetBeansIDE的"项目"窗口中,会出现三个项目



BookshopApp
BookshopApp-ejb
BookshopApp-war


持久层

JavaEE5平台引入了新的Java持久性API(它是作为JSR-220的一部分开发的)。Java持久性API不但可以在EJB组件外部使用(例如,在Web应用程序和应用程序客户端中使用),而且还可以在JavaEE平台之外的JavaSE应用程序中使用。
Java持久性API具有以下主要功能:


实体是POJO与使用容器管理持久性(Container-ManagedPersistence,CMP)的EJB组件不同,使用新API的实体对象不再是组件,并且它们不再需要位于EJB模块中。



标准化的对象关系映射。新规范将对对象关系映射的处理方式进行标准化,从而使开发者不再需要了解特定于供应商的策略。Java持久性API使用标注来指定对象关系映射信息,但它仍支持XML描述符。



命名查询。现在命名查询是用元数据表示的静态查询。查询可以是Java持久性API查询或本地查询。这样会使重用查询变得非常简单。



简单的打包规则。由于实体Bean是简单的Java技术类,因此几乎可以在JavaEE应用程序中的任意位置将其打包。例如,实体Bean可以是EJB[code]JAR、应用程序客户端
JAR
WEB-INF/lib
WEB-INF/classes
的一部分,甚至是企业应用程序归档(EnterpriseApplicationArchive,EAR)文件中实用程序
JAR
的一部分。通过这些简单的打包规则,您不再需要创建EAR文件以使用来自Web应用程序或应用程序客户端的实体Bean。



分离的实体。由于实体Bean是POJO,因此可以对它们执行序列化,通过网络将其发送到其他地址空间,并在不识别持久性的环境中使用它们。这样,您就不再需要使用数据传输对象(DataTransferObject,DTO)。



EntityManagerAPI现在,应用程序编程人员可以使用标准EntityManagerAPI来执行涉及实体的
创建、读取、更新和删除
(CreateReadUpdateDelete,CRUD)操作。


IDE提供了处理新Java持久性API的工具。您可以通过数据库自动生成实体类,或手动对实体类进行编码。IDE还提供了用于创建和维护持久性单元的模板和图形编辑器。

创建持久性单元

持久性单元目的在于通知容器哪些实体类需要由实体管理器进行管理,以及这些实体需要使用哪些数据源信息。


在“项目”窗口中右键单击"BookshopApp-ejb"项目节点,然后选择“新建”>“文件/文件夹”以打开“新建文件”向导。



从“持久性”类别中,选择“持久性单元”,然后单击“下一步”,配置信息如


持久性单元名称:BookshopApp-ejbPU

持久性提供程序:TopLink(缺省)
数据源:jdbc/bookshopDS
使用使用Java事务API:是
表生成策略:无


单击“完成”,最后生成BookshopApp-ejb项目下生成persistence.xml,这个文件中定义了持久性单元的属性。






创建实体类

实体类用于表示要创建的关系数据库中的表。下面为bookshop数据库中的三张表创建实体类,实体类包括命名的查询标注、表示列的字段以及表示外键的关系。


右键单击"BookshopApp-ejb"项目节点,然后选择“新建”>“文件/文件夹”。



从“持久性”类别中,选择“通过数据库生成实体类”,然后单击“下一步”。



下一个窗口中,“数据源”选择”jdbc/bookshopDS”,点击”全部添加”按钮,将”可用表”中的三张表(CUSTOMER,PRODUCT,PURCHASE_ORDER)添加到”选定表”中,点击”下一步”按钮。



下一个窗口中,输入包名“bookshop.entities”,点击完成。




生成的Product实体类的部分代码如下:



......




@Entity


@Table(name="PRODUCT")




@NamedQueries(...{


@NamedQuery(name="Product.findByProductId",query="SELECTpFROMProductpWHEREp.productId=:productId"),


@NamedQuery(name="Product.findByProductName",query="SELECTpFROMProductpWHEREp.productName=:productName"),


@NamedQuery(name="Product.findByPurchaseCost",query="SELECTpFROMProductpWHEREp.purchaseCost=:purchaseCost")


})




publicclassProductimplementsSerializable...{




@Id


@Column(name="PRODUCT_ID",nullable=false)


privateIntegerproductId;




@Column(name="PRODUCT_NAME")


privateStringproductName;




@Column(name="PURCHASE_COST")


privateLongpurchaseCost;




......







实体类是一个简单的Java类。@Entity标注以将该类定义为实体类,其它标注的解释和说明可以查看相关文档。

EJB层

使用新的EJB3.0API,可以减少并简化开发者需要完成的工作量,从而可以更轻松地进行软件开发。换句话说,就是使用了更少的类和代码。这是因为现在容器承担了更多的工作,从而实现了这一目的。下面是新EJB3.0API的一些功能和优点:


只需很少的类和接口。您不再需要EJB组件的Home接口和对象接口,因为现在容器负责公开必要的方法。您只需提供业务接口。您可以使用标注来声明EJB组件,并且通过容器来管理事务。



不再需要部署描述符。您可以在类中直接使用标注,为容器提供以前在部署描述符中定义的依赖关系和配置信息。如果没有任何特殊说明,容器将使用缺省规则来处理最常见的情况。



查找简单。您可以通过
EJBContext
直接在类中查找JNDI名称空间中的对象。



简化了对象关系映射。新的Java持久性API允许您使用POJO中的标注将Java对象映射到关系数据库,从而使对象关系映射变得更简单透明。


在IDE中,您可以对EnterpriseBeans进行编码,就像对其他Java类进行编码一样,方法是:使用代码完成和编辑器提示实现正确的方法并使类与其接口保持同步。您不必使用特殊命令和对话框生成诸如业务方法或Web服务操作之类的内容,虽然这些命令仍可以帮助您熟悉JavaEE5代码的语法。

创建会话Bean

为Product实体类创建一个会话Bean。



右键单击EJB模块,然后选择“新建”>“文件/文件夹”。



从“持久性”类别中,选择“实体类的会话Bean”,然后单击“下一步”。



从可用的实体类列表中,选择"Product",单击“添加”,然后单击“下一步”。






包名设置为“bookshop.ejb”,选择“创建本地接口“。



单击“完成”。


单击“完成”后,将创建会话Bean类和接口(ProductFacade.java,ProductFacadeLocal.java)。
ProductFacade.java代码如下。



packagebookshop.ejb;




importbookshop.entities.Product;


importjava.util.List;


importjavax.ejb.Stateless;


importjavax.persistence.EntityManager;


importjavax.persistence.PersistenceContext;






/***//**


*


*@authorSun


*/


@Stateless




publicclassProductFacadeimplementsProductFacadeLocal...{




@PersistenceContext


privateEntityManagerem;







/***//**CreatesanewinstanceofProductFacade*/




publicProductFacade()...{


}






publicvoidcreate(Productproduct)...{


em.persist(product);


}






publicvoidedit(Productproduct)...{


em.merge(product);


}






publicvoiddestroy(Productproduct)...{


em.merge(product);


em.remove(product);


}






publicProductfind(Objectpk)...{


return(Product)em.find(Product.class,pk);


}






publicListfindAll()...{


returnem.createQuery("selectobject(o)fromProductaso").getResultList();


}





}






其中,标注@Stateless用于将类声明为无态会话Bean组件。标注@PersistenceContext表明,PersistenceContext资源已直接注入到会话Bean组件中。

Web层

[code]Web
层实现方式很多,这个教程里给出两种方式。一种是简单的Servlet,来显示Product信息,另外一种是使用VisualWebPack,实现对订单的管理。

创建Servlet

在“项目”窗口中,右键单击BookshopApp-war节点,然后选择“新建”>"Servlet"。



类名:ProductServlet,包名:bookshop.web。单击“下一步”。



在下一个“配置Servlet部署”窗口中,单击“完成”按钮。



在ProductServlet源代码编辑器中,任意位置单击鼠标右键,选择“企业资源”>“调用EnterpriseBean”。



在“调用EnterpriseBean”窗口中,选择“BookshopApp-ejb”->“ProductFacade”,点击完成。



这一步骤之后,IDE会在ProductServlet.java代码中,插入语句“@EJBprivateProductFacadeLocalproductFacade;”,表示对EJB的声明和引用。



修改后的ProductServlet.java代码如下:








......




publicclassProductServletextendsHttpServlet...{




@EJB


privateProductFacadeLocalproductFacade;





protectedvoidprocessRequest(HttpServletRequestrequest,HttpServletResponseresponse)




throwsServletException,IOException...{


response.setContentType("text/html;charset=UTF-8");


PrintWriterout=response.getWriter();





out.println("<html>");


out.println("<head>");


out.println("<title>ProductServlet</title>");


out.println("</head>");


out.println("<body>");





java.util.Listlist=productFacade.findAll();


java.util.Iteratorproducts=list.iterator();




while(products.hasNext())...{


bookshop.entities.Productobj=(bookshop.entities.Product)products.next();


out.println("<h2>Book"+obj.getProductId()+":"+obj.getProductName()+"</h2>");


};





out.println("</body>");


out.println("</html>");




out.close();


}


......




运行企业应用程序

在“项目”窗口中,右键单击BookshopApp项目,并选择“运行项目”。IDE会执行以下所有任务:


生成企业应用程序项目及其所有子项目(Web模块项目和EJB模块项目)。



如果服务器尚未运行,启动它。



如果企业应用程序已部署到应用服务器上,卸下它。



将企业应用程序部署到应用服务器上。



打开在指定的相对URL中的Web模块。


浏览器中自动打开的URL是"http://localhost:8080/BookshopApp-war/",显示空白的index.jsp,修改URL为"http://localhost:8080/BookshopApp-war/ProductServlet",运行结果如下:



JSF与NetBeansVisualWebPack

JSF(JavaServerFaces)是Web应用程序的一种框架,而NetBeansVisualWebPack是工具,实现了JSF的可视化编程.
下面介绍了使用NetBeansVisualWebPack开发网上商店的Web层,实现如下功能.


浏览商品



根据用户名查询对应订单



生成订单



删除订单


创建VisualWebPack项目

[code]创建VisualWeb项目

IDE中选择“文件”>“新建项目”来创建一个项目。在“类别”窗格中选择"Web",然后在“项目”窗格中选择“VisualWeb应用程序”,单击“下一步”。



在"新建VisualWeb应用程序"窗口中,输入如下内容:
项目名称:BookshopApp-vwp
项目位置:建议在BookshopApp目录下
服务器:SunJavaSystemApplicationServer
JavaEE版本:JavaEE5



单击“完成”,生成BookshopApp-vwp项目文件夹及相关文件。


[code]BookshopApp-vwp项目加入到BookshopApp企业应用程序项目中


[code]右键单击BookshopApp[code]项目,选择"属性".



在"选择项目"窗口中,浏览选择"B文件夹,"项目JAR文件"栏目下出现"dist/BookshopApp-vwp.war",点击"添加项目
[code]JAR
文件
"按钮.[/code]
ookshopApp-vwp




在"项目属性"窗口中,选择左侧栏中"生成"->"打包",点击右侧栏中"添加项目"按钮.




返回到"项目属性"窗口,点击"确定"按钮.





[code]BookshopApp-vwp项目中引用BookshopApp-ejb项目


[code]右键单击BookshopApp-vwp[code]项目,选择"属性".



在出现的"项目属性BookshopApp-vwp
[code]"窗口中,"类别"选择"库",右侧栏目中选择"添加项目".



在新出现的"添加项目"窗口中,浏览选择"BookshopApp-ejb",点击"添加项目JAR"文件.




[code]返回到"项目属性[code]BookshopApp-vwp
"窗口,点击"确定"按钮.





[code]测试


右键单击BookshopApp
[code]项目,选择"部署项目".



成功部署后,可以在"运行环境"->"服务器"->"SunJavaSystemApplicationServer"->"应用程序"->"企业应用程序"下,看到"BookshopApp"及子模块.





浏览商品

之前用Servlet实现了浏览商品的功能,接下来在Page1.jsp页面上利用JSF组件实现同样功能.
将组件添加到Web页面


[code]通过将组件从“组件面板”窗口拖放到可视设计器中的Web页上,如“按钮”、“静态文本”、“表”、“下拉列表”都属于组件面板的“基本”类别.



[code]更改这些组件的属性对其进行了定制。





配置下拉列表



打开“运行环境”窗口,展开“数据库”节点并检查是否已连接bookshop数据库。



展开bookshop数据库的jdbc节点,然后展开“表”节点。



将"CUSTOMER"节点拖动到可视设计器的下拉列表上。



拖动成功的话,下拉列表会显示"abc"内容,“概要”窗口的"Page1"部分中将显示"CustomerDataProvider"节点,"SessionBean1"部分中将显示"CustomerRowSet"节点。



右键单击“下拉列表”组件,然后从弹出式菜单中选择“绑定到数据”。



在"绑定到数据"窗口,"值字段"选择"CUSTOMER.CUSTOMER_ID","显示字段"选择"CUSTOMER.CUSTOMER_NAME",点击"确定"按钮.




配置表



将"bookshop"数据库节点>“表”>"PRODUCT"节点从“运行环境”窗口拖放到可视设计器中的“表”组件上。如果显示“选择目标”对话框,请确保选择table1,然后单击“确定”。



拖动成功的话,表的显示内容会改变,“概要”窗口的"Page1"部分中将显示"ProductDataProvider"节点,"SessionBean1"部分中将显示"ProductRowSet"节点。



右键单击该表,然后从弹出式菜单中选择“表布局”,在"表布局"对话框里修改"表头文字"等信息.。




测试



右键单击BookshopApp
[code]项目,选择"部署项目".



在浏览器中输入URL:“http://localhost:8080/BookshopApp-vwp/”,显示如下结果,下拉列表中显示的是CUSTOMER数据表的内容,而"图书列表"显示的是PRODUCT数据表的内容.







根据用户名查询订单

从下拉列表中选择用户,点击"查询"按钮,可以显示出该用户的订单内容.
创建新页OrderList


[code]在“项目”窗口中,右键单击”BookshopApp-vwp”节点,然后选择“新建”->“页”。



[code]文件名输入"OrderList",然后单击“完成”,在web下创建OrderList.jsp文件.



[code]将"静态文本","文本字段"和"表"三个组件从“组件面板”窗口拖放到可视设计器中的OrderList页上,修改相关属性.


配置表



将"bookshop"数据库节点>“表”>"PURCHASE_ORDER"节点从“运行环境”窗口拖放到OrderList
[code]页上可视设计器中的“表”组件上。[/code]



拖动成功的话,表的显示内容会改变,“概要”窗口的"Page1"部分中将显示"purchase_orderDataProvider"节点,"SessionBean1"部分中将显示"perchase_orderRowSet"节点。




[code]在“概要”窗口中,右键单击"SessionBean1"下的"perchase_orderRowSet"[code],然后从弹出式菜单中选择“编辑SQL语句”。这将打开SQL查询编辑器。[/code]



将"bookshop"数据库节点>“表”>"PRODUCT"节点从“运行环境”窗口拖放到SQL查询编辑器上面的窗口中.







[code]在窗口中心附近的网格区域,选择"CUSTOMER_ID”行,在"条件"栏中输入"=?"(注意输入时,切换到英文状态).取消"BOOK.PRODUCT.PRODUCT_ID"的显示.






[code]修改SQL语句,联合PURCHASE_ORDER和PRODUCT两个表,点击IDE菜单上的"保存"按钮



[code]



SELECTALLBOOK.PURCHASE_ORDER.ORDER_NUM,


BOOK.PURCHASE_ORDER.CUSTOMER_ID,


BOOK.PURCHASE_ORDER.PRODUCT_ID,


BOOK.PURCHASE_ORDER.QUANTITY,


BOOK.PRODUCT.PRODUCT_NAME,


BOOK.PRODUCT.PURCHASE_COST


FROMBOOK.PURCHASE_ORDER,BOOK.PRODUCT


WHEREBOOK.PURCHASE_ORDER.CUSTOMER_ID=?


ANDBOOK.PURCHASE_ORDER.PRODUCT_ID=BOOK.PRODUCT.PRODUCT_ID




[code]



打开OrderList.jsp的可视设计器,右键单击表,然后从弹出式菜单中选择“表布局”,在"表布局"对话框里增加修改字段,修改"表头文字"等信息







[code]OrderList.jsp[code]显示如下:





传递参数
接下来的步骤需要把Page1.jsp中的用户名传给OrderList.jsp"订单列表"的SQL查询.
首先,确定利用RequestBean来传递参数,打开Page1.jsp页面,


右键单击“概要”窗口中的"RequestBean1"节点,然后选择“添加”>“属性”。如果没有出现“添加”菜单项,请按Esc键,然后再次右键单击该节点。将属性命名为
customerId
,将其类型设置为
String
,然后单击“确定”。请注意,新添加的属性可能没有显示在“概要”窗口中。要显示该属性,请在可视设计器中单击鼠标右键,然后从弹出式菜单中选择“刷新”。也可以按照以下步骤所述,打开并保存RequestBean1源文件以显示该属性。






在“概要”窗口中,右键单击“RequestBean1”,然后从弹出式菜单中选择“编辑Java源代码”。



滚动到源文件底部以查看IDE为属性添加的
getCustomerId
setCustomerId
方法。



保存并关闭该文件。



打开Page1.jsp可视设计器,双击"查询"按钮,打开Page1.jsp源文件窗口,光标停留在"publicStringbutton1_action()"方法内,修改内容如下:








publicStringbutton1_action()...{


//待做事项:处理操作。返回的值是一个导航


//如果名称为null,则返回到同一页。


getRequestBean1().setCustomerId((String)dropDown1.getValue());


returnnull;


}




打开OrderList.jsp的Java源代码窗口,找到"prerender()"方法,修改内容如下:








publicvoidprerender()...{


StringcustomerId=getRequestBean1().getCustomerId();




if(customerId!=null)...{


textField1.setText(customerId);




try...{


getSessionBean1().getPurchase_orderRowSet().setString(1,customerId);


getPurchase_orderDataProvider().refresh();




}catch(java.sql.SQLExceptionex)...{


ex.printStackTrace();


}


}


}




指定页面导航
点击"BookshopApp-vwp"项目下的"页面导航",用鼠标拖动建立Page1.jsp和OrderList.jsp的跳转.





测试


[code]右键单击BookshopApp[code]项目,选择"部署项目".



在浏览器中输入URL:“http://localhost:8080/BookshopApp-vwp/”,选择用户名,点击"查询"按钮,可以看到如下页面:






生成订单

PURCHASE_ORDER数据表里包括了订单信息,一共四个字段,ORDER_NUM,CUSTOMER_ID,PRODUCT_ID,以及QUANTITY.在page1.jsp页面中,可以得到CUSTOMER_ID和PRODUCT_ID的信息,接下来的步骤是如何获得ORDER_NUM和QUANTITY
取得最大ORDER_NUM


[code]打开Page1.jsp可视设计器。



从“运行环境”窗口中选择“数据库”>"bookshop">“表”>"PURCHASE_ORDER"表,然后将它拖动到“概要”窗口中的"SessionBean1"节点上。



[code]在打开的“添加新的数据提供器”对话框中,单击“创建SessionBean1/purchase_orderRowSet1”单选按钮,将数据提供器的名称更改为maxOrder,然后单击“确定”。[code]RowSet






在SessionBean1中创建maxOrderDataProvider和maxOrderRowSet。




在“概要”窗口中,双击"SessionBean1">"maxOrderRowSet"以打开查询编辑器。在源代码窗格(上数第三个窗格)中单击鼠标左键。删除此处现有的SQL查询,然后输入以下查询后,点击"保存":
代码样例8maxOrderRowSetSQL

[code]SELECTMAX(BOOK.PURCHASE_ORDER.ORDER_NUM)+1ASMAXORDERIDFROMBOOK.PURCHASE_ORDER
MAXORDERID值将作为新订单的ORDER_NUM。


Page1.jsp中添加QUANTITY输入框


打开Page1.jsp可视设计器。右键点击"图书列表",打开“表布局”对话框。




单击“列”标签,然后单击“新建”,添加两个新列到表中。



QUANTITY输入框设置:



表头文本和页脚文本:数量



组件类型:[code]文本字段



值表达式:text



宽度:



水平对齐:
居中




垂直对齐:
中部




"购买"按钮列设置。



表头文本和页脚文本:



组件类型:
按钮




值表达式:删除



宽度:



水平对齐:
居中




垂直对齐:
中部






订单保存在数据库中


在page1.jsp可视设计器中,双击"购买"按钮,以打开Java编辑器。在Java编辑器中,插入点将位于该按钮的buttonAddOrder_action()事件处理程序方法中。




源代码编辑器中,任意位置单击鼠标右键,选择“企业资源”>“调用EnterpriseBean”。



在“调用EnterpriseBean”窗口中,选择“BookshopApp-ejb”->“PurchaseOrderFacade”,点击完成。



这一步骤之后,IDE会在Page1.java代码中,生成lookupPurchaseOrderFacade()方法。修改Page1.java代码中方法[code]buttonAddOrder_action()








privatePurchaseOrderFacadeLocallookupPurchaseOrderFacade()...{




try...{


Contextc=newInitialContext();


return(PurchaseOrderFacadeLocal)c.lookup("java:comp/env/ejb/PurchaseOrderFacade");


}




catch(NamingExceptionne)...{


Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exceptioncaught",ne);


thrownewRuntimeException(ne);


}


}






@EJBPurchaseOrderFacadeLocalejbOrderLocal;




publicStringbuttonAddOrder_action()...{


//待做事项:处理操作。返回的值是一个导航


//如果名称为null,则返回到同一页。


CachedRowSetDataProvidermaxOrder=getSessionBean1().getMaxOrderDataProvider();


maxOrder.refresh();




PurchaseOrderorder=newPurchaseOrder();


order.setOrderNum((Integer)maxOrder.getValue("MAXORDERID"));


order.setCustomerId((String)dropDown1.getValue());


order.setProductId((Integer)staticText1.getValue());


order.setQuantity(newShort((String)textField1.getValue()));


ejbOrderLocal.create(order);




getRequestBean1().setCustomerId((String)dropDown1.getValue());





return"case1";




}



测试


右键单击BookshopApp
[code]项目,选择"部署项目".



在浏览器中输入URL:“http://localhost:8080/BookshopApp-vwp/”,选择用户,输入数量,点击”购买”按钮.





删除订单

[code]打开OrderList.jsp可视设计器。右键点击"订单列表",打开“表布局”对话框。



单击“列”标签,然后单击“新建”,添加一个新列到表中。



表头文本和页脚文本:



组件类型:[code]按钮



值表达式:删除



宽度:



水平对齐:
居中




垂直对齐:中部




OrderList.jsp
[code]可视设计器中,双击"删除"按钮,以打开Java编辑器。在Java编辑器中,插入点将位于该按钮的buttonDelete_action()事件处理程序方法中。









publicStringbuttonDelete_action()...{


//待做事项:处理操作。返回的值是一个导航


//如果名称为null,则返回到同一页。




try...{


RowKeyrk=tableRowGroup1.getRowKey();




if(rk!=null)...{


purchase_orderDataProvider.removeRow(rk);


purchase_orderDataProvider.commitChanges();


purchase_orderDataProvider.refresh();}




}catch(Exceptionex)...{


log("ErrorDescription",ex);


error(ex.getMessage());


}





returnnull;


}













测试


[code]右键单击BookshopApp[code]项目,选择"部署项目".



在浏览器中输入URL:“http://localhost:8080/BookshopApp-vwp/”,选择用户,点击”查询”按钮.




[code]在下一个页面上,点击”删除”按钮.





问题与解决

问题:[code]Noobjectboundtonamejava:comp/env/jdbc/bookshopDS

SunJavaSystemApplicationServerlog
StandardWrapperValve[FacesServlet]:ServletFacesServlet
Servlet.service()抛出异常

[code]javax.naming.NameNotFoundException:Noobjectboundtonamejava:comp/env/jdbc/bookshopDS
atcom.sun.enterprise.naming.NamingManagerImpl.lookup(NamingManagerImpl.java:751)

atcom.sun.enterprise.naming.java.javaURLContext.lookup(javaURLContext.java:156)

atcom.sun.enterprise.naming.SerialContext.lookup(SerialContext.java:307)

atjavax.naming.InitialContext.lookup(InitialContext.java:392)

atcom.sun.sql.rowset.internal.CachedRowSetXReader.connect(CachedRowSetXReader.java:332)

atcom.sun.sql.rowset.internal.CachedRowSetXReader.readData(CachedRowSetXReader.java:126)

解决:修改Web程序中的web.xml,添加资源引用名称jdbc/bookshopDS





参考

[code]Http://www.netbeans.org







本文转自http://inezha.com/p/7642331/item39
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: