全部产品
云市场

PLSQL 转 Java 服务

更新时间:2018-05-31 14:18:43

简介

PLSQL 转 Java 服务(以下简称 P2J 服务)通过 ADAM PLSQL 转 Java工具(以下简称 P2J 工具)和专家服务的组合,将以 Oracle 为数据库的客户业务系统中的 PLSQL 对象代码转换为 Java 代码,最终可以编译通过并执行以完成 PLSQL 代码相同的功能。

服务申请

客户可以通过以下几种途径申请 P2J 服务:

  • 阿里云 ADAM 控制台
  • ADAM 团队指定的阿里云服务团队
  • ADAM 团队技术人员

服务流程

  1. 客户在提出 P2J 服务申请前,必须先通过 ADAM 数据库采集工具收取要转换的数据库的数据并上传到阿里云 ADAM 平台。详情请参见下载 ADAM 客户端

  2. 登录 ADAM 控制台,在项目页面中的 PLSQL 转 Java 菜单或向 ADAM 团队提出转换申请。

    注意:申请时,需要留下 PLSQL 转 Java 负责人的联系方式。

  3. ADAM 团队收到申请后,在 1-3 个工作日内进行 PLSQL 转 Java 操作并和您沟通。

  4. ADAM 团队会将转换结果的一部分作为 Demo 发送给客户,确认转换后的代码是否符合客户的预期。

  5. 如果客户认可转换结果并希望得到全部转换后的代码,则需提供对应的测试库,并安排相关技术人员配合 ADAM P2J 服务专家测试转换后代码。

    测试可以在客户的实际环境中完成,也可以远程完成,过程需要 3~5 天。

  6. 测试结束后,ADAM 团队会将所有转换后代码正式提交给客户。

服务内容及费用

P2J 服务内容包含两个方面:P2J工具转换到 Java 和 P2J 专家服务。

  • P2J 工具转换目前为免费服务
  • P2J 专家服务为可选服务,服务费用根据项目具体情况而定。

P2J 工具转换

P2J 介绍

P2J 可以自动完成由 Oracle PLSQL 语言定义的对象到 Java 语言的转换,包括包(Package)、包体(Package Body)、存储过程(Procedure)、函数(Function)、序列(Sequence)、抽象数据类型(Type)和抽象数据类型体(Type Body)。目前不能作用于其他对象,如:作业(Job),定时任务(Schedule Job),触发器(Trigger)等。

使用方式

P2J 工具目前是线下工具,需要您通过向 ADAM 团队申请 P2J 服务来使用。

  • P2J 的输入是您通过 ADAM 数据采集工具收取 Oracle 数据库系统中的 PLSQL 程序。
  • P2J 的输出是一系列的 Java 程序包,通过线下的途径反馈给客户。

转换规则

P2J 工具实现对几种核心的 PLSQL 代码对象进行转换,充分考虑到了 PLSQL 语义和到 Java 语言的对应关系,对数百种 PLSQL 语法结构进行了对应的 Java 代码转换。

输出代码结构

目前最终提交给客户源代码包解压后的是一个 IDEA 的 Maven 工程目录,可以直接通过 IDEA 打开浏览。

  1. dbid
  2. └──src
  3. ├── auxcode
  4. ├── sys
  5. ├── Owner 目录
  6. ├── function
  7. ├── pkg
  8. ├── procedure
  9. ├── type
  10. ├── table.java
  11. └──object_stat
  • 顶层目录

    源代码目录以客户库的 dbId 为顶层目录,包括:

    • src 目录为转换后的源代码目录。路径为:src/main/java/com/aliyun/adam/p2j
    • Object_stat 文件中列举了所有 PLSQL 对象的分析和转换概要,仅供参考。
    • IDEA 相关文件和目录不再赘述。
  • 源代码目录

    p2j 目录下即为 Oracle 库中的 owner,每个 owner 一个目录。包含辅助代码的目录(auxcode 和 sys)和 Owner 目录(包含具体 PLSQL 类型对象目录)。

    • auxcode 包含了转换后代码中所依赖的一些固定代码的工具类,具体来说,

      • JUtil:负责 Oracle 数据类型转换为 Java 数据类型后,变量之间的转换、比较、四则运算等方法。
      • TConf、TConnection、TSession、TSqlExecution:作为数据库访问的工具函数类,提供数据库配置、连接、会话和执行 SQL 方面的基础功能。
      • TAArrayBase、TVArrayBase、TTableBase:提供 Oracle 三种类型的 Type 转换为 Java 后的模板类。
      • TCursor:提供 Oracle Cursor 变量对应的方法,如 IS OPEN, ROW COUNT 等。
      • TSequence:提供 Oracle 序列转换后的方法,如 CURRVAL, NEXTVAL 等。
      • NoDataFoundException、TooManyRowsException:提供 Oracle Exception 对应的 Java Exception。
    • sys 包含了转换后代码所需要的对应于 Oracle sys 账号下的对象一些功能类。

      • Oracle_function 中的 OFunc 包含了大部分常用的 Oracle 函数在 Java 中的实现(不断积累维护中)。
      • Oracle_package 中每个类对应于一个包的 Java 实现,如 dbms_output 等。(对于 PLSQL 代码中对 Oracle Package 的依赖,推荐通过 Java 的第三方库来实现,所以 P2J 并没有对这部分没有提供完善的 Java 实现。)
      • Oracle_type 中提供一些对应于 Oracle Type 的Java实现,如 AnyData、AnyType、 XmlData 等。和 Oracle Package 类似,这部分建议由 Java 数据结构来重构,所以也没有提供完善的 Java 实现。
    • 每个 Owner 目录下,每个 PLSQL 类型对象对应一个单独的目录。包括:

      • 函数目录(function):包含所有用户定义函数的 Java 代码,其为每个函数建立一个函数名同名的类文件,函数代码作为该类唯一的静态函数。

        function 目录下有个子目录(plsql),保存了所有函数的 plsql 源代码作为参考,目录中每个函数对应一个单独的文件。

      • Procedure 目录中包含了所有被转换的存储过程,结构和 Function 目录完全一致。

      • 包目录(pkg):包含了所有用户定义的 Package 和 Package Body 转换后的代码。

        • 每个 Package 定义被转换为与包名同名的一个 Java 类,保存为同名 Java 文件。
        • 每个 Package Body 实现被转换为 <包名称>_subclass类,从 Package 定义的类继承,保存为类名文件。
        • 同样地,也包含一个子目录(plsql),包含了所有这些包声明和包体的 plsql 源代码作为参考。
      • Type 目录

        • Type 目录中包含了所有用户定义的 Oracle Type 转换结果,
        • 每个 Type 定义被转换为 _base 类,保存为类名文件。
        • 每个 Type Body 实现被转换为 Type 同名的类,继承于 _base 类,保存为类名文件。
      • tablerefs.java 文件:保存了所有对象代码中引用的本 owner 下的表结构转换为的 Java 类,每个被引用的表结构对应一个内部静态类。

以上所有生成类的 Package 被设定为与目录结构相同,且已经添加了必要的相互 import。

P2J 并没有为每个 Sequence 生成单独的类或方法,由于所有 Sequence 的转换结果相同,在 AuxCode 中的 TSequence 统一处理。

在源代码中,所有对于其他包、类、方法等的依赖都已经按照正确的规则链接妥当。 例如,当 Package Body 中某个函数代码段中调用用户定义的函数时,用户定义的函数前自动会加入函数同名类前缀,在 Java 中可以正确链接和编译;同理,如果是存储过程则会自动加入存储过程同名类前缀;如果是调用 Oracle 系统函数则会自动加入 OFunc 前缀。

用 IDEA 创建工程后,最终生成的工程概览

测试方法

对于函数和存储过程,由于没有上下文问题,转换为的结果是静态方法,可以直接通过类名引用和调用。

对于 Type,其语义上和 Java 中的类定义一致,可以以 Java 类相同的方式来使用。

对于 Package 有些特殊,Oracle 对于 Package 的使用有 Session 上下文的管理,即一个 Session 中使用同一个的 Package 只有一份,可以理解为 Session 级别的单例。所以在实例化 Package 和调用 Package 方法时,需要使用 AuxCode 中的 TSession 来辅助,以如下的方式调用:

  1. ((<PackageClassName>)TSession.getUserPkg("<OwnerName>"," <PackageClassName >")).<FunctionName>

例:

调用的 Owner为User1, Package 为 Pkg1,方法为 Func1,参数为 a 和 b,则调用表达式为:

  1. ((Pkg1)TSession.getUserPkg(“User1”, Pkg1”)).Func1(a, b);

在转换代码结果中如果是调用了其他包的方法也是通过以上方式实现。

对于带 OUT 参数的方法,由于 Java 不支持在所有数据类型情况下传引用,转换通过返回 Map 的方式解决。转换对于所有带有 OUT 参数的方法都增加了一个 Map 参数,使用方法举例。

Owner 为 User1, Package 为 Pkg1,方法为 Func2,参数为 a、b 和 c,其中 b 和 c 为 OUT 参数,b 在 plsql 源代码中是 Number 类型,c 在plsql 源代码中是 varchar2 类型,则调用表达式为

  1. Map<String, Object> argumentMap = new HashMap<String, Object>();
  2. ((pkg1)TSession.getUserPkg("user1","pkg1")).func2(a, b, c, argumentMap);
  3. b = (BigDecimal)argumentMap.get("b");
  4. c = (String)argumentMap.get("c");

编写调用表达式时可以参见 func2 函数声明。

测试时通过测试代码调用以上对象转换后的代码检查执行结果即可。

P2J 专家服务

由于 PLSQL 语言和 Java 语言的区别,并不是所有 PLSQL 语法在 Java 语言中都可以找到完美的转换方案,所以需要专家服务的支持。P2J 工具对 PLSQL 源代码的转换成功率非常高,在已有的客户项目中的经验是,每万行代码的转换结果需要小于 1 个小时的手工调整即可实现编译通过准备开始测试的状态,且测试过程中发现的错误量极少。

无论再强大的转换工具,对于转换后的代码人工的检查和调整是必不可少的,P2J 专家服务即基于 P2J 工具转换后的代码,通过 P2J 技术专家的经验帮助客户完善转换后的代码,需要 P2J 的技术专家和客户的技术人员一起检查、修改并测试转换结果,并最终辅助用户可以将转换的代码实现测试上线的目标。

目前,ADAM 团队或其指定的合作伙伴团队可以提供 P2J 专家服务,收费的专家服务可选非强制,具体方式需要和客户讨论,每个项目不尽相同。