☰
Jeecg-boot从MySQL切换到Oracle 11g的完整部署指南
2026/10/14 14:38:17 网站建设 项目流程

1. 先别急着装库,确认你这套组合拳到底要打给谁

很多人拿到 Jeecg-boot 项目之后,第一反应是把官方文档里的 MySQL 配置一套,业务就能跑起来。但真到了生产环境,事情往往没这么简单。公司既有系统原本就是 Oracle,DBA 只给你开 Oracle 的库权限;或者项目验收要求数据库必须用某类商业数据库;又或者甲方直接说了,我们采购的就是 Oracle 11g,你看着办。这时候你就得把 Jeecg-boot 从默认的 MySQL 切到 Oracle 11g 上,这也是这篇"第二弹"存在的意义。

第一弹的基础部署已经把 Jeecg-boot 的前后端工程跑通,环境也理顺了。这一弹专门解决数据库这一层:从零装一个 Oracle 11g,建好表空间和用户,把 Jeecg-boot 的初始化 SQL 导进去,再把工程的数据库配置从 MySQL 换成 Oracle,最后启动、联调、排错,一路走到底。整个过程我会按"伸手党"的标准写,命令给你完整可复制,不让你自己去拼文档。

这篇内容适合这几类人看:公司要求必须用 Oracle 11g 的 Java 开发;准备把 Jeecg-boot 从开发环境往生产环境迁移的新手;以及那些被各种教程碎片搞得头大、想一口气把数据库部署链路跑通的人。文章默认操作系统是 CentOS 7 + Oracle 11g R2,这也是目前存量使用最多的组合。

1.1 这条链路上到底有哪几个环节

先把全链路拆开,心里有个地图,后面每一步才知道自己在干嘛。

  • 系统准备:装依赖包、调内核参数、创建 oracle 账号、设置环境变量
  • 安装 Oracle 软件:解压安装包、运行 runInstaller、执行 root 脚本
  • 创建实例和监听:netca 配置监听、dbca 建库
  • 数据库初始化:建表空间、建业务用户、导入 Jeecg-boot 的 Oracle 脚本
  • 工程改造:pom.xml 加驱动、数据源配置切换、方言和分页调整
  • 启动联调:后端跑起来、前端连上、处理各种兼容问题

这里面的坑主要集中在第三到第六步,尤其是第四步和第五步,数据库建好了但工程连不上、SQL 执行报错、分页查不出来,这些才是真正耗时间的地方。

1.2 版本组合怎么选才稳

我这次用的是 CentOS 7.6(64位)+ Oracle 11g R2(11.2.0.4)+ JDK 8 + Jeecg-boot 3.x 版本。这里要强调一个关键点:Oracle 11g R2 官方支持的操作系统里 CentOS 7 需要做一定兼容处理,但实际生产中使用的人非常多,稳定运行没问题。

JDK 版本和 Oracle 驱动的对应关系很容易搞混。JDK 8 建议用 ojdbc8,但 Oracle 11g 官方配套的是 ojdbc6,你可以在 pom 里引入 ojdbc8 也没问题。最稳的做法是用 ojdbc6 配 JDK 8,这个组合我在多个项目里都验证过。Oracle 12c 的 ojdbc8 驱动连 11g 实例也可以,但没必要,老老实实用 ojdbc6。

另外,如果你的 Jeecg-boot 版本比较老,初始化脚本的目录结构可能跟我说的有点差异,但整体思路不变。版本差异主要影响脚本文件名,后面我会专门讲怎么找正确的脚本。

2. 装 Oracle 11g 前,先把系统"底子"打好

这一步看着简单,但其实是最容易被跳过、后面疯狂返工的地方。Oracle 对操作系统参数的要求比 MySQL 严格得多,少了某些依赖包,图形界面直接起不来;内核参数没调,安装过程中会报各种莫名其妙的错误。

2.1 系统依赖包、内核参数与用户限制

先检查系统版本,确认是 64 位 CentOS:

cat /etc/redhat-release uname -r

然后安装依赖包。Oracle 11g 官方要求一堆 compat 库,CentOS 7 上这些包有的在默认源里没有,需要先装 epel-release:

yum install -y epel-release yum install -y binutils compat-libcap1 compat-libstdc++-33 gcc gcc-c++ glibc \ glibc-devel libaio libaio-devel libgcc libstdc++ libstdc++-devel \ libXext libXtst libX11 libXau libXi make sysstat unixODBC unixODBC-devel

这些包里有几个特别容易漏:compat-libstdc++-33和libaio-devel。漏了它们,安装时打不开 runInstaller 或报libclntsh.so找不到的情况很常见。

接下来调内核参数。编辑/etc/sysctl.conf,在末尾追加以下内容:

fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.sem = 250 32000 100 128 kernel.shmmni = 4096 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048586 net.ipv4.ip_local_port_range = 9000 65500

执行sysctl -p生效。这几个参数里面,kernel.sem影响力最大,不调的话后面 dbca 建库很可能卡死或报内存信号量错误。

再改用户资源限制。编辑/etc/security/limits.conf,追加:

oracle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240

顺带把 pam 配置也确认一下,/etc/pam.d/login里确保有session required pam_limits.so这一行。这一步容易被忽略,但缺少它nofile限制不会生效。

2.2 创建 oracle 专用账号

官方规范是创建两个组oinstall和dba,账号名就叫oracle。这个账号不是随便建着玩的,后面所有 Oracle 操作都必须用它执行,千万别拿 root 去跑安装程序。

groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01/app/oracle chmod -R 775 /u01/app/oracle

/u01这个路径就是后面 ORACLE_BASE,如果你磁盘规划不一样,可以改成别的位置,但前后必须保持一致。生产环境建议单独挂一块数据盘给/u01,避免系统盘空间被数据库文件占满。

2.3 环境变量别偷懒

切换到 oracle 用户,编辑~/.bash_profile:

su - oracle vi ~/.bash_profile

追加:

export ORACLE_BASE=/u01/app/oracle export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1 export ORACLE_SID=orcl export PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK

NLS_LANG这个变量建议一开始就设成ZHS16GBK,跟后续建库时的字符集保持一致。否则后面导入的 SQL 里有中文注释,很容易出现乱码入库的情况。

环境变量设置完成后,source ~/.bash_profile让它生效。到这里系统底子就算打好了。

3. 一步步把 Oracle 11g 装起来,含监听和实例

这个阶段是整个部署里最需要耐心的。如果你的服务器有图形桌面环境,可以走图形安装;但生产环境大多是纯命令行的 CentOS 服务器,所以下面我直接按命令行方式来写,这也是最贴近生产场景的操作。

3.1 解压安装包与命令行安装

Oracle 11g R2 的安装包一般叫这两个:

  • linux.x64_11gR2_database_1of2.zip
  • linux.x64_11gR2_database_2of2.zip

把两个 zip 放到/u01/install目录下,然后解压:

su - oracle cd /u01/install unzip linux.x64_11gR2_database_1of2.zip unzip linux.x64_11gR2_database_2of2.zip

解压后会出现一个database目录,里面有runInstaller。命令行安装有两种方式:一种是准备 response 文件做完全静默安装,另一种是交互式但不开 X 窗口。

先看传统图形方式。如果你本地用 Xshell 或类似终端,可以配合 Xmanager 转发图形界面,在终端里设置 DISPLAY 后直接调出安装界面:

export DISPLAY=你的本机IP:0.0 cd /u01/install/database ./runInstaller

如果你不想搞图形转发,建议用响应文件静默安装。Oracle 自带响应文件模板在database/response/db_install.rsp,复制一份后修改关键项:

cp database/response/db_install.rsp db_install_custom.rsp

编辑db_install_custom.rsp,至少需要改这些内容:

oracle.install.option=INSTALL_DB_SWONLY ORACLE_HOSTNAME=你的主机名 UNIX_GROUP_NAME=oinstall INVENTORY_LOCATION=/u01/app/oraInventory SELECTED_LANGUAGES=en,zh_CN ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1 ORACLE_BASE=/u01/app/oracle oracle.install.db.InstallEdition=EE oracle.install.db.DBA_GROUP=dba oracle.install.db.OPER_GROUP=dba oracle.install.db.config.starterdb.type=GENERAL_PURPOSE oracle.install.db.config.starterdb.globalDBName=orcl oracle.install.db.config.starterdb.SID=orcl oracle.install.db.config.starterdb.characterSet=ZHS16GBK oracle.install.db.config.starterdb.memoryLimit=800 oracle.install.db.config.starterdb.password.ALL=你的数据库密码

这里有一个容易踩的坑:INVENTORY_LOCATION和ORACLE_BASE所在的目录必须保证 oracle 用户有写权限,否则安装一开始就报OUI-10086之类的问题。

然后执行安装:

cd /u01/install/database ./runInstaller -silent -responseFile /u01/install/db_install_custom.rsp

安装脚本跑完后,会提示你"以 root 身份执行以下脚本",一般是两个:

su - root /u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/11.2.0/dbhome_1/root.sh

这两个脚本不执行,后面的 dbca 建库会出错。这是新手最容易漏的步骤。

3.2 配置监听器与创建实例

软件装好了,接下来要建实例。先配置监听器,用 netca 的静默模式最简单:

su - oracle netca /silent /responseFile /u01/app/oracle/product/11.2.0/dbhome_1/network/install/netca_typ.rsp

执行完可以用lsnrctl status看看监听是否起来了。如果显示The command completed successfully,说明监听已运行。

创建实例用 dbca 静默模式。先规划实例名,这里统一用orcl,全局数据库名也叫orcl。一个大坑:字符集在这里要定好,后面基本改不了。我建议用ZHS16GBK,如果你确定要存多国语言数据,再考虑AL32UTF8。

dbca -silent -createDatabase \ -templateName General_Purpose.dbc \ -gdbname orcl -sid orcl \ -responseFile NO_VALUE \ -characterSet ZHS16GBK \ -sysPassword 你的密码 \ -systemPassword 你的密码 \ -datafileDestination /u01/app/oracle/oradata \ -recoveryAreaDestination /u01/app/oracle/flash_recovery_area \ -recoveryAreaSize 8192 \ -memoryPercentage 40

这条命令跑起来需要几分钟到十几分钟不等,取决于机器配置。如果中间报内存不足或/tmp空间不足,检查一下kernel.sem是否生效、/tmp是否够大(至少 1GB 可用空间)。

3.3 安装后的基础验证

实例建好后,先用操作系统认证进入数据库验证:

sqlplus / as sysdba

执行:

select status from v$instance; select name from v$database;

能查到OPEN状态和数据库名ORCL,说明实例没问题。再确认监听能识别服务:

lsnrctl services

看到orcl服务名,说明客户端可以通过 JDBC 连接了。到这里,Oracle 本身已经部署完成,接下来是给 Jeecg-boot 准备业务空间。

4. 建表空间、建用户、导入初始化 SQL,一步都不能省

Jeecg-boot 默认的数据库账号是root密码root之类,但实际生产环境绝对不能用默认账号。我们要建独立的表空间和用户,跟系统库隔离。

4.1 表空间怎么规划

先登录 sys:

sqlplus / as sysdba

创建 Jeecg-boot 专用的表空间。表空间文件不要放在系统目录里,放到/u01/app/oracle/oradata/orcl下比较合理:

CREATE TABLESPACE JEECGBOOT DATAFILE '/u01/app/oracle/oradata/orcl/jeecgboot.dbf' SIZE 1024M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;

这里SIZE 1024M是初始大小,AUTOEXTEND ON表示空间不够自动扩展。生产环境建议初始就给大一点,避免频繁扩展带来的性能抖动。

然后建临时表空间。Oracle 默认的 TEMP 表空间也能用,但隔离性不好,建议单独建一个:

CREATE TEMPORARY TABLESPACE JEECGBOOT_TEMP TEMPFILE '/u01/app/oracle/oradata/orcl/jeecgboot_temp.dbf' SIZE 512M AUTOEXTEND ON NEXT 100M MAXSIZE UNLIMITED;

4.2 创建业务用户并授权

创建用户时,把默认表空间指向刚建的 JEECGBOOT,临时表空间指向 JEECGBOOT_TEMP:

CREATE USER jeecgboot IDENTIFIED BY 你的业务密码 DEFAULT TABLESPACE JEECGBOOT TEMPORARY TABLESPACE JEECGBOOT_TEMP; GRANT CONNECT, RESOURCE TO jeecgboot; GRANT UNLIMITED TABLESPACE TO jeecgboot;

这里UNLIMITED TABLESPACE很重要,不授权的话,后面导入初始化脚本时一旦表空间配额用完就会报ORA-01536。

4.3 导入 Jeecg-boot 的 Oracle 初始化脚本

Jeecg-boot 项目的源码目录里通常会有一个db文件夹,里面放着各数据库的初始化脚本。MySQL 脚本文件名一般是jeecgboot-mysql.sql,Oracle 脚本一般叫jeecgboot-oracle.sql,也可能按版本分成多个脚本。它的位置一般在:

  • 后端工程源码的db/目录
  • 如果你是从官方仓库下载的发布包,通常在jeecg-boot/db/

在导入之前,先确认这个脚本是给 Oracle 用的,不要拿 MySQL 的脚本直接导入 Oracle。判断方式很简单:看里面的建表语句有没有反引号、有没有ENGINE=InnoDB、有没有AUTO_INCREMENT,有这些关键字的就是 MySQL 版。

用 jeecgboot 用户登录:

sqlplus jeecgboot/你的业务密码@localhost:1521/orcl

然后执行脚本。脚本文件大,建议用@方式导入:

@/你的路径/jeecgboot-oracle.sql

导入过程中如果报错,常见的有两类:

  • ORA-00900: invalid SQL statement:说明脚本里混了 MySQL 语法,需要改脚本
  • ORA-01950:表空间配额不足,回到上一步加UNLIMITED TABLESPACE授权

导入完成后,验证一下表数量:

select count(*) from user_tables;

Jeecg-boot 完整初始化后一般有几十到上百张表,如果你查出来数量明显不对,说明脚本执行中断过,需要排查具体报错点,而不是直接继续。

5. 把 Jeecg-boot 工程从 MySQL 切到 Oracle,配置就这么改

数据库这层准备好了,接下来是工程侧。很多人在这一步卡住,原因是对 Spring Boot 的数据源配置不熟悉,或者不知道 MyBatis 还需要单独设置数据库方言。

5.1 Maven 依赖:Oracle 驱动必须手动安装到本地仓库

Oracle 的 JDBC 驱动没有放在中央仓库,直接写进pom.xml是拉不下来的。你需要先把 ojdbc6 的 jar 包手动安装到 Maven 本地仓库。

先下载ojdbc6.jar(版本 11.2.0.3 或 11.2.0.4),然后执行:

mvn install:install-file \ -Dfile=ojdbc6.jar \ -DgroupId=com.oracle \ -DartifactId=ojdbc6 \ -Dversion=11.2.0.3 \ -Dpackaging=jar

然后在后端工程的pom.xml里加上依赖:

<dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency>

如果你用的是 Jeecg-boot 的微服务版本,记得在公共依赖模块加,而不是只加在某个微服务里。

5.2 数据源配置:application-dev.yml 的关键改动

Jeecg-boot 的配置通常分环境,开发环境是application-dev.yml,生产是application-prod.yml。找到数据源配置,把 MySQL 改成 Oracle:

spring: datasource: driver-class-name: oracle.jdbc.OracleDriver url: jdbc:oracle:thin:@你的数据库IP:1521:orcl username: jeecgboot password: 你的业务密码

这里有几个容易犯迷糊的点:

  • jdbc:oracle:thin:@IP:1521/orcl和jdbc:oracle:thin:@IP:1521:orcl的区别
  • 前者是 SID 连接方式,后者是 SERVICE_NAME 连接方式。Oracle 11g 默认用 SID 方式连接,所以冒号后直接跟orcl是没问题的。如果你用的是 12c+ 的 CDB/PDB,就得分清楚。

驱动类名一定不能写错,是oracle.jdbc.OracleDriver,不是oracle.jdbc.driver.OracleDriver。虽然两个在老版本里都能用,但新驱动推荐前者。

5.3 方言、分页与连接池参数

Jeecg-boot 使用了 Hibernate 的部分能力(比如代码生成器的 entity 映射),所以方言也要改。在 yml 里找到 jpa 配置,改成:

spring: jpa: database-platform: org.hibernate.dialect.Oracle10gDialect

这里用Oracle10gDialect而不是OracleDialect,原因是 Oracle 11g 的 SQL 方言跟 10g 基本一致,而OracleDialect对应的是更老版本,某些新语法不兼容。

分页这部分坑更大。Jeecg-boot 用的 MyBatis-Plus,它默认的动态方言可能还是 MySQL。如果你用了官方的分页插件,需要在配置类里明确指定 Oracle 方言:

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.ORACLE));

在 yml 中如果有一个mybatis-plus.global-config.db-config.dialect之类的配置项,直接改成oracle。

5.4 初始化脚本导入后还要处理兼容点

Jeecg-boot 的 Oracle 初始化脚本虽然官方是适配过的,但实际导入后还会有两个兼容问题需要手动处理。

第一个是序列问题。Oracle 没有 MySQL 的自增主键,Jeecg-boot 的 Oracle 脚本里会为相关表建序列和触发器,比如SEQ_SYS_USER这类。导入脚本后检查一下序列是否真的创建成功:

select sequence_name from user_sequences;

如果某个表的序列缺失,写入时就会报主键冲突。处理办法是手动补序列,或者看脚本里是否漏掉了触发器。

第二个是时间字段的默认值。Oracle 的SYSDATE跟 MySQL 的NOW()行为类似,但有些表结构用了DEFAULT CURRENT_TIMESTAMP,这在 Oracle 里会报错。脚本如果是从 MySQL 版改的,你需要把这些默认值统一改成SYSDATE,否则执行 DML 时会出现 ORA-00932。

6. 启动、联调与排错:从"装好了"到"能跑通"的最后一段路

配置全部改完后,就开始启动验证。别指望一次就能顺利跑起来,数据库切换涉及的细节太多,我在多个项目里踩过的坑,基本都在下面这个流程里。

6.1 后端启动验证

执行 Jeecg-boot 的启动入口,观察日志。出现Started JeecgSystemApplication且没有异常堆栈,说明后端已经连接 Oracle 成功了。

但光启动成功还不够,需要实际测两个功能:

  • 登录接口能不能通,验证 SQL 查询是否正常
  • 列表分页查询能不能正常返回,验证分页方言是否生效

如果启动时报错,大概率是以下几种情况之一,我直接给排查路径。

6.2 高频报错清单与处理方式

报错信息原因解决办法
ClassNotFoundException: oracle.jdbc.OracleDriverpom 里没有引入驱动,或本地仓库没有该 jar重新执行mvn install:install-file,并在 pom 中加入依赖
ORA-12541: TNS:no listener监听没启动,或端口不是 1521lsnrctl start启动监听,确认端口没被占
ORA-12514: TNS listener does not currently know of service requested连接串里的服务名不对确认是 SIDorcl还是 SERVICE_NAME,保持连接串和实际一致
ORA-01017: invalid username/password用户名或密码错误检查 yml 中的账号密码,用 sqlplus 手动验证
ORA-01034: ORACLE not available实例没启动sqlplus / as sysdba,执行startup
BadSqlGrammarExceptionSQL 语法不兼容 MySQL检查 SQL 里是否还有反引号、NOW()、LIMIT等 MySQL 专用语法
NoSuchMethodError或方言报错Hibernate 方言版本不匹配确认database-platform设置为Oracle10gDialect

6.3 我踩过的几个特别隐蔽的细节

第一,Oracle 中对空字符串的处理和 MySQL 不同。MySQL 里''和NULL是两回事,但 Oracle 把空字符串当成NULL。这会导致某些查询逻辑跟原来不一样,比如WHERE user_name = ''在 Oracle 里查不出任何东西。如果业务代码里依赖了空字符串判断,建议全局梳理一遍。

第二,Oracle 默认字段名是大写的,而 MySQL 默认小写。MyBatis-Plus 的map-underscore-to-camel-case配置通常没问题,但如果手动写 SQL 用了SELECT *,返回的 Map 的 key 是大写的,这时 JSON 序列化后字段名看起来就和原来不同。最省事的办法是在查询 SQL 里显式写别名。

6.4 前端工程在这一环节要做的配合

Jeecg-boot 前端一般通过接口访问后端,数据库切换后前端通常不用改代码。但要确认后端的端口、接口前缀没变化,以及前端的代理配置是否指向了新的后端地址。如果用 Nginx 部署,检查 upstream 指向的是不是新启动的后端服务即可。

最后再分享两句实在话

我在实际部署中最深的体会是:Jeecg-boot 切 Oracle 并不难,难的是在切换之前把数据库和工程之间的兼容问题提前摸清楚。建议先在测试环境完整跑一遍从 Oracle 安装到工程启动的流程,记录下每一条报错和改动,再上生产。生产环境的 Oracle 安装建议让 DBA 参与,尤其是表空间规划和字符集选择这两个决定,一旦定下来后面就不太好改了。

另外,Oracle 11g 已经在运行的项目,后续要特别留意归档日志的增长,尤其是初始化脚本导入和频繁联调这个阶段,日志增长很快,磁盘很容易被打满。我当时在一次全量导入测试中,归档日志直接把数据盘写满了,差点导致数据库无法启动。所以每完成一个阶段,最好清理一下归档日志,或者设置自动删除策略。

这篇基础上的"第二弹"先把数据库这条腿立住,接下来你就可以安心往后端业务代码、权限配置、生产上线那些方向去折腾了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询