JFinal+SQLite 解决Date类型与DATETIME类型转换异常

SQLite存储的数据读出来可能是String ,但是我们需要的是Date,就会出现转化异常

在不改动生产代码的前提下进行修改代码

复制代码
public class MyRecordBuilder extends RecordBuilder {
    @Override
    public List<Record> build(Config config, ResultSet rs, Function<Record, Boolean> func) throws SQLException {
        List<Record> result = new ArrayList<>();
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        String[] labelNames = new String[columnCount + 1];
        int[] types = new int[columnCount + 1];
        buildLabelNamesAndTypes(rsmd, labelNames, types);
        while (rs.next()) {
            Record record = new Record();
            CPI.setColumnsMap(record, config.getContainerFactory().getColumnsMap());
            Map<String, Object> columns = record.getColumns();
            for (int i = 1; i <= columnCount; i++) {
                Object value;
                if (types[i] < Types.BLOB) {
                    value = rs.getObject(i);
                    if(value!=null&&!"".equals(value)){
                        if (types[i] == Types.DATE) {//91 SQLite读到的数据是Date或者是TIMESTAMP,展现出来的是String
                            if(value instanceof String){//说明时间类型数据,需转成Date
                                value = changeDate(value.toString());
                            }
                        }else if (types[i] == Types.TIMESTAMP) {//93
                            if(value instanceof String){//说明时间类型数据,需转成Date
                                value = changeDate(value.toString());
                            }
                        }
                    }
                } else {
                    if (types[i] == Types.CLOB) {
                        value = ModelBuilder.me.handleClob(rs.getClob(i));
                    } else if (types[i] == Types.NCLOB) {
                        value = ModelBuilder.me.handleClob(rs.getNClob(i));
                    } else if (types[i] == Types.BLOB) {
                        value = rs.getBytes(i);
                    } else {
                        value = rs.getObject(i);
                    }
                }

                columns.put(labelNames[i], value);
            }

            if (func == null) {
                result.add(record);
            } else {
                if (!func.apply(record)) {
                    break;
                }
            }
        }
        return result;
    }

}
复制代码
public class MyModelBuilder extends ModelBuilder {
    @SuppressWarnings({"unchecked"})
    public <T> List<T> build(ResultSet rs, Class<? extends Model> modelClass, Function<T, Boolean> func) throws SQLException, ReflectiveOperationException {
        List<T> result = new ArrayList<>();
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        String[] labelNames = new String[columnCount + 1];
        int[] types = new int[columnCount + 1];
        buildLabelNamesAndTypes(rsmd, labelNames, types);
        while (rs.next()) {
            Model<?> ar = modelClass.newInstance();
            Map<String, Object> attrs = CPI.getAttrs(ar);
            for (int i=1; i<=columnCount; i++) {
                Object value;
                if (types[i] < Types.BLOB) {
                    value = rs.getObject(i);
                    if(value!=null&&!"".equals(value)){
                        if (types[i] == Types.DATE) {//91 SQLite读到的数据是Date或者是TIMESTAMP,展现出来的是String
                            if(value instanceof String){//说明时间类型数据,需转成Date
                                value = changeDate(value.toString());
                            }
                        }else if (types[i] == Types.TIMESTAMP) {//93
                            if(value instanceof String){//说明时间类型数据,需转成Date
                                value = changeDate(value.toString());
                            }
                        }
                    }
                } else {
                    if (types[i] == Types.CLOB) {
                        value = handleClob(rs.getClob(i));
                    } else if (types[i] == Types.NCLOB) {
                        value = handleClob(rs.getNClob(i));
                    } else if (types[i] == Types.BLOB) {
                        value = rs.getBytes(i);
                    } else {
                        value = rs.getObject(i);
                    }
                }

                attrs.put(labelNames[i], value);
            }

            if (func == null) {
                result.add((T)ar);
            } else {
                if ( ! func.apply((T)ar) ) {
                    break ;
                }
            }
        }
        return result;
    }
    public static Date changeDate(String str) {
        String[] formats = {"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd"};
        for (String format : formats) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                Date date = sdf.parse(str);
                return date;
            } catch (ParseException e) {
                // 如果解析失败,尝试下一个格式
            }
        }
        return null;
    }
}
复制代码
package com.jfinal.plugin.activerecord.dialect;

import com.jfinal.plugin.activerecord.CPI;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.Table;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wuqiujiang
 * @date 2025/7/16 12:25
 * @desc
 */

public class CustomSqlite3Dialect extends Sqlite3Dialect {

    @Override
    protected void fillStatementHandleDateType(PreparedStatement pst, List<Object> paras) throws SQLException {
        for (int i = 0; i < paras.size(); i++) {
            Object para = paras.get(i);
            if (para instanceof Date) {
                // 将 Date 转换为 SQLite 支持的字符串格式
                para = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(para);
            }
            pst.setObject(i + 1, para);
        }
    }
    @Override
    public void forModelUpdate(Table table, Map<String, Object> attrs, Set<String> modifyFlag, StringBuilder sql, List<Object> paras) {
        sql.append("update ").append(table.getName()).append(" set ");
        String[] pKeys = table.getPrimaryKey();
        Iterator var7 = attrs.entrySet().iterator();

        while(var7.hasNext()) {
            Map.Entry<String, Object> e = (Map.Entry)var7.next();
            String colName = (String)e.getKey();
            if (modifyFlag.contains(colName) && !this.isPrimaryKey(colName, pKeys) && table.hasColumnLabel(colName)) {
                if (paras.size() > 0) {
                    sql.append(", ");
                }

                sql.append(colName).append(" = ? ");
                Object val = e.getValue();
                if (val instanceof Date) {
                    val = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) val);
                }
                paras.add(val);
            }
        }

        sql.append(" where ");

        for(int i = 0; i < pKeys.length; ++i) {
            if (i > 0) {
                sql.append(" and ");
            }

            sql.append(pKeys[i]).append(" = ?");
            paras.add(attrs.get(pKeys[i]));
        }

    }

    @Override
    public void forDbSave(String tableName, String[] pKeys, Record record, StringBuilder sql, List<Object> paras) {
        tableName = tableName.trim();
        this.trimPrimaryKeys(pKeys);
        sql.append("insert into ");
        sql.append(tableName).append('(');
        StringBuilder temp = new StringBuilder();
        temp.append(") values(");
        Iterator var7 = record.getColumns().entrySet().iterator();

        while(var7.hasNext()) {
            Map.Entry<String, Object> e = (Map.Entry)var7.next();
            if (paras.size() > 0) {
                sql.append(", ");
                temp.append(", ");
            }

            sql.append((String)e.getKey());
            temp.append('?');
            Object val = e.getValue();
            if (val instanceof Date) {
                val = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) val);
            }
            paras.add(val);
        }

        sql.append(temp.toString()).append(')');
    }
    @Override
    public void forDbUpdate(String tableName, String[] pKeys, Object[] ids, Record record, StringBuilder sql, List<Object> paras) {
        tableName = tableName.trim();
        this.trimPrimaryKeys(pKeys);
        Set<String> modifyFlag = CPI.getModifyFlag(record);
        sql.append("update ").append(tableName).append(" set ");
        Iterator var8 = record.getColumns().entrySet().iterator();

        while(var8.hasNext()) {
            Map.Entry<String, Object> e = (Map.Entry)var8.next();
            String colName = (String)e.getKey();
            if (modifyFlag.contains(colName) && !this.isPrimaryKey(colName, pKeys)) {
                if (paras.size() > 0) {
                    sql.append(", ");
                }

                sql.append(colName).append(" = ? ");
                Object val = e.getValue();
                if (val instanceof Date) {
                    val = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) val);
                }
                paras.add(val);
            }
        }

        sql.append(" where ");

        for(int i = 0; i < pKeys.length; ++i) {
            if (i > 0) {
                sql.append(" and ");
            }

            sql.append(pKeys[i]).append(" = ?");
            paras.add(ids[i]);
        }

    }

}
相关推荐
名字还没想好☜8 小时前
Python f-string 进阶:数字格式化、对齐填充、调试 = 号与嵌套表达式
开发语言·数据库·python·字符串格式化·f-string
ltl9 小时前
Serverless 数据库弹性理论:Neon 与 Aurora Serverless v2
数据库
marvelyu13 小时前
每天10分钟学会OceanBase系列(Day 20):跨机房容灾实战——构建多数据中心高可用架构
java·大数据·数据库
ZCBUS实时计算14 小时前
金融证券实时数仓建设实践:轻量化实时计算平台落地,实现交易数据端到端秒级处理
大数据·数据库·数据仓库·金融·flink·dba·etl
zd20057214 小时前
海洋微生物数据库
数据库·宏基因组
海上小飞龙14 小时前
Redis 分布式锁原理:从 SET NX EX 到 Redisson 看门狗
数据库·redis·分布式
xiaoye-duck15 小时前
MySQL 表约束全解:从基础约束到外键关联规则
数据库·mysql
Hammer_Hans15 小时前
DFT笔记98
java·开发语言·数据库
迪康Defender15 小时前
从静态存储到动态流转:终端透明加密两种模式实战解析
运维·服务器·网络·数据库·其他
2601_9657984715 小时前
Is Piroll WordPress Theme Worth It for Freelancers? Full Review
数据库·php