了解 IBM® Data Studio Developer 2.1 如何让您更好地理解数据库应用程序。看看 Data Studio Developer 的新实现如何提高您的生产率,以及如何使开发人员与 DBA 之间能够更好地协作。遵循本文中的场景,体验如何使用 Data Studio Developer 2.1 获得更大的方便性和洞察力,从而做更多的事情。
Data Studio Developer 这个新的发行版的主要优点有:
- 它提供更多的信息来帮助您进行 SQL 调优。
- 它提高了 OpenJPA 和 .NET 应用程序的服务质量。
- 通过它可以更好地理解使用 SQL 的 Java 应用程序。
- 通过它可以提高生成率和促进开发人员与 DBA 之间的协作。
- 可以减少或消除 Java 数据库应用程序的 SQL 注入风险。
为了实践后面的场景,需要安装以下东西:
- Data Studio Developer 2.1(很快就有试用代码)
- DB2® for Linux®, UNIX®, and Windows® —— DB2 Express-C 就可以了
- DB2 附带的 sample 数据库
通过现有的分析工具,可以识别应用程序中的哪些 Java™ 方法花费最长的运行时间。而通过 Data Studio Developer 2.1,则可以查看包含对数据库的调用的 Java 方法的性能度量,获取更深入的信息。无论使用 pureQuery、JDBC 还是其他框架,都可以识别应用程序中每条 SQL 花费的时间、它运行的次数以及它运行的最长、最短和平均时间。
在 Data Studio 中尝试下面这些简单的步骤:
![]() |
|
- 在视图中,进入到 Data Management > Data Source Explorer(之前是 Database Explorer)。建立到 sample 数据库的一个连接,并将该连接命名为 SAMPLE。
- 创建一个 Java 项目,将其命名为 myDSDPrj。
- 下载文件 TutMod.java 和 Util.java,将它们复制到 db2jcc.example 包中。该文件表示一个简单的现有的 JDBC 应用程序,您将使用它来运行不同的场景。
- 为了将 pureQuery 支持添加到项目中:
- 右键点击该项目,选择 pureQuery -> Add pureQuery support。
- 选择 SAMPLE,并添加适当的模式,以限定 STAFF 表。
- 在下面的图中,模式为 SSURANGE。
- 选中 Enable SQL capturing and binding for JDBC applications 复选框。
图 1. 添加 pureQuery 支持注意,现在可以指定一个默认的模式,以限定表和视图。使用新的 Default path widget 限定您未限定的例程。
- 为了收集性能度量,使用 pureQuery 配置运行应用程序:
- 在运行应用程序之前,设置模式以限定 STAFF 表。为此,打开 TutMod.Java,找到第 66 行,将值 SSURANGE 改为您的模式,并保存该文件。
stmt.execute("set current schema SSURANGE"); - 为了使用 pureQuery 配置运行应用程序,打开 TutMod.java,然后右键点击该文件,选择 Run -> Run Configurations。
- 选择 pureQuery,并为数据库名称、服务器、端口、userID 和密码等参数(图 2)提供值,然后单击 Run。
- 这样将收集执行的 SQL 以及性能信息。
图 2. 运行应用程序以收集 SQL 度量 - 在运行应用程序之前,设置模式以限定 STAFF 表。为此,打开 TutMod.Java,找到第 66 行,将值 SSURANGE 改为您的模式,并保存该文件。
- 要查看性能信息:
- 右键点击 myDSDPrj 并选择 Show pureQuery outline。
- 在 pureQuery outline 中,单击 Toggle Profile 按钮。
- 展开 myDSDPrj 项目,可以看到每条 SQL 语句的性能信息。
例如,下面的图显示 SELECT 语句被运行了 2 次,花费的总时间为 598 毫秒。
图 3. SQL 执行度量
SELECT 语句运行得比较多,应用程序可以通过优化这条 SQL 获益。
![]() |
|
发现有问题的 SQL 后,就需要优化它。对于生产应用程序或打包的应用程序,也许不能更改应用程序的源代码,但是您可能希望能够更改产生的 SQL。例如,您可能想更改 SQL,以利用新添加的索引,或者限制返回的行数,又或者添加非常需要的 ORDER BY 子句。
Data Studio Developer 2.1 提供了一个受控编辑器,通过它可以用等效的、很可能更好的语句替代应用程序生成的现有 SQL 语句。这个编辑器自动验证语句的等效性,并且拒绝不等效的语句。
在 Data Studio Developer 中尝试以下简单的步骤:
![]() |
|
- 在 myDSDPrj 中,展开 pureQueryFolder。双击 capture.pdqxml。
- 右键点击 SELECT 语句(SELECT id, name, dept, job, years, salary, comm FROM staff WHERE id = ?),并选择 Edit。这是您在图 3 中看到的 SELECT 语句。选择默认模式,以限定您的表。
图 4. 编辑现有的 SQL,以减少返回的行数 - 现在用下面的 SQL 替换该语句,下面的 SQL 语句是等效的,但是返回更少的行:
SELECT id, name, dept, job, years, salary, comm FROM staff WHERE id = ? fetch first 2 rows only - 单击 Save。
图 5. 替换为经过优化的 SQL
您已经更改了 SQL,使之返回更少的行,现在再次运行它,看看性能度量中有什么不同。
- 为了再次运行应用程序:
- 打开 pdq.properties,将 captureMode 设为 OFF,并添加 pdq.enableDynamicSQLReplacement=TRUE
pdq.captureMode=OFF pdq.executionMode=DYNAMIC pdq.enableDynamicSQLReplacement=TRUE 。 - 使用 pureQuery 配置运行应用程序。
- 打开 pdq.properties,将 captureMode 设为 OFF,并添加 pdq.enableDynamicSQLReplacement=TRUE
- 要再次查看性能度量,右键点击 myDSDPrj 并选择 Show pureQuery outline。
- 下面的图显示 SELECT 语句运行了 2 次(和之前一样),但是总时间为 519 毫秒。注意,SQL 语句运行的时间比之前更短。
图 6. 替换为经过优化的 SQL 之后性能更好
现在,您可以获得关于访问 DB2 数据的现有或新的 JPA 应用程序发出的任何 SQL 和 JPAQL 的信息。您还可以无缝地使用静态 SQL,而不必更改任何应用程序代码。如果您的应用程序使用 DB2,那么可以使用 WebSphere® Application Version 7 中的静态生成器(wsdb2gen)来收集 SQL。您不必运行应用程序就可以获得大多数好处。对于其他情况,可以与客户机优化相结合。Data Studio Developer 2.1 包括工具支持,以使静态生成过程更加容易。注意,必须使用 WebSphere 7 fixpack 3。
在 Data Studio Developer 中尝试以下简单的步骤:
- 将 pureQuery 支持添加到 JPA 项目中。
- 将 WebSphere 安装中的 com.ibm.ws.jpa.jar 添加到构建路径中。
- 右键点击 persistence.xml 并选择 pureQuery > Generate pureQueryXml file。
- 右键点击 project 并选择 pureQuery->Show pureQuery outline。
- 查看所有可能从实体和映射文件中的实体、namedQueries 和 namedNativeQueries 生成的 CRUD。
- 双击任意 SQL 进入触发该 SQL 查询的 JPA 源代码。
- 作为可选步骤,可以使用客户机优化来捕捉只在运行时可用的 SQL(例如,动态 JPAQL 语句)。将 pdq.Properties 中的 captureMode 设为 ON 之后运行应用程序,并收集应用程序中任何剩下的 JPAQL 和 SQL。
无论应用程序是否使用 DB2,优化现有的非 DB2 JPA 应用程序,这不需要更改任何代码。要想用经过优化的 SQL 替换现有的 SQL,请参阅 在不必更改代码的情况下调优和优化应用程序 小节。不要走开,下面是关于支持 JPA 的 Data Studio Developer 2.1 的更深入、操作性更强的教程。
Data Studio pureQuery Runtime 2.1 为提高 .Net 应用程序的稳定性、安全性和易管理性提供了支持,包括那些用任何基于 .Net 的语言(例如 C# 和 VB.Net)编写的应用程序。用这种 SQL 摘要升级现有的 .Net 应用程序。
- 在 .Net 连接字符串中将捕捉模式设为 ON
captureMode = on;pureQueryXML=path/filename:collection=collName;rootpackage=pkgName - 执行所有测试
- 使用 DB2cap 实用程序从捕捉的 SQL 绑定和创建静态包
- 授予执行许可
- 在连接字符串中将捕捉模式设为 OFF,将 executionMode 设为 STATIC
executionMode=STATIC:captureMode=OFF - 执行所有测试,以验证结果是否正确。
在 pureQuery outline 中,要对现有的应用程序使用 Data Studio Developer 1.2,必须运行应用程序,以查看应用程序将发出的 SQL 以及它在源代码中的位置。但是 Data Studio Developer 2.1 中,可以自动看到应用程序中的 SQL,而不必运行应用程序。您可以查看应用程序中所有硬编码的 SQL。还可以运行应用程序来收集任何其他的 SQL。
在 Data Studio Developer 中尝试以下简单的步骤:
- 右键点击 myDSDPrj 并选择 Show pureQuery outline。
- 在 pureQuery outline 中,单击 Toggle Profile 按钮。
- 选择 Database 选项卡。注意,outline 中显示了还没有被执行的 UPDATE 和 DELETE 语句。双击 DELETE statement,进入到 Java 文件中的位置。在下面的图中,可以看到发出 SQL 语句的 Java 源代码是一条 executeUpdate 语句。
图 7. 自动查看 SQL - Database 选项卡 - 单击 Java 选项卡。展开 myDSDPrj 和以包命名的 db2jcc.example。注意,outline 中显示了还没有被执行的 UPDATE 和 DELETE 语句。这一次,双击 update 语句,进入到 Java 文件中的位置(在这里,就是定位到 JDBC 预置语句)。注意,在 JDBC executeUpdate 也显示了该预置语句的执行位置。
图 8. 自动查看 SQL - Java 选项卡
如果实际运行应用程序,可以提高 SQL 位置的准确性。此外,这样可以得到动态构造的 SQL。
在 Data Studio Developer 中尝试以下简单的步骤:
- 打开 TutMod.java,激活 mail 方法中的 basicUpdate 调用。
- 要运行应用程序:
- 打开 pdq.properties,将 captureMode 设为 ON,并添加 pdq.enableDynamicSQLReplacement=false
pdq.captureMode=ON pdq.executionMode=DYNAMIC pdq.enableDynamicSQLReplacement=false - 运行应用程序。
- 打开 pdq.properties,将 captureMode 设为 ON,并添加 pdq.enableDynamicSQLReplacement=false
- 右键点击 myDSDPrj 并选择 Show pureQuery outline。
- 单击 Java 选项卡。 展开 myDSDPrj 和以包命名的 db2jcc.example。注意,前面提到的 executeUpdate 现在被替换为实际的 SQL update 语句。
图 9. 运行应用程序以提高准确性 - Java 选项卡
之前,pureQuery outline 只限于单个的项目,所以只能逐个项目地查看关于应用程序中发出的 SQL 的信息。对于跨多个项目的应用程序,则不能方便地获得完整的信息。
关闭工作区中不属于您的应用程序的所有项目。Data Studio Developer 2.1 会提供您需要的关于应用程序将对数据库发出的 SQL 的所有信息。
在继续之前,让我们再添加更多的项目到应用程序中。Data Studio Developer 现在允许为很多表批量生成 pureQuery 代码。
批量自下而上代码生成在 Data Studio Developer 1.2 中,只能为单个的表生成代码。在 Version 2.1 中,则可以更快地为多个表自下而上生成代码。
- 创建一个 Java 项目,并将它命名为 pdqBulkBottomUp。
- 选择 DEPARTMENT 和 EMPLOYEE 表,单击右键,并选择 Generate pureQuery code。
- 提供包名,并选择 Generate annotated style 代码。单击 Next。
图 10. 从两个表生成 pureQuery 代码 - 对于 DEPARTMENT 表,选择 SQL Statements 选项卡。选择 Select all rows、Create row by parameters 和 Create row by object。单击 Finish。
图 11. pureQuery 代码生成 - 选择 SQL 语句 - 现在可以马上为大量的表生成数据访问!注意,SQL CRUD 语句是为每个表单独生成的。也就是说,不考虑表之间的关系。
- 右键点击项目,并选择 Show pureQuery outline,以便对于每条 SQL 下钻到数据库和上钻到应用程序。获取像这样的问题的答案:哪个 SQL 使用 DEPARTMENT 表,它在 Java 代码中的什么地方被使用?
图 12. 哪个 SQL 使用某个模式或表,它在 Java 代码中的什么地方被使用 - Database 选项卡 - 单击 Java 选项卡;如您所想,pureQuery outline 中可以看到所有的项目。您可以进行下钻,以了解 Java 类与访问数据库的 SQL 之间的关系。获取像这样的问题的答案:我的 Java 类 DepartmentData 发出什么 SQL,从哪里发出?
图 13. Java 类发出什么 SQL,从哪里发出 - Java 选项卡
发现您的应用程序使用哪些 SELECT 语句,或者哪些 SQL 应用程序使用绝对值(abs)函数
之前,通过使用 pureQuery outline 中的过滤器,可以获得关于哪些 SQL 语句使用一个数据库列或表的信息。无论您使用 pureQuery API 还是有现有的使用 JDBC 或框架的应用程序,Data Studio Developer 2.1 都允许您通过增强的过滤,将注意力集中到感兴趣的 SQL 上。使用这个功能来发现哪些 SQL 语句使用某个特定的列,以及其中哪些是 SELECT 语句。而且,了解哪些 SQL 语句使用某个函数。
![]() |
|
- 在 pureQuery outline 中单击 Filter 按钮,如下图所示。
- 为 SQL text filter pattern 提供过滤器信息 (.*SELECT.*)。然后选择 OK。
- 现在,可以在过滤后的 pureQuery outline 视图中看到应用程序中的所有 SELECT 语句。
图 14. 发现应用程序发出哪些 SELECT 语句 - 现在,按列名添加过滤器,输入过滤值 .STAFF.ID。您可以看到使用 STAFF 表中的 ID 列的所有 SELECT 语句。您可以看到这些信息如何影响分析。为 database object name 提供值 .STAFF.ID。查看使用 STAFF 表中 ID 列的所有 SELECT 语句。
图 15. 发现哪些 SELECT 语句使用列 ID
查看 pureQuery outline,将应用程序中的 SQL 与实际被发送到数据库的 SQL 相关联。我们来看看之前替换的 SQL。
在 Data Studio 中尝试以下简单的步骤:
- 在 pureQuery outline 中的 Database 选项卡中,展开 SELECT 语句。注意,被发送到数据库的 SQL 是您在之前步骤中替换的那个 SQL。
图 16. 查看应用程序中的 SQL 以及被发送到数据库的 SQL
Data Studio Developer 1.2 只能根据栈跟踪显示 SQL 语句在源代码中的大约位置。现在,Data Studio Developer 2.1 可以更准确地提供 SQL 在应用程序中的位置。想知道 SQL 是在哪里定义和执行的吗?调用同一条 SQL 的所有代码路径有哪些?
在 Data Studio Developer 中尝试以下简单的步骤:
- 在 pureQuery outline 中单击 Java 选项卡,然后展开 SELECT 语句。注意,这里可以看到定义 SQL 的位置(preparedStatement)和执行它的位置(executeQuery)。
- 注意,delete 语句指向预置和执行 SQL 的那一行。
图 17. 查看定义 SQL 的位置和执行它的位置
获取关于 Java 应用程序如何使用 SQL 的更多信息。检索到的列在哪里被使用?它是否被发送回数据库?它是否被打印出来?如果有源代码,那么可以跟踪结果集中返回的值如何在应用程序中流动。
- 打开 DepartmentData.java,右键点击 DEPTNO 并选择 Source Code Analysis, Analyze column value Dependency。
- pureQuery analysis 视图显示值如何在应用程序中流动。注意,database 图标显示从数据库中的什么位置检索值,以及将值更新到数据库的什么位置。
图 18. 查看 DEPTNO 列的值如何在 Java 应用程序中流动
之前,必须手动创建用于命令行部署的绑定属性。没有办法指出条目是否为无效的,只能等到部署时报告错误。开发人员不能方便地使用 jar、ear 或 war 文件测试部署。
做好部署准备了吗?Data Studio Developer 2.1 明显加快了部署的速度。创建可部署的 bindProps,bindProps 可以集中维护,并且可以在组织中共享。Data Studio Developer 2.1 使开发人员可以测试驱动这些步骤,以确保应用程序做好部署的准备。
![]() |
|
- 右键点击 Default.bindProps 并选择 Add remove entries。选择 com.pdqdemo.EmployeeData 和 com.pdqdemo.DepartmentData。下面的图显示关于如何轻松管理条目的一个例子。
图 19. 轻松管理静态 SQL 属性 - 接下来,为了测试绑定,右键点击 Default.bindProps 并选择 bind。
您已验证 bindProps 是就绪的,现在为应用程序生成 jar 文件,以便进行部署。
完成应用程序的开发和测试后,为应用程序生成 jar 文件,以便进行部署。然后,在命令行绑定 jar。同样,Data Studio Developer 2.1 允许开发人员测试驱动这些步骤,以确保应用程序可以被部署。现在,您可以享受智能化 的好处,只在需要时执行绑定。如果只有应用程序中的一部分被更改,那么在重新部署 jar 时,可以避免不必要的绑定。
- 将 pdqBulkBottomUp 项目的 src 文件夹中的文件和 pureQuery 文件夹中的 bindprops 打包成 jar 文件。
- 为了绑定 Jar 文件,右键点击 jar 文件并选择 pureQuery->Bind。bindProps 中列出的条目将被绑定。
在 Data Studio 1.x 中,当绑定失败时,只显示有限的信息。您不能识别哪些包导致绑定失败。这种知识的缺乏使得绑定问题更难以修复。由于大量包含很多 SQL 语句的包通常是在部署时绑定的,这个问题甚至会变得更加困难。
Data Studio Developer 2.1 现在显著改进了当出现绑定错误时提供的信息。Version 2.1 让您可以通过 Data Studio Developer 工具和 pureQuery 运行时命令行工具获得关于绑定中哪个包失败的更多反馈,从而确定导致失败的原因。
现在,如果应用程序中只有一部分被更改,在重新部署 jar 时可以避免不必要的绑定。
如果您是一名 DBA,使用 SQL builder 等工具创建 SQL 语句或者使用 SQL 编辑器,那么现在可以轻松地生成 pureQuery 代码。在 SQL builder 中,将 SQL 保存为一个 .sql 文件。然后,只需在这个 .sql 文件上或者在一个打开的 SQL 编辑器中单击右键,并选择 Generate pureQuery code。通过弹出的向导,您可以有效地为文件中的所有 SQL 语句生成 pureQuery 数据访问层。
如果您是一名 Java 开发人员,从 DBA 那里接收了一些 .sql 文件,那么,对于启用了 pureQUery 的项目中的文件中的所有 SQL,您可以轻松地为它们生成 pureQuery 代码。通过使用该功能,还可以从现有的 JDBC 应用程序或使用框架的应用程序轻松地迁移到 pureQuery API。首先,从 pureQuery outline 中将 SQL 导出到项目中的 .sql 文件中,或者在 SQL 编辑器中打开它。然后,只需在这个 .sql 文件上或者在一个打开的 SQL 编辑器中单击右键,然后选择 Generate pureQuery code。
选择 Data Studio Developer 中要使用的 pureQuery 运行时的位置
在 Data Studio Developer 1.2 之前,必须经过很多手动步骤才能使用 pureQuery 运行时。通过以下步骤,将 Point Data Studio Developer 2.1 指向 pureQuery 运行时安装位置。
- 从顶级的 Window->preferences 选择 Data Management -> SQL Development -> pureQuery 类别。
- 提供一个位置,其中 pureQuery 运行时 jar 位于 pureQuery Runtime Location 区域的下面。
在 Data Studio Developer 1.2 之前,必须在 Data Studio 所有基于 Eclipse 的工具中单独创建数据库连接。现在,您可以在一个工具中定义数据库连接,然后与其他工具共享连接。导入共享的连接,然后享受重用的好处!
轻松迁移 Data Studio Developer 1.x 或 Data Studio Developer 2.1 中的 pureQuery 项目
当在 Data Studio Developer 2.1 中打开旧的 Data Studio 工作区时,工作区中现有的连接将被自动迁移。只需选择 Window->Reset perspective,重置 Data Studio Developer 2.1 透视图。要迁移现有项目中的 pureQuery 运行时,可以使用项目上的 Upgrade project 菜单。请参阅技术文档 ,获得关于这个过程的更详细的信息。
通过捕捉的 pdqxml 将对数据库发出的 SQL 限制为已知被许可的 SQL。
- 使用 pdq.properties 中的以下属性执行您的应用程序。所有被运行的 SQL 将被捕捉到 pureQueryFolder 中的 capture.pdqxml 中。 captureMode=ON executeMode=DYNAMIC pureQueryXML=pureQueryFolder/capture.pdqxml capturedOnly=false
- 当您已经通过以不垃圾广告式执行应用程序收集到所有的 SQL 时,就可以限制 SQL。
打开 pdq.properties,设置以下属性: captureMode=OFF capturedOnly=true - 现在,只有被捕捉的 SQL 可以被执行,无论是动态地执行还是静态地执行。
显著提高开发人员的效率,构建可立即投入企业使用的应用程序。使开发人员可以构建更好的应用程序,并且与 DBA 协作,减少生产中可能出现的关键性能问题。使用静态 SQL 减少 DB2 服务器上的 CPU 使用/事务,并使现有的硬件和软件投资获得额外的价值增长。
表 1 总结了每个数据库平台上的 Version 2.1 特性支持:
表 1. 每个数据库平台上的特性支持
特性 | DB2 for LUW | IDS | DB2 for z/OS | DB2 for iSeries |
为开发人员提供更多信息,帮助他们进行 SQL 调优
| 有 | 有 | 有 | 有 |
为开发人员提供更多信息,帮助他们进行 SQL 调优
| 有 | 无 | 有 | 有 |
通过静态 SQL 提高 OpenJPA 的服务质量 | 有 | 无 | 有 | 有 |
更好地洞察使用 SQL 的 Java 应用程序
| 有 | 有 | 有 | 有 |
提高生成率和促进开发人员与 DBA 之间的协作 – 与静态 SQL 相关的特性
| 有 | 无 | 有 | 有 |
提高生成率和促进开发人员与 DBA 之间的协作 – 与非静态 SQL 相关的特性
| 有 | 有 | 有 | 有 |
减少或消除 Java 数据库应用程序的 SQL 注入风险 | 有 | 有 | 有 | 有 |
没有理由不使用 Data Studio Developer 和 Data Studio pureQuery Runtime 2.1。以下是下载信息。
![]() |
描述 | 名字 | 大小 | 下载方法 |
---|---|---|---|
本文的样例代码 | TutMod.java | 11KB | HTTP |
本文的样例代码 | Util.java | 11KB | HTTP |
![]() | ||||
![]() | 关于下载方法的信息 | ![]() |
学习
- 您可以参阅本文在 developerWorks 全球网站上的 英文原文。
- 在 developerWorks 上的 Data Studio 专题,可以获得提高 Data Studio 方面的技能所需的资源。
- 浏览 技术书店,找到关于这些主题和其他技术主题的图书。
获得产品和技术
- 现在可以免费使用 DB2。您可以下载 DB2 Express-C,这是为社区提供的免费版本的 DB2 Express Edition,它具有与 DB2 Express Edtion 相同的核心数据特性,并为构建和部署应用程序提供了坚实的基础。
- 下载 IBM Data Studio Developer 并开始使用 Data Studio 进行数据库应用程序的开发。
- 下载 IBM 产品评估版 并开始使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。
讨论
- developerWorks 上的 Data Studio Community Space。
- developerWorks 上的 Data Studio Team Blog。
![]() | ||
| ![]() | Sonali Surange 在位于加州圣何塞市的 IBM 硅谷实验室 IBM Data Server Tooling 开发团队领导 IBM pureQuery 工具的开发。在加入 IBM pureQuery 之前,Sonali 领导开发了 IBM Data Servers 的 Visual Studio .Net 工具,并针对 .NET 为 IBM 开发 SOA。在此之前,Sonali 领导了 Informix SOA 解决方案的开发,并且是 Object Relational 映射工具的首席开发人员。 |
![]() | ||
| ![]() | Zeus Courtois 是加利福尼亚州圣何塞市 IBM 硅谷实验室 Data Studio Development 团队的工程师,从事 pureQuery 工具方面的工作。在加入这个团队之前,Zeus 在 Data Studio Enablement 小组实习。Zeus 拥有 Texas A&M International University 信息系统硕士学位。 |
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15082138/viewspace-536564/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15082138/viewspace-536564/