之前我的NewBot-Nova(微信机器人)项目是用的MySQL数据库,主要是自己用。后面很多网友希望我能把项目开源出来,考虑到MySQL使用起来比较麻烦。如果后续有人把NewBot部署到服务器上还得再搭建个云端数据库,这就增加了很大的工作量。我在慢慢接触面向“微信”开发的过程,发现其使用的是Sqlite3数据库。不得不说微信的设计者真的很牛逼,这样把数据库隐藏在用户端无疑是减轻了云端的资源成本。在这之前我使用过类似的也只有“H2”数据库,同样是可以随项目移动的,因为它只是个jar包。缺点也是很多的,这里就不一一列举了。
那么应该怎么迁移呢?首先要注意几个注意事项:
1.数据库部分字段的类型转换问题:Sqlite数据库里面没有date类型字段,时间格式只能用text储存。
2.mapper.xml文件中自定义SQL语句的大小写问题。
3.更换pom.xml中的maven依赖以及application.yml中的驱动器配置。
4.我的项目用到了MyBatis-Plus,所以需要把MyMetaObjectHandler(自定义填充处理类)里面适用于对MySQL数据库时间字段填充的地方都改成适用于Sqlite数据库的。
5.之前我把项目的时间类型都改成了Date,这下还得改回去(LocalDateTime)。
现在就可以根据步骤进行处理了,相关部分处理如下:

pom.xml:
        <dependency>
            <groupId>org.xerial</groupId>
            <artifactId>sqlite-jdbc</artifactId>
            <version>3.46.0.0</version>
        </dependency>
application.yml:
  datasource:
    url: jdbc:sqlite:./data/NewBot.db
    # SQLite 不需要用户名和密码,可以省略或留空
    username: root
    password: 888888
    driver-class-name: org.sqlite.JDBC
MyMetaObjectHandler:
package com.chaizhou.config;


import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @Author zF.
 * @ClassName MyMetaObjectHandler.java
 * @ProjectName NewBot-Nova
 * @Description MP自动填充处理类
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        // 检查字段是否为空,避免覆盖已有值
        if (getFieldValByName("createTime", metaObject) == null) {
            setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        }
        if (getFieldValByName("updateTime", metaObject) == null) {
            setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
    }
}
实体类的时间格式:
    @ApiModelProperty("注册时间")
    @TableField(value = "CREATE_TIME", fill = FieldFill.INSERT)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    @ApiModelProperty("更新时间")
    @TableField(value = "UPDATE_TIME", fill = FieldFill.INSERT_UPDATE)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

最后是MyBatis-Plus的代码生成器修改:

/**
     * 数据源配置
     */
    private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
            .Builder("jdbc:sqlite:./data/newbot.db", "root", "888888")
            .dbQuery(new SqliteQuery()) // 使用 SQLite 的查询类
            .typeConvert(new SqliteTypeConvert()) // 使用 SQLite 的类型转换器
            .keyWordsHandler(new SqliteKeyWordsHandler()); // 使用 SQLite 的关键字处理器
            ··· ···

使用自定义的关键字处理器:

package com.chaizhou.event;

import com.baomidou.mybatisplus.generator.config.IKeyWordsHandler;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author zF.
 * @ClassName SqliteKeyWordsHandler.java
 * @ProjectName NewBot-Nova
 * @Description 自定义SQLite的关键字处理器
 */
public class SqliteKeyWordsHandler implements IKeyWordsHandler {
    private static final Set<String> SQLITE_KEYWORDS = new HashSet<>();

    static {
        // SQLite 关键字列表,可以根据需要扩展
        String[] keywords = {
                "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND",
                "AS", "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN",
                "BY", "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN",
                "COMMIT", "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
                "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
                "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DROP", "EACH",
                "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
                "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING",
                "IF", "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY",
                "INNER", "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL",
                "JOIN", "KEY", "LEFT", "LIKE", "LIMIT", "MATCH", "NATURAL", "NO",
                "NOT", "NOTNULL", "NULL", "OF", "OFFSET", "ON", "OR", "ORDER",
                "OUTER", "PLAN", "PRAGMA", "PRIMARY", "QUERY", "RAISE", "RECURSIVE",
                "REFERENCES", "REGEXP", "REINDEX", "RELEASE", "RENAME", "REPLACE",
                "RESTRICT", "RIGHT", "ROLLBACK", "ROW", "SAVEPOINT", "SELECT",
                "SET", "TABLE", "TEMP", "TEMPORARY", "THEN", "TO", "TRANSACTION",
                "TRIGGER", "UNION", "UNIQUE", "UPDATE", "USING", "VACUUM", "VALUES",
                "VIEW", "VIRTUAL", "WHEN", "WHERE", "WITH", "WITHOUT"
        };
        for (String keyword : keywords) {
            SQLITE_KEYWORDS.add(keyword);
        }
    }

    @Override
    public @NotNull Collection<String> getKeyWords() {
        return null;
    }

    @Override
    public @NotNull String formatStyle() {
        return null;
    }

    @Override
    public boolean isKeyWords(@NotNull String columnName) {
        return SQLITE_KEYWORDS.contains(columnName.toUpperCase());
    }
}

好了,做完这些基本上就大功告成了。

什么?你问我Sqlite3数据库怎么安装?不需要安装,你用Navicat之类的数据库工具新建一个就行了。它是一个文件,例如:NewBot.db,在操作数据的时候用Navicat打开就好了。之后项目部署上线的时候,直接把这个文件复制过去,项目里面指定对应的路径就可以了。怎么样?是不是很方便?

最后修改:2024 年 09 月 30 日
给我一点小钱钱也很高兴啦!o(* ̄▽ ̄*)ブ