SQLite的Blob类型支持

使用Jfinal读取SQLite数据库表 Blob 类型的时候会抛出 not implemented by SQLite JDBC driver,
原因是因为 sqlite的driver中,JDBC4ResultSet没有实现以下接口:

    public Blob getBlob(int col)
        throws SQLException { throw unused(); }    
    public Blob getBlob(String col)
        throws SQLException { throw unused(); }

需要用下面两个接口才能读取SQLite的Blob数据类型

    InputStream getBinaryStream(int col)
    byte[] getBytes(int col)

    

在Mybatis里是通过在mapper里添加 typeHandler 实现读取Blob类型, 

https://blog.csdn.net/mengshangwangzi/article/details/114107319
请问JFinal里有对应方法吗?
还是暂时需要自己修改JFinal的源码?

目前没有修改JFinal源码,暂时通过SQLite的把byte[]转16进制然后再用Jfinal读取的方式 

select hex(column) as column_hex from table;


评论区

JFinal

2024-10-26 14:58

问一下 chat gpt ,回复可以参考一下,虽然结果出现了了幻觉,但思路值得借签,它提出继承 dialect, 其实应该是要继承 ModelBuilder、RecordBuilder,然后处理一下获取数的地方:

是的,您可以在 JFinal 中通过自定义 Dialect(方言)来解决从 SQLite 数据库读取 Blob 类型数据的问题,而无需修改 JFinal 的源代码。

问题原因:

SQLite JDBC 驱动程序未实现 getBlob 方法,因此当 JFinal 使用默认的 getBlob 方法读取 Blob 数据时,会抛出 “not implemented by SQLite JDBC driver” 的异常。

解决方案:

创建自定义 Dialect:

您可以创建一个自定义的 Dialect 类,继承自 JFinal 提供的 SQLiteDialect 或直接继承 com.jfinal.plugin.activerecord.dialect.Dialect。

java
复制代码
public class CustomSQLiteDialect extends SQLite3Dialect {
@Override
public Object getValue(ResultSet rs, String colName, Class type) throws SQLException {
if (type == byte[].class) {
// 使用 getBytes 方法读取 Blob 数据
return rs.getBytes(colName);
}
return super.getValue(rs, colName, type);
}
}
注册自定义 Dialect:

在您的 JFinal 配置中,注册您自定义的 Dialect:

java
复制代码
ActiveRecordPlugin arp = new ActiveRecordPlugin(...);
arp.setDialect(new CustomSQLiteDialect());
me.add(arp);
使用自定义类型映射(可选):

如果需要,您还可以自定义类型转换器,以确保 Blob 类型的数据被正确地映射为 byte[]:

java
复制代码
public class CustomTypeConverter extends TypeConverter {
@Override
public Object convert(Class type, Object value) {
if (value instanceof byte[]) {
return value;
}
return super.convert(type, value);
}
}
然后在配置中设置自定义的类型转换器:

java
复制代码
arp.setTypeConverter(new CustomTypeConverter());
总结:

通过自定义 Dialect,您可以控制 JFinal 在从 ResultSet 中读取数据时的行为,使用 getBytes 或 getBinaryStream 方法来读取 Blob 数据类型。这种方式无需修改 JFinal 的源代码,且解决了 SQLite JDBC 驱动未实现 getBlob 方法的问题。

杜福忠

2024-10-26 16:01

刚在 gitee 仓库看到issues 了, https://gitee.com/jfinal/jfinal/issues/IAZVXR

杜福忠

2024-10-26 16:14

把代码贴过来:
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
Sqlite3Dialect d3 = new Sqlite3Dialect();
d3.setRecordBuilder(new MyRecordBuilder());
d3.setModelBuilder(new MyModelBuilder());
arp.setDialect(d3);

继承RecordBuilder 和 ModelBuilder 覆写build方法里面的
value = handleBlob(rs.getBlob(i));
改为:
value = rs.getBytes(i);
MyRecordBuilder 与 MyModelBuilder 代码在上面issues里面,这里回复区贴不下

本人纯属虚构

2024-10-26 21:05

@杜福忠 感谢,已经测试通过 谢谢

热门分享

扫码入社