Ormlite RawRowMapper 在 MySQL 的长字段上阻塞
Ormlite RawRowMapper chokes on long field with MySQL
我正尝试在 MySQL 上将 queryRaw 与 RawRowMapper 结合使用。它适用于字符串列,但是如果我添加一个长字段,.mapRow() 会阻塞——它会尝试将列名转换为数字。
doc for getRawRowMapper说它是实验性的并提供反馈,但我只是一个鸡蛋,所以如果其他人成功使用此配置,我会更加努力,然后用它来窃听 Gray。
我的代码如下:
@DatabaseField(dataType=DataType.LONG_STRING)
@Getter @Setter
private String formatted_message;
@DatabaseField(id=true)
@Getter @Setter
private long event_id;
public void getRowMapper() {
RawRowMapper<DbLog> rowMapper = daol.getRawRowMapper();
final String[] rowmap = { DbLog.EVENTID_FIELD, DbLog.MESSAGE_FIELD, DbLog.LEVEL_FIELD }; //
try {
rowMapper.mapRow( rowmap, rowmap );
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
它 returns 以下堆栈跟踪:
java.lang.NumberFormatException: For input string: "event_id"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:441)
at java.lang.Long.parseLong(Long.java:483)
at com.j256.ormlite.field.types.LongObjectType.parseDefaultString(LongObjectType.java:32)
at com.j256.ormlite.field.types.BaseDataType.resultStringToJava(BaseDataType.java:161)
at com.j256.ormlite.field.FieldType.convertStringToJavaField(FieldType.java:671)
at com.j256.ormlite.stmt.RawRowMapperImpl.mapRow(RawRowMapperImpl.java:33)
I'm trying to use queryRaw with a RawRowMapper on MySQL. It works great with string columns, but .mapRow() chokes on if I add a long field -- it attempts to convert the column name to numeric.
getRawRowMapper()
已经有一段时间了,真的不是实验性的。我会改评论的。
我不确定您希望发生什么,但 ORMLite 正在尝试将字符串 EVENTID_FIELD
转换为 long
。 mapRow(...)
method 定义为:
T mapRow(String[] columnNames, String[] resultColumns) throws SQLException
并且您正试图将 rowmap
作为 resultColumns
传递。我假设第一个结果列应该很长并且它正在尝试做一个
Long.parseLong("event_id")
抛出。
如果您提供有关您要完成的目标的更多详细信息,我会看看是否可以提供帮助。
这是工作示例。它是 Logback DbAppender's logging_event
table 的访问 class,这是使 Slf4j 登录到数据库的非常漂亮的方法。 SQL 由于我需要根据同伴 table [= 中是否存在特定 MDC 行(它们就像日志事件的可选标签)来过滤 logging_event 行而变得非常复杂12=].
但是,RawRowMapper 的使用是完全标准的。问题是我缺乏理解:
- 你不给自己打电话
mapRow()
。它由 queryRaw
、as is explained perfectly well in the docs. 调用
- 您从
dao.getRawRowMapper()
获得的映射器将正常工作,即使您没有执行 SELECT *
。相信它,直到你有理由不相信它。
无论如何,这是工作访问 classes,以及我时髦的双连接过滤。可能对尝试在 Ormlite 项目中使用 DbAppender 的任何人有用。
@DatabaseTable(tableName = "logging_event")
public class DbLog {
public static String EVENTID_FIELD = "event_id";
public static String TIMESTAMP_FIELD = "timestmp";
public static String MESSAGE_FIELD = "formatted_message";
public static String LEVEL_FIELD = "level_string";
@DatabaseField
@Getter @Setter
private long timestmp;
@DatabaseField(dataType=DataType.LONG_STRING)
@Getter @Setter
private String formatted_message;
@DatabaseField
@Getter @Setter
private String logger_name;
@DatabaseField
@Getter @Setter
private String level_string;
@DatabaseField
@Getter @Setter
private String thread_name;
@DatabaseField
@Getter @Setter
private byte reference_flag;
@DatabaseField
@Getter @Setter
private String arg0;
@DatabaseField
@Getter @Setter
private String arg1;
@DatabaseField
@Getter @Setter
private String arg2;
@DatabaseField
@Getter @Setter
private String arg3;
@DatabaseField
@Getter @Setter
private String caller_filename;
@DatabaseField
@Getter @Setter
private String caller_class;
@DatabaseField
@Getter @Setter
private String caller_method;
@DatabaseField
@Getter @Setter
private String caller_line;
@DatabaseField(id=true)
@Getter @Setter
private long event_id;
/** Gets server logs since timestamp.
* Filters out logs which have NO MDC called "Client".
* @param daol - Dao for DbLog.
* @param timestamp - get only logs after this.
* @param eventId - if not zero, filters out logs matching this event.
* @return
*/
public static GenericRawResults<DbLog> getServerLogsSince(Dao<DbLog, Long> daol, long timestamp, int eventId ) {
try {
// NB: This is not tested on SQLite.
String mySqlQuery = "SELECT ";
mySqlQuery += "a.event_id, a.formatted_message, a.level_string ";
mySqlQuery += "FROM logging_event a ";
mySqlQuery += "LEFT JOIN logging_event_property b ";
mySqlQuery += "ON ( a.event_id = b.event_id ";
mySqlQuery += " and b.mapped_key = 'Event' ";
if( eventId != 0) {
mySqlQuery += " and b.mapped_value = ? ";
}
mySqlQuery += ") ";
mySqlQuery += "LEFT JOIN logging_event_property c ";
mySqlQuery += "ON ( a.event_id = c.event_id AND c.mapped_key = 'Client') ";
mySqlQuery += "WHERE a.timestmp > ? ";
mySqlQuery += "and c.event_id is null ";
RawRowMapper<DbLog> rowMapper = daol.getRawRowMapper();
String evStr = Long.toString(db.getEvent().getId());
String timeStr = Long.toString(timestamp);
GenericRawResults<DbLog> results;
if( eventId == 0)
results = daol.queryRaw(mySqlQuery, rowMapper, timeStr);
else
results = daol.queryRaw(mySqlQuery, rowMapper, evStr, timeStr);
return results;
} catch (SQLException e) {
log.error("Exception {}",Helpers.stackTraceInfo(e,DbLog.class));
}
return null;
}
}
@DatabaseTable(tableName = "logging_event_property")
public class DbLogProp {
public static String EVENTID_FIELD = "event_id";
public static String MAPPEDKEY_FIELD = "mapped_key";
public static String MAPPEDVALUE_FIELD = "mapped_value";
@DatabaseField(columnName="event_id", foreign=true)
@Getter @Setter
//private Long event_id;
DbLog event;
@DatabaseField(columnName="mapped_key")
@Getter @Setter
private String mappedKey;
@DatabaseField(columnName="mapped_value")
@Getter @Setter
private String mappedValue;
}
我正尝试在 MySQL 上将 queryRaw 与 RawRowMapper 结合使用。它适用于字符串列,但是如果我添加一个长字段,.mapRow() 会阻塞——它会尝试将列名转换为数字。
doc for getRawRowMapper说它是实验性的并提供反馈,但我只是一个鸡蛋,所以如果其他人成功使用此配置,我会更加努力,然后用它来窃听 Gray。
我的代码如下:
@DatabaseField(dataType=DataType.LONG_STRING)
@Getter @Setter
private String formatted_message;
@DatabaseField(id=true)
@Getter @Setter
private long event_id;
public void getRowMapper() {
RawRowMapper<DbLog> rowMapper = daol.getRawRowMapper();
final String[] rowmap = { DbLog.EVENTID_FIELD, DbLog.MESSAGE_FIELD, DbLog.LEVEL_FIELD }; //
try {
rowMapper.mapRow( rowmap, rowmap );
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
它 returns 以下堆栈跟踪:
java.lang.NumberFormatException: For input string: "event_id"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:441)
at java.lang.Long.parseLong(Long.java:483)
at com.j256.ormlite.field.types.LongObjectType.parseDefaultString(LongObjectType.java:32)
at com.j256.ormlite.field.types.BaseDataType.resultStringToJava(BaseDataType.java:161)
at com.j256.ormlite.field.FieldType.convertStringToJavaField(FieldType.java:671)
at com.j256.ormlite.stmt.RawRowMapperImpl.mapRow(RawRowMapperImpl.java:33)
I'm trying to use queryRaw with a RawRowMapper on MySQL. It works great with string columns, but .mapRow() chokes on if I add a long field -- it attempts to convert the column name to numeric.
getRawRowMapper()
已经有一段时间了,真的不是实验性的。我会改评论的。
我不确定您希望发生什么,但 ORMLite 正在尝试将字符串 EVENTID_FIELD
转换为 long
。 mapRow(...)
method 定义为:
T mapRow(String[] columnNames, String[] resultColumns) throws SQLException
并且您正试图将 rowmap
作为 resultColumns
传递。我假设第一个结果列应该很长并且它正在尝试做一个
Long.parseLong("event_id")
抛出。
如果您提供有关您要完成的目标的更多详细信息,我会看看是否可以提供帮助。
这是工作示例。它是 Logback DbAppender's logging_event
table 的访问 class,这是使 Slf4j 登录到数据库的非常漂亮的方法。 SQL 由于我需要根据同伴 table [= 中是否存在特定 MDC 行(它们就像日志事件的可选标签)来过滤 logging_event 行而变得非常复杂12=].
但是,RawRowMapper 的使用是完全标准的。问题是我缺乏理解:
- 你不给自己打电话
mapRow()
。它由queryRaw
、as is explained perfectly well in the docs. 调用
- 您从
dao.getRawRowMapper()
获得的映射器将正常工作,即使您没有执行SELECT *
。相信它,直到你有理由不相信它。
无论如何,这是工作访问 classes,以及我时髦的双连接过滤。可能对尝试在 Ormlite 项目中使用 DbAppender 的任何人有用。
@DatabaseTable(tableName = "logging_event")
public class DbLog {
public static String EVENTID_FIELD = "event_id";
public static String TIMESTAMP_FIELD = "timestmp";
public static String MESSAGE_FIELD = "formatted_message";
public static String LEVEL_FIELD = "level_string";
@DatabaseField
@Getter @Setter
private long timestmp;
@DatabaseField(dataType=DataType.LONG_STRING)
@Getter @Setter
private String formatted_message;
@DatabaseField
@Getter @Setter
private String logger_name;
@DatabaseField
@Getter @Setter
private String level_string;
@DatabaseField
@Getter @Setter
private String thread_name;
@DatabaseField
@Getter @Setter
private byte reference_flag;
@DatabaseField
@Getter @Setter
private String arg0;
@DatabaseField
@Getter @Setter
private String arg1;
@DatabaseField
@Getter @Setter
private String arg2;
@DatabaseField
@Getter @Setter
private String arg3;
@DatabaseField
@Getter @Setter
private String caller_filename;
@DatabaseField
@Getter @Setter
private String caller_class;
@DatabaseField
@Getter @Setter
private String caller_method;
@DatabaseField
@Getter @Setter
private String caller_line;
@DatabaseField(id=true)
@Getter @Setter
private long event_id;
/** Gets server logs since timestamp.
* Filters out logs which have NO MDC called "Client".
* @param daol - Dao for DbLog.
* @param timestamp - get only logs after this.
* @param eventId - if not zero, filters out logs matching this event.
* @return
*/
public static GenericRawResults<DbLog> getServerLogsSince(Dao<DbLog, Long> daol, long timestamp, int eventId ) {
try {
// NB: This is not tested on SQLite.
String mySqlQuery = "SELECT ";
mySqlQuery += "a.event_id, a.formatted_message, a.level_string ";
mySqlQuery += "FROM logging_event a ";
mySqlQuery += "LEFT JOIN logging_event_property b ";
mySqlQuery += "ON ( a.event_id = b.event_id ";
mySqlQuery += " and b.mapped_key = 'Event' ";
if( eventId != 0) {
mySqlQuery += " and b.mapped_value = ? ";
}
mySqlQuery += ") ";
mySqlQuery += "LEFT JOIN logging_event_property c ";
mySqlQuery += "ON ( a.event_id = c.event_id AND c.mapped_key = 'Client') ";
mySqlQuery += "WHERE a.timestmp > ? ";
mySqlQuery += "and c.event_id is null ";
RawRowMapper<DbLog> rowMapper = daol.getRawRowMapper();
String evStr = Long.toString(db.getEvent().getId());
String timeStr = Long.toString(timestamp);
GenericRawResults<DbLog> results;
if( eventId == 0)
results = daol.queryRaw(mySqlQuery, rowMapper, timeStr);
else
results = daol.queryRaw(mySqlQuery, rowMapper, evStr, timeStr);
return results;
} catch (SQLException e) {
log.error("Exception {}",Helpers.stackTraceInfo(e,DbLog.class));
}
return null;
}
}
@DatabaseTable(tableName = "logging_event_property")
public class DbLogProp {
public static String EVENTID_FIELD = "event_id";
public static String MAPPEDKEY_FIELD = "mapped_key";
public static String MAPPEDVALUE_FIELD = "mapped_value";
@DatabaseField(columnName="event_id", foreign=true)
@Getter @Setter
//private Long event_id;
DbLog event;
@DatabaseField(columnName="mapped_key")
@Getter @Setter
private String mappedKey;
@DatabaseField(columnName="mapped_value")
@Getter @Setter
private String mappedValue;
}