Java使用SQLite时如何在应用首次启动时初始化不存在的数据库及基础数据
可行实现方式
- 原生JDBC轻量校验实现:适合小项目、没有引入额外ORM框架的场景,逻辑最简单
SQLite在调用DriverManager.getConnection("jdbc:sqlite:FinanceControl.sqlite")时,如果指定路径的数据库文件不存在,会自动创建空的数据库文件,所以只需要在获取连接后,查询SQLite内置的sqlite_master系统表,判断业务表是否存在,如果不存在就执行建表、插入预置数据的逻辑即可。
修改后的DBController参考代码:
package com.example.financecontrol; import java.sql.*; public class DBController { public static Connection Connector() { try { Class.forName("org.sqlite.JDBC"); Connection conn = DriverManager.getConnection("jdbc:sqlite:FinanceControl.sqlite"); // 新增初始化逻辑 initDBIfNeeded(conn); return conn; } catch (Exception e) { System.out.println(e); return null; } } private static void initDBIfNeeded(Connection conn) throws SQLException { // 检查是否已经存在业务表,这里以配置表config为例,可替换为你自己的核心业务表名 String checkTableSql = "SELECT count(*) as cnt FROM sqlite_master WHERE type='table' AND name='config'"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(checkTableSql)) { if (rs.next() && rs.getInt("cnt") == 0) { // 没有表,执行初始化SQL // 1. 建表语句,根据业务需求自行修改 String createTableSql = """ CREATE TABLE config ( id INTEGER PRIMARY KEY AUTOINCREMENT, config_key TEXT NOT NULL UNIQUE, config_value TEXT NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE bill ( id INTEGER PRIMARY KEY AUTOINCREMENT, amount REAL NOT NULL, type TEXT NOT NULL, remark TEXT, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); """; stmt.executeUpdate(createTableSql); // 2. 插入预置基础数据 String initDataSql = """ INSERT INTO config (config_key, config_value) VALUES ('app_version', '1.0.0'), ('default_currency', 'CNY'); """; stmt.executeUpdate(initDataSql); } } } }
- 版本化初始化实现:适合需要长期迭代、后续会有表结构变更的项目
利用SQLite支持的user_version自定义版本标记,第一次初始化时把版本号设为1,后续每次表结构变更就升级版本号,启动时读取当前库的版本号,和应用支持的最新版本号对比,执行对应版本的升级脚本,既可以完成首次初始化,也可以支持后续版本平滑升级,不会重复执行SQL。
核心逻辑示例:
// 读取当前库版本 try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("PRAGMA user_version")) { int currentVersion = rs.getInt(1); int latestVersion = 1; // 应用支持的最新版本 if (currentVersion == 0) { // 首次初始化,执行建表和插数据逻辑,然后把版本号设为1 stmt.executeUpdate("PRAGMA user_version = 1"); } else if (currentVersion < latestVersion) { // 执行版本升级逻辑,比如currentVersion=1、latestVersion=2时新增字段/表 } }
- ORM框架自动建表实现:适合已经引入ORM框架的项目
如果项目已经用了Hibernate、MyBatis-Plus这类框架,直接用框架自带的自动建表特性即可:- Hibernate:配置
hibernate.hbm2ddl.auto参数为update,启动时会自动对比实体类和表结构,不存在就自动建表 - MyBatis-Plus:引入自动建表插件,配置后启动会自动根据实体类生成表结构,也支持执行初始化SQL脚本
- Hibernate:配置
注意事项
- 初始化逻辑建议放在事务里执行,避免执行到一半异常导致表结构不完整
- 预置数据插入前可以加存在性判断,避免重复插入
- 如果初始化SQL比较多,建议把SQL语句单独存放到
src/main/resources下的sql文件中,代码里读取文件内容执行,不要硬编码在Java类中,方便维护
内容的提问来源于stack exchange,提问作者Artyom Belsky
相关产品推荐
相关产品推荐

