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]);
        }

    }

}
相关推荐
qq_416018722 小时前
用Python批量处理Excel和CSV文件
jvm·数据库·python
逐鹿艾缇3 小时前
【达梦数据库】锁超时
数据库
F1FJJ3 小时前
只是想查个数据,不想装 phpMyAdmin
数据库·网络协议·容器·开源软件
蓝天守卫者联盟13 小时前
2026乙酸乙酯回收设备厂家选型与技术实践
java·jvm·python·算法
Johnstons3 小时前
2026企业网络流量监控与分析工具对比
运维·网络·数据库·网络流量监控·网络流量分析
IMPYLH3 小时前
Linux 的 dirname 命令
linux·运维·服务器·数据库
摇滚侠3 小时前
限流的方法,Redis 计算器限流算法、滑动时间窗口限流算法、漏漏桶限流算法、令牌桶限流算法,Java 开发
java·数据库·redis
吾诺3 小时前
mysql用户名怎么看
数据库·mysql