[咨询] 字段映射问题
Description
我使用字段映射功能,重写了setColumn和getKey方法,在初始化时正常输入内容,但是当我调用查询时,ColumnUtil.VERSIONED_KEY_COLUMN_MAP为空了
代码内容 public class TunnelSqlConfig extends APIJSONSQLConfig<String> {
/**
* 默认构造函数
*/
public TunnelSqlConfig() {
super();
}
/**
* 带参数构造函数
*
* @param method 请求方法
* @param table 表名
*/
public TunnelSqlConfig(RequestMethod method, String table) {
super(method, table);
}
static {
// 设置逻辑删除字段
KEY_DELETED_KEY = "del_flag";
KEY_DELETED_VALUE = "1";
KEY_NOT_DELETED_VALUE = "0";
// 设置默认数据库类型和模式
DEFAULT_DATABASE = DATABASE_MYSQL;
DEFAULT_SCHEMA = SystemProperties.Database.getDefaultSchema();
// 配置SQL配置回调
SIMPLE_CALLBACK = new SimpleCallback<String>() {
/**
* 获取SQL配置实例
*
* @param method 请求方法
* @param database 数据库名
* @param schema 模式名
* @param datasource 数据源名
* @param table 表名
* @return SQL配置实例
*/
@Override
public AbstractSQLConfig<String> getSQLConfig(RequestMethod method, String database, String schema, String datasource, String table) {
return new TunnelSqlConfig(method, table);
}
/**
* 获取用户ID字段名
*
* @param database 数据库名
* @param schema 模式名
* @param datasource 数据源名
* @param table 表名
* @return 用户ID字段名
*/
@Override
public String getUserIdKey(String database, String schema, String datasource, String table) {
return USER_.equals(table) || PRIVACY_.equals(table) ? ID : USER_ID;
}
};
Map<String, Map<String, String>> tableKeyColumnMap = new HashMap<>();
Map<String, String> ballastlessLedgerColumnMap = new HashMap<>();
ballastlessLedgerColumnMap.put("id", "id");
ballastlessLedgerColumnMap.put("lineName", "line_name");
ballastlessLedgerColumnMap.put("lineLevel", "line_level");
ballastlessLedgerColumnMap.put("bureauName", "bureau_name");
ballastlessLedgerColumnMap.put("divisionName", "division_name");
ballastlessLedgerColumnMap.put("sectionName", "section_name");
ballastlessLedgerColumnMap.put("direction", "direction");
ballastlessLedgerColumnMap.put("locationType", "location_type");
ballastlessLedgerColumnMap.put("locationName", "location_name");
ballastlessLedgerColumnMap.put("sectionNumber", "section_number");
ballastlessLedgerColumnMap.put("equipmentCode", "equipment_code");
ballastlessLedgerColumnMap.put("startMileage", "start_mileage");
ballastlessLedgerColumnMap.put("endMileage", "end_mileage");
ballastlessLedgerColumnMap.put("centerMileage", "center_mileage");
ballastlessLedgerColumnMap.put("overallLength", "overall_length");
ballastlessLedgerColumnMap.put("trackType", "track_type");
ballastlessLedgerColumnMap.put("componentType", "component_type");
ballastlessLedgerColumnMap.put("status", "status");
ballastlessLedgerColumnMap.put("delFlag", "del_flag");
ballastlessLedgerColumnMap.put("createBy", "create_by");
ballastlessLedgerColumnMap.put("createTime", "create_time");
ballastlessLedgerColumnMap.put("updateBy", "update_by");
ballastlessLedgerColumnMap.put("updateTime", "update_time");
tableKeyColumnMap.put("BallastlessLedger", ballastlessLedgerColumnMap);
ColumnUtil.VERSIONED_KEY_COLUMN_MAP.put(1, tableKeyColumnMap);
// 初始化列工具
ColumnUtil.init();
// 调试:检查初始化结果
System.out.println("映射配置初始化完成");
System.out.println("表映射: " + ColumnUtil.VERSIONED_KEY_COLUMN_MAP.get(1).keySet());
}
@Override
public AbstractSQLConfig<String> setColumn(List<String> column) {
System.out.println(ColumnUtil.VERSIONED_KEY_COLUMN_MAP);
List<String> list = ColumnUtil.compatInputColumn(column, getTable(), getMethod(), 1, false);
return super.setColumn(list);
}
@Override
public String getKey(String key) {
System.out.println(ColumnUtil.VERSIONED_KEY_COLUMN_MAP);
String inputKey = ColumnUtil.compatInputKey(key, getTable(), getMethod(),1,false);
String string = super.getKey(inputKey);
return string;
}
}
日志内容
查询条件
{ "BallastlessLedger[]": { "count": 20, "page": 0, "BallastlessLedger": { "delFlag": "0", "@order": "createTime-" }, "query": 2 }, "total@": "/BallastlessLedger[]/total" }
异常日志
Caused by: java.sql.SQLSyntaxErrorException: (conn=3221599286) Unknown column 'delFlag' in 'where clause'
If column exists but type cannot be identified (example 'select ? field1 from dual'). Use CAST function to solve this problem (example 'select CAST(? as integer) field1 from dual')
at com.oceanbase.jdbc.internal.util.exceptions.ExceptionFactory.createException(ExceptionFactory.java:110)
at com.oceanbase.jdbc.internal.util.exceptions.ExceptionFactory.create(ExceptionFactory.java:202)
at com.oceanbase.jdbc.OceanBaseStatement.executeExceptionEpilogue(OceanBaseStatement.java:331)
at com.oceanbase.jdbc.JDBC4PreparedStatement.executeInternal(JDBC4PreparedStatement.java:258)
at com.oceanbase.jdbc.JDBC4PreparedStatement.execute(JDBC4PreparedStatement.java:172)
at com.oceanbase.jdbc.JDBC4PreparedStatement.executeQuery(JDBC4PreparedStatement.java:186)
at apijson.orm.AbstractSQLExecutor.executeQuery(AbstractSQLExecutor.java:1386)
at apijson.orm.SQLExecutor.executeQuery(SQLExecutor.java:70)
@hany5725 应该是自定义的 TunnelSqlConfig 没注册导致字段配置没用上 https://github.com/Tencent/APIJSON/issues/363 https://github.com/Tencent/APIJSON/issues/812
@TommyLemon 有进行正常的初始化配置
启动类主方法:
这是我的APIJSONConfig配置:
public class ApiJsonConfig {
/**
* 初始化APIJSON配置
*/
public static void initApiJsonConfig() {
// 配置APIJSON创建器
configureApiJsonCreator();
// 配置Spring实例获取器
configureInstanceGetter();
// 配置JSON回调处理器
configureJsonCallback();
log.info("APIJSON配置初始化完成");
}
/**
* 配置APIJSON创建器
*/
private static void configureApiJsonCreator() {
APIJSONApplication.DEFAULT_APIJSON_CREATOR = new APIJSONCreator<String>() {
@Override
public Parser<String> createParser() {
return new TunnelParser();
}
@Override
public FunctionParser<Long> createFunctionParser() {
return new TunnelFunctionParser();
}
@Override
public Verifier<String> createVerifier() {
return new TunnelVerifier();
}
@Override
public SQLConfig<String> createSQLConfig() {
return new TunnelSqlConfig();
}
@Override
public SQLExecutor<String> createSQLExecutor() {
return new TunnelSqlExecutor();
}
};
}
断点调试 setColumn 和 getKey,发下截屏,包含对应变量的值
这是初始化的断点信息:
查询条件: { "BallastlessLedger[]": { "count": 20, "page": 0, "BallastlessLedger": { "delFlag": "0", "@order": "createTime-" }, "query": 2 }, "total@": "/BallastlessLedger[]/total" }
查询的调试信息:
错误日志:
表结构:
断点 getClosestValue ,看看为啥对 keyColumnMap 返回了 null
init方法时正常的,实际调用时候
项目初始化启动时
在查询时 这三个静态变量都为空了
@hany5725 应该是在某个地方把 VERSIONED_KEY_COLUMN_MAP 重置或键值对清空了导致。 把 VERSIONED_KEY_COLUMN_MAP 所有用到的代码都用 IDE 找出来, 尤其是 VERSIONED_KEY_COLUMN_MAP = , VERSIONED_KEY_COLUMN_MAP.clear , VERSIONED_KEY_COLUMN_MAP.put , VERSIONED_KEY_COLUMN_MAP.putAll 等能改变内部值的代码,都附带上下文发出来。
或者干脆去掉业务逻辑、数据库 URI 及账号密码 等敏感代码,只保留基础的能复现的 Demo 发出来源码 (压缩后应该可以粘贴到 issue 中,不行的话直接 GitHub 上新建一个 repo 来提交代码)
tunnel - 副本.zip这是出现问题的项目以及sql文件