作者:Fay Wang, 顾问软件工程师, IBM
Catalina Wei, 高级软件工程师, IBM
David Wisneski, 高级软件工程师, IBM
Asim Singh, 软件工程师, IBM
IBM WebSphere Application Server V7 交付了增强的 Java Persistence API (JPA) 实现,可支持 pureQuery,从而可以支持用于 DB2 的静态 SQL。本文介绍如何利用通过 IBM Data Studio pureQuery 运行时提供的静态 SQL 的性能和安全性,同时使用 JPA 实现其完整的对象关系功能。它几乎就像拿起您的蛋糕并将其吃掉一样简单。
在简要介绍一些有关 SQL 和 pureQuery 的信息之后,本文将对动态 (JDBC) 访问与通过 JPA 的静态 (pureQuery) 访问进行更详细的比较和对比。您将了解如何使用 WebSphere Application Server V7 中的静态生成器 (wsdb2gen) 实用工具来生成 SQL,然后了解如何将生成的 SQL 绑定到 DB2 包中。本文在结束时简要概述了如何使用 pureQuery 客户端优化功能作为对这里描述的静态生成器功能的补充。
先决条件
本文假设读者基本熟悉 JPA。有关有帮助的背景信息,请参阅参考资料。要执行本文中的步骤,您需要拥有 pureQuery 运行时。就本文而言,您可以使用可从试用版下载中获得的 Data Studio Developer 中包含的 pureQuery 运行时。
DB2 中的静态 SQL 是一个强大的功能,可以通过预先执行某些工作来简化运行时的数据访问,例如确定数据库访问路径。这可以使运行时执行得更快速并且更加一致。
静态 SQL 的安全模型也不同于动态 SQL 的安全模型。使用静态 SQL,用户仅收到执行绑定进程输出(称为包)的权限,并且该包包含 SQL 语句。换句话说,如果对某个表的所有访问都是静态的,则 DBA 将不需要授予对整个表或视图的访问权限,而是仅授予对包的访问权限。此外,可静态执行的 SQL 越多,则意味着恶意注入 的机会越少,恶意注入是动态 SQL 的一个众所周知的安全问题。
有关静态 SQL 的详细信息,请参阅参考资料。
pureQuery 是一个高性能的数据访问平台,可以简化数据访问的开发、优化、保护和管理。它包括:
pureQuery 可以帮助您以有助于优化性能的方式编写数据访问代码。此外,访问 DB2 数据时切换到静态 SQL 的简便性有助于同时提高性能(静态 SQL 一般运行得更快)和安全性。相对于 JDBC 和 SQLJ,pureQuery 具有许多优点。例如,pureQuery 不需要自定义程序,并且不要求在应用程序源代码中硬编码 SQL 语句即可实现静态执行。
WebSphere Application Server V7 所交付的 pureQuery 集成要求添加单独购买的 Data Studio pureQuery 运行时。Data Studio Developer 当前是可选的。
有关 pureQuery 的更多信息,请参阅参考资料。
|
在 Feature Pack for EJB™ 3 for WebSphere Application Server V6.1 中,JPA 实现使用 JDBC 作为访问数据库服务器的 API。每个 JDBC 调用在性质上是动态的,要求在运行时分析和优化 SQL 语句。图 2 显示了使用 JDBC 时从 JPA 应用程序到数据库的流。
在 WebSphere Application Server V7 中,您可以选择 pureQuery 而不是 JDBC 来访问 DB2 数据。使用 pureQuery 时从 JPA 应用程序到数据库的流如图 3 所示。
如图 3 所示,使用 pureQuery 来支持静态 SQL 的过程包括以下步骤:
用于收集 SQL 语句的 JPA 实用工具称为静态生成器,并使用 %WAS_HOME%\bin 目录中的 wsdb2gen 进行调用,如图 3 所示。此实用工具接受持久性单元名称以及其他参数作为输入,并生成一个输出文件,其中包含所有实体操作所需要的 SQL 语句,包括保存、删除、更新和查找。它还生成在 JPA 命名的查询的执行中需要的 SQL 语句。与命名的查询相反,动态查询中的 SQL 语句不能由静态生成器生成。(稍后将讨论如何使用 pureQuery 客户端优化功能在运行时捕获这些语句。)
请注意,在调用此工具前,您需要设置 pdq 运行时 JAR、db2jcc JAR 和实体类 JAR 的类路径(或增强实体类所在的目录),以及 persistence.xml 文件的位置。
就本文而言,包括在下载中的 JPA_EE_SAMPLE.ear 文件将用作示例,以指导您完成收集语句和创建包所需的步骤。该示例应用程序允许您创建、更新和删除客户并检索订单。该示例的持久性单元名称为 JPASample。
清单 1 向您显示了语法,以及如何使用命令行调用静态绑定器实用工具 wsdb2gen。
C:\was70\bin>wsdb2gen Syntax: WSDB2GEN -pu |
从清单 1 中可以看到,JPASample 中用于调用该实用工具的命令如下:
wsdb2gen –pu JPASample –url jdbc:db2://localhost:50000/demodb –user db2admin –pw passw0rd
该命令的输出是一个文件,其名称由持久性单元名称后面跟着后缀 .pdqxml 组成。在此例中,该文件名为 JPASample.pdqxml。pdqxml 文件被写到与 persistence.xml 文件相同的目录。在与 persistence.xml 配置文件相同的位置,需要将 pdqxml 文件打包在存档中,该位置一般为 META-INF 目录。
PureQuery 静态绑定器将使用 pu.pdqxml 文件来创建 DB2 包。可以从 WebSphere Application Server 管理控制台中或者通过使用管理命令调用静态绑定器:
wsadmin -lang jython
print AdminTask.listPureQueryBindFiles('[-appName JPA_EE_SAMPLE]')
print AdminTask.processPureQueryBindFiles( '[-appName JPA_EE_SAMPLE -classpath [C:\\pdq.jar C:\\pdqmgmt.jar C:\\db2jcc.jar] -url jdbc:db2://localhost:50000/demodb -user db2admin -password passw0rd -options [-bindoptions "BLOCKING NO"] -files [JPA_W_EJB.jar\\META-INF\\JPASample.pdqxml] ]') |
注意:pdqmgmt.jar 包含运行 pureQuery 运行时所需要的许可证。
print AdminTask.help('processPureQueryBindFiles')
清单 3 显示了上面描述的命令和输出。可以看到,在缺省情况下,将创建每个包的四个版本;数字 1 至 4 分别追加到每个包,以区分该包的隔离级别,每个数据库锁定隔离级别对应一个包。
C:\was70\bin>wsadmin -lang jython
wsadmin>print AdminTask.listPureQueryBindFiles('[-appName JPA_EE_SAMPLE]')
JPA_W_EJB.jar\META-INF\JPASample.pdqxml
wsadmin>print AdminTask.help('processPureQueryBindFiles')
WASX8006I: Detailed help for command: processPureQueryBindFiles
Description: Process the pureQuery bind files that are in an installed application. Bind
static SQL packages in a database. Refer to the information center documentation for the
pureQuery bind utility.
Target object: None
Arguments:
*appName - The name of an installed application that contains the pureQuery bind files
to be processed.
classpath - A list of the paths to the .jar files that contain the pureQuery bind
utility and its dependencies: pdq.jar, pdqmgmt.jar, and db2jcc4.jar or db2jcc.jar.
Use / or \\ as a file separator. Use a blank space to separate the paths for the .jar
files.
*url - The URL for connecting to the database. The format is jdbc:db2://server_name:
port/database_name.
user - The user name for connecting to the database.
password - The password for connecting to the database.
options - Any additional options that are needed by the pureQuery bind utility.
Provide bind options as: -bindoptions "options-string". Refer to the information center
documentation for the pureQuery bind utility.
*files - A list of the names of the pureQuery bind files to be processed. The bind
file path names must be relative to the application .ear file that contains them.
Use / or \\ as a file separator. If you specify multiple file paths, use a blank space
to separate them.
Steps:
None
wsadmin> wsadmin>print AdminTask.processPureQueryBindFiles('[-appName JPA_EE_SAMPLE
-classpath [C:\\pdq.jar C:\\pdqmgmt.jar C:\\db2jcc.jar ] -url jdbc:db2://localhost:50000
/demodb -user db2admin
-password passw0rd -options [-bindoptions "BLOCKING NO"] -files [JPA_W_EJB.jar\\META-INF
\\JPASample
.pdqxml ]]')
IBM Data Studio pureQuery Runtime 1.2 build 1.3.98
Licensed Materials - Property of IBM
5724-U16
(c) Copyright IBM Corp. 2006, 2008 All Rights Reserved.
================================================================================
Package 'Order1' was bound successfully for isolation level UR.
Package 'Order2' was bound successfully for isolation level CS.
Package 'Order3' was bound successfully for isolation level RS.
Package 'Order4' was bound successfully for isolation level RR.
Package 'Custome1' was bound successfully for isolation level UR.
Package 'Custome2' was bound successfully for isolation level CS.
Package 'Custome3' was bound successfully for isolation level RS.
Package 'Custome4' was bound successfully for isolation level RR.
Package 'pkgseq1' was bound successfully for isolation level UR.
Package 'pkgseq2' was bound successfully for isolation level CS.
Package 'pkgseq3' was bound successfully for isolation level RS.
Package 'pkgseq4' was bound successfully for isolation level RR.
Bind completed successfully for the file 'META-INF\JPASample.pdqxml'.
Bind succeeded for |
您可能发现使用 WebSphere Application Server 管理控制台来绑定包会更加容易:
可以在 EAR 文件中提供 bindprops 文件以细化绑定选项,或者绑定多个 pdqxml 文件。清单 4 是一个示例 bindprops 文件,其中列出了三个 pdqxml 文件以及每个 pdqxml 文件的不同绑定选项。
# Artifact 1 META-INF\myPureQueryXmlFile1.pdqxml = -rootPkgName myPkg1 -bindOptions "bind options" -generateDBRM true -outputDBRMPath C:\myDRMDirectory5\myDBRMSubDirectory1 -isolationLevel UR # Artifact 2 META-INF\myPureQueryXmlFile2.pdqxml = -rootPkgName myPkg2 -pkgVersion -ver6 # Artifact 3 META-INF\JPASample.pdqxml = |
可以在下面任一位置将 bindprops 文件与 persistence.xml 文件和 pdqxml(在此例中为 JPASample.pdqxml)一起打包,
无论采用哪种方式,WebSphere Application Server 都将自动检测绑定文件并相应地显示它。
成功绑定 bindprops 文件中的 pdqxml 文件以后,您就为使用静态 SQL 来运行应用程序做好准备了。
在清单 3 中,您绑定了 JPASample.pdqxml 中的 SQL 语句而未授予该包的任何权限,这意味着包所有者是唯一拥有该包执行权限的人。要向公众授予包执行权限,您可以使用 grant 关键字。例如,以下命令将包的执行权限授予公众:
wsadmin>print AdminTask.processPureQueryBindFiles('[-appName JPA_EE_SAMPLE -classpath
[C:\\openjpadep\\pdq.jar C:\\openjpadep\\pdqmgmt.jar C:\\openjpadep\\db2jcc.jar ] -url
jdbc:db2://localhost:50000/demodb -user db2admin -password passw0rd -options
[-bindoptions "BLOCKING NO" -grant "grantees(public)"] -files [JPA_W_EJB.jar\META-INF\
JPASample.pdqxml]]') |
要向特定用户授权(例如 admf002 和 admf003),您将输入:
-grant "grantees(admf002, admf003)"
可以使用 WebSphere Application Server 管理控制台向静态绑定器添加 grant 选项。同样,在图 7 中,没有提供附加选项,因此只有所有者才拥有包的执行权限。图 11 显示 Additional options 中添加了 -grant grantee(public) 选项,从而向公众提供了该包的执行权限。
您可以直接将本文附带的示例应用程序部署到 WebSphere Application Server V7 上,或者可以将 .ear 文件导入 IBM Rational® Application Developer 7.5 工作区。将 .ear 示例文件导入工作区以后,您可以在 WebSphere Application Server V7 上运行 Web 项目 JPA_W_EJB_WEB。还可以将以下 URL 输入浏览器以运行该示例应用程序: http://localhost:9080/JPA_W_EJB_WEB/。
要验证 SQL 已运行,可以通过导航到 Logging and Tracing => server1 => Diagnostic trace service => change log details levels 来打开 WebSphere 跟踪,并设置:
*=info: JPA=all: penjpa=all: SystemErr=all: SystemOut=all: com.ibm.pdq=all
创建一个客户后,打开 WebSphere trace.log 文件。以下跟踪表明用于创建客户的 SQL 的确是静态地运行的。
[11/24/08 12:07:30:239 PST] 00000016 OpenJPA 3 wsjpa.pdq: Trace: PDQ static sql: INSERT INTO SALES.CUSTOMER (id, name) VALUES (?, ?)
|
使用 pureQuery 客户端优化来查找和绑定附加 SQL(可选)
不可否认,并非从应用程序生成的每个 SQL 语句都将按上述方式静态地执行。例如,wsdb2gen 就不收集动态 JPQL 查询。取决于您的应用程序,您可能对使用 wsdb2gen 所获得的结果感到满意。但是,如果您有大量无法使用静态生成器来收集的 SQL,您可以使用 Data Studio Developer 和 pureQuery 运行时中的 pureQuery 客户端优化功能在执行期间捕获 SQL。这里提供了相关步骤的概述,但是强烈建议您完整阅读客户端优化教程。
正如前面提到过的,使用客户端优化,您可以在应用程序运行时捕获 SQL,同时最好进行一组良好的测试来试验大部分或所有的用例。该过程的输出是一个 pdqxml 文件,其中包含成功执行的动态 SQL 元素。然后可以按照前面描述的那样绑定该文件,或者使用 Data Studio Developer 工具(如该教程中所述)。
图 13 显示了使用 pureQuery 客户端优化时从应用程序到数据库的流。
<!-- PDQ dynamic mode --> |
请注意,pdqProperties 被追加到普通 URL 以启用捕获功能,并指定将在其中写入所捕获的 SQL 语句的输出文件名称。
重要:请确保使用的包名称或集合 ID 与用于静态生成器绑定的包名称或集合 ID 不同,从而确保为所捕获的 SQL 与所生成的 SQL 创建唯一的包。如果不保持这些包的唯一性,则在执行应用程序时可能会看到 SQLCODE -818。
C:\test>java com.ibm.pdq.tools.Configure -pureQueryXml C://mycapture.pdqxml -rootPkgName pkg1 -collection coll1 |
C:\test>java com.ibm.pdq.tools.StaticBinder -pureQueryXml C://mycapture.pdqxml -user db2admin -password passw0rd -url jdbc:db2://localhost:50000/demodb |
此时,您应该已经将使用静态生成器生成时遗漏的 SQL 语句成功绑定到数据库。
<!-- PDQ static mode --> |
<!-- PDQ static mode --> |
对于 J2EE™ 应用程序,可以通过将 WebSphere Application Server 中的 pdqProperties 属性设置为某个 DataSource CustomProperties 来启用和禁用捕获模式。在输出文件中捕获 SQL 语句以后,然后可以按照清单 7 所述配置和绑定它们,并在生产环境中运行您的应用程序。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15082138/viewspace-605285/ ,如需转载,请注明出处,否则将追究法律责任。