【问题标题】:Ormlite RawRowMapper chokes on long field with MySQLOrmlite RawRowMapper 在 MySQL 的长字段上窒息
【发布时间】:2016-05-30 16:08:32
【问题描述】:

我正在尝试在 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();
        }
}

它返回以下堆栈跟踪:

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)

【问题讨论】:

    标签: mysql ormlite


    【解决方案1】:

    我正在尝试在 MySQL 上使用 queryRaw 和 RawRowMapper。它适用于字符串列,但是如果我添加一个长字段,.mapRow() 会阻塞——它会尝试将列名转换为数字。

    getRawRowMapper() 已经有一段时间了,实际上并不是实验性的。我去换cmets。

    我不确定您期望发生什么,但 ORMLite 正在尝试将作为字符串的 EVENTID_FIELD 转换为 longmapRow(...) method 的定义是:

    T mapRow(String[] columnNames, String[] resultColumns) throws SQLException
    

    并且您正尝试将rowmap 作为resultColumns 传递。我假设第一个结果列应该很长,并且它正在尝试执行 Long.parseLong("event_id") 抛出。

    如果您提供有关您要完成的工作的更多详细信息,我可以看看是否可以提供帮助。

    【讨论】:

    • 感谢 Gray,“它不再是实验性的”加上“你想做什么”只是我需要的提示。基本上我只是不相信我的情况像我发现的例子那么简单,并试图让它变得复杂。发布了工作代码,但不值得阅读——RawRowMapper 的使用是完全标准的。
    【解决方案2】:

    这是一个工作示例。它是Logback DbAppender's logging_event table 的访问类,这是一种让 Slf4j 登录到数据库的非常好的方法。由于我需要通过伴随表 logging_event_property 中是否存在特定 MDC 行(它们就像日志事件的可选标签)来过滤 logging_event 行,因此 SQL 非常复杂。

    然而,RawRowMapper 的使用是完全标准的。问题是我缺乏理解力:

    1. 您不要自己打电话给mapRow()。它由queryRawas is explained perfectly well in the docs. 调用
    2. 您从dao.getRawRowMapper() 获得的映射器将正常工作,即使您不使用SELECT *。相信它,直到你有理由不这样做。

    无论如何,这里是工作访问类,以及我的时髦双连接过滤。可能对任何尝试在 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;
    }
    

    【讨论】:

      猜你喜欢
      • 2012-06-15
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 2010-11-22
      • 2011-02-11
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多