学习如何在 Bluemix 上创建一个 SQL 数据库,并将其添加到您的 Java Web 应用程序中。探索一个数据驱动、动态生成的网络商店,该商店会根据当前库存水平来改变外观。使用基于 Web 的 Bluemix SQL 数据库控制台查看和维护您的 SQL 数据库。
本教程是 developerWorks 上的 “Bluemix 基础” 教程系列的一部分。
第 3 步. 创建一个 SQL Database 服务实例并将它绑定到您的应用程序中
第 4 步. 将该应用程序导入您的 Eclipse 工作区中
第 6 步. 创建一个启用了数据的 WAR 并将它部署到 Bluemix
第 8 步. 通过 Bluemix SQL 数据库控制台访问 SQL 数据库
在前一篇教程 “将大量服务添加到您的应用程序中” 中,您已经了解到,服务只是 Bluemix 或第三方合作伙伴托管的代码,它们可以给您部署的 Bluemix 应用程序增添价值。
服务给您的应用程序带来了强大的功能,比如数据库、移动应用程序支持、分析、遗留系统集成和安全管理。从某种意义上讲,它们就像是插件,您随时可以向应用程序添加和绑定服务。
在可用的 Bluemix 服务中,数据库服务是最常使用的。而 SQL Database 服务是最流行的 Web 应用程序附加功能之一。
为经典的三层架构设计的大部分 Web 应用程序(比如 Java EE 应用程序)都在第三层需要一个数据库服务:
您的应用程序逻辑在无状态的应用程序层运行,而数据存储在数据库层。此架构使您只需增加应用程序实例的数量,就可以将应用程序扩展到越来越多的用户。
本教程将快速概述如何使用 Bluemix 将一个 SQL Database 服务添加到您的 Bluemix 应用程序中。
您将创建 SQL Database 服务的一个实例,并将它绑定到您的 Java 应用程序。然后,您将在数据库中创建表(也称为模式)并在其中填入数据。您将了解 Web 应用程序如何能够根据数据库中的数据来动态改变外观。最后,您将使用 Bluemix 上的 IBM SQL 数据库控制台,用它作为访问您的数据的替代方式。
Bluemix 上的 SQL Database 服务提供了 IBM DB2 的一个实例,您可以在自己的应用程序中绑定这些实例并立即使用它们。目前的免费 beta 计划提供了一个支持最多 10 个并发连接和 100 MB 的实例;其他计划可提供至多 500 GB 和 100 个并发连接的选项。
您应该将该应用程序部署到 Bluemix,创建 SQL Database 服务的一个实例并将该实例绑定到应用程序。
cf api https://api.ng.bluemix.net/
cf login
cf push your-app-name -p lauren.war
为应用程序选择的名称必须在 Bluemix 上是唯一的;换句话说,它不能被其他任何 Bluemix 用户使用。如果该名称(称为 “route”)已被使用,您将得到一个错误。
cf create-service sqldb sqldb_free laurenlandscapes
cf bind-service your-app-name laurenlandscapes
尽管该数据库服务现在已绑定到该应用程序,但应用程序中的代码尚未使用该数据库。接下来的几步将创建一个新 WAR 文件,并将其部署到 Bluemix,以解决此问题。
该项目现在已导入您的工作区中。您可以在左边的 Enterprise Explorer 窗格中看到它的结构。您可以注意到,Markers 窗格中列出了各种问题。在学习本教程的剩余内容时,可以安全地忽略它们。
您将在下一步中熟悉该项目和代码。
在 Eclipse 中打开您的项目,查看左边的 Enterprise Explorer 窗格:
展开 Java Resources 查看 Java 源代码文件。展开 WebContent 查看组成网站的两个 JSP 文件。
您应该已经在前面的教程中熟悉了此代码结构。
让我们来复习一下,针对 Lauren's Lovely Landscapes 商店的一个页面的 Web 请求首先经过 DispatchServlet,然后转发到三个 JSP 页面之一:alaska.jsp、antartica.jsp 或 australia.jsp,每种销售的照片印刷品一个页面。DispatchServlet 将一个 WebsiteTitle 对象附加到该请求,每个 JSP 页面都使用 WebsiteTitle 来将标题设置为 Lauren's Lovely Landscapes。
您将注意到的一个区别是:每册照片的 JSP 不再存在;现在有一个数据库驱动的 printdisp.jsp 页面来处理照片印刷品细节和定价的显示。
DispatchServlet 现在仅转发以下两个 JSP 中的一个:home.jsp 或or printdisp.jsp。针对主页的请求会在附加一个印刷品列表后被转发。然后,home.jsp 根据可用的印刷品来生成主页。
如果用户选中任何可用的印刷品,DispatchServlet 会将传入的请求转发给 printdisp.jsp,并向请求附加一个印刷品的信息。然后 printdisp.jsp 动态地生成该印刷品的标题、jpg 引用、描述和价格。
让我们试一下。首先,您需要创建一个新的启用了数据的 WAR,并将它部署到 Bluemix。
cf env your-app-name
这将显示可用于已部署的应用程序的环境变量。绑定的 SQL Database 服务的信息将显示在 VCAP_SERVICES 中。查找以下类似代码:
"VCAP_SERVICES": { "sqldb": [ { "credentials": { "db": "SQLDB", "host": "75.126.1.1", "hostname": "75.126.1.1", "jdbcurl": "jdbc:db2://75.126.1.1:50000/SQLDB", "password": "3pKxxxxxxx", "port": 50000, "uri": "db2://user1234:3pKxxxxxxx@75.126.1.1:50000/SQLDB", "username": "user1234" }, …
返回到 Eclipse 中,查找 persistence.xml 文件。您可能需要展开 JPA Content,或者查看 Java Resources > src > META-INF 下的内容。打开 persistence.xml 并修改以下属性:
javax.persistence.jdbc.url
javax.persistence.jdbc.user
javax.persistence.jdbc.password
更改这些属性值,使之与您的 VCAP_SERVICES 匹配。对于 javax.persistence.jdbc.url,确保仅修改了该属性值的第一部分,将其替换为来自 VCAP_SERVICES 的 “jdbcurl” 字段。
这些更改会将数据库访问代码链接到您创建的 SQL Database 服务实例。
cf push your-app-name -p laurendb.war
EclipseLink 为您的 Eclipse 添加了 Java Persistence API (JPA) 支持。对于本教程,您需要使用 EclipseLink 2.4.x 版,该版本兼容 jpa-2.0 — 这是唯一得到目前 Bluemix 上的 Liberty Profile 服务器可靠支持的版本。
JPA 自动化了在对象访问调用与关系数据库查询之间转换的单调的编码工作。自动化方式是,在您创建的带注释的传统 Java 对象 (POJO) 与位于一个关系数据库中的表中的行之间建立映射。
一个带注释的 POJO 在 JPA 中是一个实体。借助 JPA EntityManager,您可以填充 POJO 字段,然后持久保存它。这会在关联的关系数据库中实际写入或更新行。您还可以借助 EntityManager,使用 POJO 的实例从表中抓取行。
对于这个网络商店应用程序,Print.java(在 Java Resources > src > com.ibm.devworks.examples.lll 下)包含带注释的 POJO 定义,并表示 Lauren's 网络商店中有货的一个印刷品。这个类具有以下属性,它们与数据库字段具有一对一的映射关系:
POJO 与关系数据库之间的链接已在持久性单元 中介绍。您之前编辑的 persistence.xml 文件包含一个持久性单元的定义。除了 persistence.xml 之外,持久性单元可能还涉及其他映射文件。
例如,Print.java 通过 @Entity 注释从一个 POJO 转换为一个 JPA 实体:
@Entity public class Print implements Serializable { @Id @GeneratedValue private long id; private String title; private String description; private String imgsrc; private float price; private int quan; private static final long serialVersionUID = 1L;
这个 POJO 直接对应于 SQL 数据库中的一个 print 表。这个 POJO 的实例可映射到该表中的行。
数据定义语言或 DDL 通常为 SQL 数据库采用 CREATE TABLE 语句。通过检查一个实体(带注释的 POJO),然后生成一个 SQL 语句,JPA 可以自动生成关联的 SQL 表。表和字段名称可以通过更多注释来自动或显式地建立映射。
所有上述操作都通过 DDL 在 JPA 中完成。例如,丢弃和创建表的代码通过 EclipseLink 的 DDL 生成功能来创建:
propertiesMap.put(PersistenceUnitProperties.DDL_GENERATION,
PersistenceUnitProperties.DROP_AND_CREATE);
使用
Alaska 印刷品记录填充 print 表的代码类似于(em
是 JPA
EntityManager):
print = new Print(); print.setDescription("Lauren loves this photo even though she wasn't present when the photo was taken. Her husband took this photo on a guys' weekend in Alaska."); print.setTitle("Alaska"); print.setImgsrc("alaska.jpg"); print.setPrice(75); print.setQuan(1); em.persist(print);
在本教程的最后一步中,假设一批新的 Australia 印刷品已到货,所以您需要更新数据库中的可用数量。然后,您会看到网站在动态地发生变化,以包含新入库的商品。
AddAustraliaPrint.java 的操作方式类似于 DataSeeder.java。在一个 JPA 事务内,它抓取并寻找 Australia 印刷品,更新它的数量,然后将它持久保存回 SQL 数据库中:
List<Print> prints = em.createQuery("SELECT p FROM Print p ORDER BY p.id").getResultList(); for(Print print : prints ) { if (print.getTitle().equals("Australia")) { print.setQuan(3); em.persist(print); break; } } em.getTransaction().commit(); em.close();
如果想知道 home.jsp 如何处理脱销印刷品的动态呈现,您可在 JSP 中找到 JSTL <c:choose> 代码 —
结合使用 outofstock
CSS 样式类来更改它的外观:
<c:choose> <c:when test"${print.quan < 1}"> <div class="preview outofstock"> <a href="printdisp?id=${print.id}" class="outofstock"> ${print.title} - <i><small>(out of stock)</small></i><br> </c:when> <c:otherwise> <div class="preview"> <a href="printdisp?id=${print.id}"> ${print.title}<br> </c:otherwise> </c:choose>
除了 SQL Database 服务之外,Bluemix 还提供了许多有趣的服务,它们可以给您的应用程序增添价值和特性。例如,IBM Watson 的许多学习和认知功能 现在都能够以 Bluemix 服务的形式提供。您可能想浏览 Bluemix 服务目录,想象您可添加到已部署的 Web 应用程序中的所有新特性。
测试您在本教程中学到的知识。答案在下方。
1. d,2. d,3. b,4. b,5. e
在本教程中,您:
本教程是 developerWorks 上的 “Bluemix 基础” 教程系列的最后一篇!如果您已经完成了所有这些教程,那么您已经出师了!
要获取稳定的教程和技术资源流来帮助您继续使用 Bluemix 进行学习、开发和连接,请参阅 developerWorks 上的 Bluemix 页面。