From 32090ff06e6975514ed1cb60f04147894eda141a Mon Sep 17 00:00:00 2001
From: zzy <2450266535@qq.com>
Date: Sun, 24 May 2026 01:01:59 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0SQLite=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=94=AF=E6=8C=81=E5=B9=B6=E8=BF=81=E7=A7=BB?=
=?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=BD=AC=E6=8D=A2=E8=84=9A=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 新增init_sqlite.py脚本,用于将MySQL转储文件转换为SQLite数据库
- 实现MySQL到SQLite的语法转换,包括数据类型映射、表结构清理等功能
- 在pom.xml中替换MySQL驱动为SQLite驱动,并添加JDBC依赖
- 更新application.yml配置文件,切换数据库连接从MySQL到SQLite
- 配置HikariCP连接池参数以适配SQLite数据库特性
---
init_sqlite.py | 124 +++++++++++++++++++++++++++++
pom.xml | 13 ++-
src/main/resources/application.yml | 18 ++++-
3 files changed, 150 insertions(+), 5 deletions(-)
create mode 100644 init_sqlite.py
diff --git a/init_sqlite.py b/init_sqlite.py
new file mode 100644
index 0000000..39a2f4e
--- /dev/null
+++ b/init_sqlite.py
@@ -0,0 +1,124 @@
+"""Convert MySQL dump to SQLite database using executescript."""
+import re
+import sqlite3
+import os
+
+MYSQL_DUMP = os.path.join(os.path.dirname(__file__), '..', 'psychologicaltreatment.sql')
+MYSQL_DUMP = os.path.normpath(MYSQL_DUMP)
+DB_PATH = os.path.join(os.path.dirname(__file__), 'psychologicaltreatment.db')
+
+
+def preprocess(sql):
+ """Remove MySQL-specific syntax, returns SQLite-compatible SQL."""
+ # Remove lines that are MySQL meta commands
+ lines = []
+ for line in sql.splitlines():
+ stripped = line.strip().upper()
+ if any(stripped.startswith(x) for x in
+ ['SET NAMES', 'SET FOREIGN_KEY_CHECKS', 'SET SQL_MODE',
+ 'SET TIME_ZONE', 'SET CHARACTER_SET']):
+ continue
+ lines.append(line)
+ sql = '\n'.join(lines)
+
+ # Process each CREATE TABLE separately
+ # Strategy: find each CREATE TABLE block, clean it, replace it
+ def clean_create(match):
+ block = match.group(0)
+
+ # Remove table-level options: ENGINE=..., AUTO_INCREMENT=N, etc.
+ block = re.sub(r'\)\s*ENGINE.*?;', ');', block, flags=re.IGNORECASE | re.DOTALL)
+
+ # Remove inline CHARACTER SET / COLLATE (column-level)
+ block = re.sub(r'\s*CHARACTER\s+SET\s+\S+(?:\s+COLLATE\s+\S+)?', '', block, flags=re.IGNORECASE)
+ block = re.sub(r'\s+COLLATE\s+\S+', '', block, flags=re.IGNORECASE)
+
+ # Remove inline COMMENT '...'
+ block = re.sub(r"\s+COMMENT\s+'[^']*'", '', block, flags=re.IGNORECASE)
+
+ # Remove USING BTREE
+ block = re.sub(r'\s+USING\s+BTREE', '', block, flags=re.IGNORECASE)
+
+ # Remove ON UPDATE CURRENT_TIMESTAMP
+ block = re.sub(r'\s+ON\s+UPDATE\s+CURRENT_TIMESTAMP\s*(?:\([^)]*\))?', '', block, flags=re.IGNORECASE)
+
+ # MySQL types -> SQLite
+ block = re.sub(r'\b(tinyint|smallint|mediumint|bigint|int)\s*\(\s*\d+\s*\)', 'INTEGER', block, flags=re.IGNORECASE)
+ block = re.sub(r'\b(tinyint|smallint|mediumint|bigint|int)\b', 'INTEGER', block, flags=re.IGNORECASE)
+ block = re.sub(r'\bvarchar\s*\(\s*\d+\s*\)', 'TEXT', block, flags=re.IGNORECASE)
+ block = re.sub(r'\bdatetime\s*(?:\([^)]*\))?', 'TEXT', block, flags=re.IGNORECASE)
+ block = re.sub(r'\bdate\b', 'TEXT', block, flags=re.IGNORECASE)
+ block = re.sub(r'\b(tinytext|mediumtext|longtext)\b', 'TEXT', block, flags=re.IGNORECASE)
+
+ # AUTO_INCREMENT -> AUTOINCREMENT as INTEGER PRIMARY KEY
+ block = re.sub(
+ r'(`\w+`)\s+INTEGER\s+NOT\s+NULL\s+AUTO_INCREMENT',
+ r'\1 INTEGER PRIMARY KEY AUTOINCREMENT',
+ block, flags=re.IGNORECASE
+ )
+ block = re.sub(r'\bAUTO_INCREMENT\b', 'AUTOINCREMENT', block, flags=re.IGNORECASE)
+
+ if 'AUTOINCREMENT' in block:
+ block = re.sub(r'\s*,\s*PRIMARY\s+KEY\s*\(`\w+`\)', '', block, flags=re.IGNORECASE)
+
+ # Remove standalone INDEX/KEY lines
+ lines2 = block.splitlines()
+ result2 = []
+ for ln in lines2:
+ s = ln.strip()
+ if re.match(r'^\s*(INDEX|KEY)\s+', s, re.IGNORECASE) and \
+ not re.match(r'^\s*(PRIMARY|UNIQUE)\s', s, re.IGNORECASE):
+ # Remove trailing comma from previous line
+ if result2 and result2[-1].strip().endswith(','):
+ result2[-1] = result2[-1].rstrip(',')
+ continue
+ result2.append(ln)
+ block = '\n'.join(result2)
+
+ # Remove trailing comma before )
+ block = re.sub(r',\s*\)', '\n)', block)
+
+ return block
+
+ # Apply clean_create to all CREATE TABLE blocks
+ sql = re.sub(r'CREATE\s+TABLE.*?;', clean_create, sql, flags=re.IGNORECASE | re.DOTALL)
+
+ return sql
+
+
+def main():
+ with open(MYSQL_DUMP, 'r', encoding='utf-8') as f:
+ raw = f.read()
+
+ sqlite_sql = preprocess(raw)
+
+ if os.path.exists(DB_PATH):
+ os.remove(DB_PATH)
+
+ conn = sqlite3.connect(DB_PATH)
+ conn.execute("PRAGMA journal_mode=WAL;")
+ conn.execute("PRAGMA foreign_keys=OFF;")
+
+ # Use executescript which handles statement splitting properly
+ try:
+ conn.executescript(sqlite_sql)
+ except sqlite3.Error as e:
+ print(f"Error during executescript: {e}")
+
+ conn.commit()
+
+ # Verify
+ cursor = conn.execute("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
+ tables = [row[0] for row in cursor.fetchall()]
+ print(f"Database: {DB_PATH}")
+ print(f"Tables created: {len(tables)}")
+ for t in tables:
+ if t == 'sqlite_sequence':
+ continue
+ count = conn.execute(f'SELECT COUNT(*) FROM "{t}"').fetchone()[0]
+ print(f" {t}: {count} rows")
+ conn.close()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/pom.xml b/pom.xml
index 846a7dd..bd48eac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,11 +25,22 @@
spring-boot-starter-web
-
+
+
+
+ org.xerial
+ sqlite-jdbc
+
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+
com.baomidou
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 68c667f..1fb8831 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,12 +2,22 @@ server:
port: 9090
# 数据库配置
+# MySQL原始配置
+#spring:
+# datasource:
+# driver-class-name: com.mysql.cj.jdbc.Driver
+# username: root
+# password: 123456
+# url: jdbc:mysql://localhost:3306/psychologicaltreatment?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
+
+# SQLite
spring:
datasource:
- driver-class-name: com.mysql.cj.jdbc.Driver
- username: root
- password: 123456
- url: jdbc:mysql://localhost:3306/psychologicaltreatment?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
+ driver-class-name: org.sqlite.JDBC
+ url: jdbc:sqlite:psychologicaltreatment.db
+ hikari:
+ maximum-pool-size: 1
+ minimum-idle: 1
servlet:
multipart:
max-file-size: 100MB