暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何用 Oracle 数据库直接调用 Java 类实现加密解密

前言

最近在维护一些旧项目中,还发现有些代码是通过调用 Java 类来实现,由于之前没有接触过,后来查找了相关资料,原来 Oracle 数据库支持通过嵌入式 JVM 调用 Java 类,可以利用 Java 存储过程扩展数据库功能,通过 Java Stored Procedure 或 PL/SQL 调用外部 Java 类 的方式将 Java 代码集成到数据库中,实现复杂逻辑、调用外部 API 等功能。

使用场景

Oracle 调用 Java 类可使用在以下场景:

  • 复杂的业务逻辑处理:如果一些复杂的算法或业务逻辑使用 PL/SQL 实现效率较低,或者难以实现,可以通过 Java 类完成。
  • 调用外部服务或接口:如果数据库需要与外部系统交互(如 HTTP 接口调用、消息队列发送等),则这类任务通过 PL/SQL 无法直接实现。
  • 文件操作与日志管理:可以批量生成 CSV 文件或处理文件的输入输出。
  • 数据加密与解密:对于敏感数据,可以使用 Java 提供的加密库可以实现高效、安全的加解密功能。
  • 批量处理与优化计算:如果经常需要对大量数据进行处理,可以利用 Java 类进行批量数据操作。

由于在生产环境中,Oracle 调用 Java 类的使用频率并不高,现只针对数据加密与解密进行演示,了解一下 Oracle 下使用 Java 类的基本步骤。

相关步骤

💡使用前要确保用户有 CREATE JAVAEXECUTE 权限。

  1. 编写 Java 代码,后续可以直接使用 Java 代码,class 文件或者 jar 包。

  2. 将写好的 Java 代码导入到 Oracle 数据库中,有两种方法:一种是使用 loadjava 命令;另一种是在编写PL/SQL的时候编写。以下是使用 loadjava 方式导入 jar 文件到数据库中:由于本使用的是 19c 数据库 pdb 模式,sys 登录后需要先切换到对应的 pdb 下:

sys@ORCL 23:09:12> alter session set container=test_db; sys@ORCL 23:09:29> !loadjava -user muser/123456@test_db -resolve /home/oracle/scripts/pwd.jar
复制
--查询类是否成功加载 select * from user_objects u where u.OBJECT_TYPE LIKE 'JAVA%';
复制
  1. 检查类已经成功加载后,编写 encrypt_str 加密函数 与 decrypt_str 解密函数来封装 Java 代码,以实现后面对 java 功能的调用,如下所示:
CREATE OR REPLACE FUNCTION encrypt_str(r IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'com/myjob/encrypt/EncryptionUtils.encrypt_str(java.lang.String) return String'; CREATE OR REPLACE FUNCTION decrypt_str(r IN VARCHAR2) RETURN VARCHAR2 AS LANGUAGE JAVA NAME 'com/myjob/encrypt/EncryptionUtils.decrypt_str(java.lang.String) return String';
复制

💡Java方法的包名需要用“/”,类名用“.” 分隔,Java方法的传入类型要和数据库类型相对应例如: NVARCHAR2和String

Oracle 和 Java 之间的数据类型需要映射,常用类型如下,更详细的对应关系说明可以看Oracle 官方的文档:

Oracle 数据类型 Java 数据类型 备注
VARCHAR2, CHAR java.lang.String 字符串类型
NUMBER java.math.BigDecimal 精确数值类型
BINARY_FLOAT float 浮点类型(单精度)
BINARY_DOUBLE double 浮点类型(双精度)
DATE java.sql.Date 日期类型
TIMESTAMP java.sql.Timestamp 时间戳类型
RAW, BLOB, CLOB byte[], InputStream 二进制数据或大字段类型
  1. 通过传入相关参数,调用编写好的函数
--加密 select encrypt_str(r => '1122') from dual; --解密 select decrypt_str(r => '11F5A4A997ECE44196AA501D3D2A5832') from dual;
复制
  1. 删除相关 Java 类,操作中下:
sys@ORCL 01:05:48> !dropjava -user muser/123456@test_db-v com/myjob/encrypt/EncryptionUtils dropping: class com/myjob/encrypt/EncryptionUtils sys@ORCL 01:08:29> !dropjava -user muser/123456@test_db-v com/myjob/encrypt/EncrypCons dropping: class com/myjob/encrypt/EncrypCons sys@ORCL 01:08:51> !dropjava -user muser/123456@test_db -v META-INF/MANIFEST.MF dropping: resource META-INF/MANIFEST.MF sys@ORCL 01:09:33> !dropjava -user muser/123456@test_db -v .classpath dropping: resource .classpath sys@ORCL 01:09:49> !dropjava -user muser/123456@test_db -v .project dropping: resource .project
复制

总结

由于在生产环境中,Oracle 调用 Java 类的使用频率逐渐降低,在某些特殊场景下或者旧的项目中(如文件处理、轻量级数据转换、加密/解密等),仍然会有部分使用。但大多数现代系统更倾向于将复杂的业务逻辑和外部集成放在中间件或应用层完成,而不是直接在数据库中实现。如需使用,需要对场景、性能和维护成本进行详细评估,尽量优化设计。在使用 Oracle 调用 Java 类过程中,比较容易出现以下三个错误 :

  • ORA-29532 调用中发生异常
    解决方法:检查 Java 类逻辑或数据类型映射是否正确。

  • ORA-29540 类未找到
    解决方法:是重新加载 Java 类。

  • ORA-29541 解析失败
    解决方法:确保所有依赖库也加载到数据库中。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论