JOOQ Converter/Binding未执行加密代码排查:PostgreSQL bytea列存储BigDecimal[][][]加密数据异常
问题根源:你绕开了JOOQ的执行流程
你的核心问题其实很清晰——你直接使用了原生JDBC的PreparedStatement执行插入,完全跳过了JOOQ的整个转换/绑定机制,这就导致你配置的EncryptionBinding根本没有被调用的机会。
JOOQ的Converter和Binding是深度集成在JOOQ自身的SQL执行链路里的,只有当你通过JOOQ生成的DAO、DSLContext等API来构建和执行SQL时,JOOQ才会在合适的节点触发这些绑定逻辑。而你手动获取Connection创建PreparedStatement的操作,已经脱离了JOOQ的管控,加密代码自然不会生效。
正确实现方式:改用JOOQ API执行操作
你需要调整代码,用JOOQ提供的方式来执行插入,这样才能让Binding生效:
方式1:用JOOQ DSL构建插入语句
假设你通过codegen生成了表对象MY_TABLE,对应列是MATRIX_COLUMN,可以这样写:
private Result executeInsert(BigDecimal[][][] valueToEncrypt) { try (Connection conn = config.connectionProvider().acquire()) { DSLContext dsl = DSL.using(conn, SQLDialect.POSTGRES); // 用JOOQ DSL构建插入,自动触发Binding的加密逻辑 Result<?> result = dsl.insertInto(MY_TABLE) .set(MY_TABLE.MATRIX_COLUMN, valueToEncrypt) .returning() .fetch(); return result; } catch (SQLException e) { throw new RuntimeException("插入失败", e); } }
方式2:使用JOOQ生成的DAO类
如果已经生成了对应表的DAO(比如MyTableDao),直接调用DAO的方法更简洁:
private Result executeInsert(BigDecimal[][][] valueToEncrypt) { MyTableDao dao = new MyTableDao(config); MyTableRecord record = dao.newRecord(); record.setMatrixColumn(valueToEncrypt); dao.insert(record); // 如果需要返回插入后的记录,可按需调整 return dao.fetchByMatrixColumn(valueToEncrypt); }
JOOQ Converter/Binding的执行时机解析
再帮你梳理下这些组件在JOOQ流程中的触发节点,避免以后踩坑:
- SQL构建阶段:
Binding.sql()会被调用,用来生成匹配数据库类型的SQL占位符声明 - 参数设置阶段:
Binding.set()触发,流程是:- 先调用
converter().to(userObject),把你的BigDecimal[][][]转换成加密后的byte[] - 再将加密后的字节数组设置到JDBC的
PreparedStatement中
- 先调用
- 结果读取阶段:
Binding.get()触发,调用converter().from(databaseObject),把数据库存储的加密byte[]解密并转换成BigDecimal[][][]
额外代码优化建议
你的EncryptionBinding里有两个细节可以调整:
- 补充
sql()方法的实现,确保生成正确的PostgreSQLbytea类型声明:
@Override public void sql(BindingSQLContext<BigDecimal[][][]> ctx) throws SQLException { ctx.render().visit(DSL.val(ctx.convert(converter()).value(), SQLDataType.BYTEA)); }
- 修正
register()方法的参数类型,和bytea列匹配:
@Override public void register(BindingRegisterContext<BigDecimal[][][]> ctx) throws SQLException { ctx.statement().registerOutParameter(ctx.index(), Types.BINARY); }
内容的提问来源于stack exchange,提问作者jban
相关产品推荐
相关产品推荐

