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 转换为 longmapRow(...) 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 的使用是完全标准的。问题是我缺乏理解:

  1. 你不给自己打电话 mapRow()。它由 queryRawas is explained perfectly well in the docs.
  2. 调用
  3. 您从 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;
}