RuoYi + H2 数据库:轻量部署实战踩坑全记录

导读: 若依(RuoYi)是国内使用广泛的 Java 快速开发框架,默认依赖 MySQL。但在演示环境、非专业研发人员使用、轻量级部署场景下,安装和维护 MySQL 显得过于"重"。本文记录了将若依项目改造为使用 H2 内嵌数据库的完整过程,包括踩坑记录与解决方案,供有同样需求的开发者参考。


一、为什么选择 H2?

H2 是一款纯 Java 编写的内嵌关系型数据库,具备以下优势:

  • 零安装

    :随 JAR 包启动,无需独立安装数据库服务

  • 兼容 MySQL 语法

    :通过 MODE=MYSQL 配置可兼容大部分 MySQL 语法

  • 自带 Web 控制台

    :方便开发调试,无需额外工具

  • 适合轻量部署

    :演示环境、CI/CD 流水线、本地开发首选


二、依赖配置

pom.xml 中添加 H2 相关依赖:

【特别注意】RuoYi v4.8.3 使用的spring-boot最新版本4.0.3,h2-console需单独引用

复制代码
<!-- H2 数据库驱动 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

<!-- H2 控制台(Spring Boot 集成) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-h2console</artifactId>
</dependency>

三、数据源配置

修改 application.yml,将数据源切换为 H2:

复制代码
spring:
  h2:
    console:
      enabled:true # 开启 H2 Web 控制台
datasource:
  druid:
    master:
      driverClassName:org.h2.Driver
      url:jdbc:h2:file:./data/h2db;MODE=MYSQL # 文件模式 + MySQL 兼容
      username:sa
      password:password

说明: jdbc:h2:file:./data/h2db 表示数据库以文件形式持久化存储在 ./data/ 目录下,重启后数据不丢失。MODE=MYSQL 开启 MySQL 兼容模式。


四、接入 H2 控制台

若依框架有权限控制,直接访问 /h2-console 会被拦截。需要新增一个控制器做跳转:

复制代码
@Controller
@RequestMapping("/tool/h2")
publicclassH2ConsoleControllerextendsBaseController {

@RequiresPermissions("tool:h2:view")
@GetMapping()
public String index() {
return"redirect:/h2-console";
    }
}

同时在系统菜单 中添加菜单项,路径配置为 /tool/h2,即可通过若依的权限体系访问 H2 控制台。


五、建表 SQL 的坑与解决方案

将 MySQL 的建表 SQL 迁移到 H2 时,使用AI生成适配的SQL文件,如下图所示:

AI 生成的 SQL 文件(ry_20260319_h2.sqlquartz_h2.sql)存在以下几类问题:

1. 转义字符问题

问题 MySQL 写法 H2 正确写法
单引号转义 \' '' (两个单引号)
双引号 \" " (无需反斜杠)

2. 自增主键序列问题

初始化 SQL 中包含带主键值的 INSERT 语句,导致 H2 的自增序列不会自动更新。后续通过页面新增数据时,主键从 1 开始,与已有数据冲突。

解决方案: 在初始化 SQL 末尾追加序列重置语句:

复制代码
ALTER TABLE SYS_CONFIG ALTERCOLUMN config_id RESTART WITHSELECTMAX(config_id)+1FROM SYS_CONFIG;
ALTER TABLE SYS_DEPT ALTERCOLUMN dept_id RESTART WITHSELECTMAX(dept_id)+1FROM SYS_DEPT;
ALTER TABLE SYS_DICT_DATA ALTERCOLUMN dict_code RESTART WITHSELECTMAX(dict_code)+1FROM SYS_DICT_DATA;
ALTER TABLE SYS_DICT_TYPE ALTERCOLUMN dict_id RESTART WITHSELECTMAX(dict_id)+1FROM SYS_DICT_TYPE;
ALTER TABLE SYS_JOB ALTERCOLUMN job_id RESTART WITHSELECTMAX(job_id)+1FROM SYS_JOB;
ALTER TABLE SYS_MENU ALTERCOLUMN menu_id RESTART WITHSELECTMAX(menu_id)+1FROM SYS_MENU;
ALTER TABLE SYS_NOTICE ALTERCOLUMN notice_id RESTART WITHSELECTMAX(notice_id)+1FROM SYS_NOTICE;
ALTER TABLE SYS_POST ALTERCOLUMN post_id RESTART WITHSELECTMAX(post_id)+1FROM SYS_POST;
ALTER TABLE SYS_ROLE ALTERCOLUMN role_id RESTART WITHSELECTMAX(role_id)+1FROM SYS_ROLE;
ALTER TABLE SYS_USER ALTERCOLUMN user_id RESTART WITHSELECTMAX(user_id)+1FROM SYS_USER;

3. MySQL 函数替换

H2 不支持部分 MySQL 专有函数,需逐一替换:

① 当前时间函数

复制代码
-- MySQL
sysdate()

-- H2 替换为
CURRENT_TIMESTAMP()

② 时间范围查询

复制代码
-- MySQL(date_format 函数 H2 不支持)
AND date_format(create_time,'%Y%m%d') >= date_format(#{params.beginTime},'%Y%m%d')
AND date_format(create_time,'%Y%m%d') <= date_format(#{params.endTime},'%Y%m%d')

-- H2 替换为(直接字符串拼接时间范围)
AND create_time >= concat(#{params.beginTime},' 00:00:00')
AND create_time <= concat(#{params.endTime},' 23:59:59')

③ CAST 类型转换

复制代码
-- MySQL(cast as char 在 H2 中不兼容)
CAST(notice_content ASchar)

-- H2 替换为(直接使用字段名)
notice_content

④ FIND_IN_SET 函数

复制代码
-- MySQL(H2 不支持 FIND_IN_SET)
find_in_set(#{deptId}, ancestors)

-- H2 替换为(使用 INSTR 模拟)
INSTR(CONCAT(ancestors,','), CONCAT(#{deptId},','))

原理说明: FIND_IN_SET 是 MySQL 专有函数,用于在逗号分隔的字符串中查找指定值。H2 中可用 INSTR 函数替代------通过在 ancestors 末尾追加逗号,再查找 deptId, 的位置,避免子串误匹配(如 1 匹配到 1011 等)。


六、暂不改造的部分

代码生成器目前暂未进行 H2 适配,如需使用代码生成功能,切换回 MySQL 数据源即可。后续有时间再研究。


七、总结

改造项 状态 备注
依赖引入 ✅ 完成 添加 H2 驱动和控制台依赖
数据源配置 ✅ 完成 文件模式 + MySQL 兼容
H2 控制台接入 ✅ 完成 通过权限控制器跳转
建表 SQL 迁移 ✅ 完成 修复转义、序列、函数问题
代码生成器 ⏳ 待改造 暂时使用 MySQL

整体改造工作量不大,主要精力在 SQL 兼容性处理上。改造完成后,项目可以做到开箱即用、无需安装任何外部数据库,非常适合演示和轻量化部署场景。


如果本文对你有帮助,欢迎点赞收藏,有问题欢迎在评论区交流 👇


相关推荐
沐风清扬1 天前
微服务-进阶与底层原理学习备忘录
微服务·若依
清寒一缕震丝魂2 天前
个人原创自定义计算公式组件可继续扩展
javascript·vue.js·elementui·ruoyi
RuoyiOffice5 天前
企业请假销假系统设计实战:一张表、一套流程、两段生命周期——BPM节点驱动的表单变形术
java·spring·uni-app·vue·产品运营·ruoyi·anti-design-vue
RuoyiOffice5 天前
SpringBoot+Vue3+Uniapp实现PC+APP双端考勤打卡设计:GPS围栏/内网双模打卡、节假日方案、定时预生成——附数据结构和核心源码讲解
java·spring·小程序·uni-app·vue·产品运营·ruoyi
陈晓明start12 天前
【ruoyi】部署笔记
ruoyi
嫂子开门我是_我哥16 天前
从零开发微信小程序+若依后端项目:本地全流程开发,从环境搭建到前后端联调跑通
微信小程序·小程序·若依
狂龙骄子18 天前
如何修改ElementUI表单与表格标签label样式
elementui·vue·ruoyi·el-form-item·el-table-column·表单项label·列表头label
zihan03211 个月前
若依(RuoYi)框架升级适配 JDK 21 和 SpringBoot 3.5.10
java·spring boot·spring·若依·若依升级jdk21
狂龙骄子1 个月前
RuoYi-Vue字典标签CSS样式自定义指南
css·前端框架·ruoyi·数据字典·若依·字典标签·样式属性