2016-05-30 26 views
0

我試圖在MySQL上使用與RawRowMapper的queryRaw。它可以很好地處理字符串列,但是.mapRow()會在我添加一個長字段時扼殺它 - 它會嘗試將列名轉換爲數字。Ormlite RawRowMapper與MySQL的長字段扼流圈

doc for getRawRowMapper表示它是實驗性的,並提供反饋,但我只是一個蛋,所以如果其他人已經成功配置這個配置,我會更努力地嘗試之前,灰色的。

我的代碼如下:

@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) 

回答

0

下面是工作示例。它是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; 
} 
1

我試圖使用queryRaw與MySQL的一個RawRowMapper。它可以很好地處理字符串列,但是.mapRow()會在我添加一個長字段時扼殺它 - 它會嘗試將列名轉換爲數字。

getRawRowMapper()已經有一段時間了,實際上並不是實驗性的。我會改變評論。

我不確定你期待發生什麼,但ORMLite試圖將EVENTID_FIELD這是一個字符串轉換爲long。該mapRow(...) method定義是:

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

,你正試圖在rowmapresultColumns通過。我假設第一個結果列應該是一個很長的時間,並且它正在嘗試執行拋出的 Long.parseLong("event_id")

如果您提供了關於您要完成的更多細節,我可以看看我能否提供幫助。

+0

謝謝格雷,「這不再是實驗」,加上「你想做什麼」只是我需要的提示。基本上我只是不相信我的情況和我發現的例子一樣簡單,並且希望使它變得複雜。發佈了工作代碼,但不值得閱讀 - 使用RawRowMapper是完全標準的。 –