2012-08-16 9 views
7

私はJOINを必要とするクエリを実行する方法を探しています。準備された声明でこれを行う方法はありますか、または私が持っている唯一の選択肢はrawQueryです。 rawQueryが唯一のオプションである場合、返されたオブジェクトを実装されているDaoのオブジェクトに自動的にマッピングする方法があります。ORMLite JOIN、またはrawQuery自動マッピング

私は文書や例を挙げて掘ってきましたが、私はORMのオブジェクトクラスに、生のデータベースの結果をマッピングすることができます何かを見つけることができません。

+1

同じですダニエル。単純なJOIN問合せをサポートするORMLite 4.22がリリースされました。 – Gray

+0

以前はJOINクエリをサポートしていないORMLite 4.23がありました。あなたのコメントのリリース日とタイムスタンプを確認すると、単純なJOINクエリーをサポートする最初のバージョンはORMLite 4.26(9/26/12)です。私はちょうどJOINがある4.45に更新しました。 –

答えて

15

ORMLiteはsimple JOIN queriesをサポートしています。これを行うにはraw-queriesを使用することもできます。

あなたが見られるようなクエリをマッピングするためにDao.getRawRowMapper()を使用するか、カスタムマッパーを作成することができます。私は、カスタムのマッピングフィールドの問題を抱えていた生のクエリの自動マッピング

はない列を返すかを選択

GenericRawResults<Foo> rawResults = 
    orderDao.queryRaw(
    "select account_id,sum(amount) from orders group by account_id", 
    new RawRowMapper<Foo>() { 
      public Foo mapRow(String[] columnNames, 
       String[] resultColumns) { 
       return new Foo(Long.parseLong(resultColumns[0]), 
        Integer.parseInt(resultColumns[1])); 
     } 
    }); 
+0

ありがとう@Gray。私はすべてのカスタム行マッパを見つけましたが、すでに定義したオブジェクトに自動的にマップするようにしました。 QueryBuilder JOINオプションは私のウィッシュリスト上に次にあります!それがいつ来るかについての言葉? – DanO

+0

ormlite-devでスレッドを開始したいですか?私はそれを書く準備ができています。より困難になるのは、結合を使用してサブオブジェクトを水和することです。しかし、スレッドを開始し、私は返信します:https://groups.google.com/forum/?fromgroups#!forum/ormlite-dev – Gray

+1

スレッドを作成しました。 – DanO

8

私は、自動モデルオブジェクトに設定し、結果をマッピングする方法を見つけました。

// return the orders with the sum of their amounts per account 
GenericRawResults<Order> rawResults = 
    orderDao.queryRaw(query, orderDao.getRawRowMapper(), param1) 

// page through the results 
for (Order order : rawResults) { 
    System.out.println("Account-id " + order.accountId + " has " 
    + order.totalOrders + " total orders"); 
} 

rawResults.close(); 

キーはあなたのためのマッピングを処理するgetRawRowMapper()を使用して、オブジェクトDaoから行マッパーを引っ張っています。私はこれがそれを見つけた人に役立つことを願っています。私はまだやる能力が大好きだ

QueryBuilder以内に加入するが、それがサポートされるまで、これが私の意見では次善の策です。

0

:ドキュメントには、あなたのオブジェクトにString[]をマッピングする方法を示し、次のサンプルコードを持っていますどのテーブルモデルにも存在します。そこで私は、カスタムクエリからフィールドをカスタムモデルにマップできるカスタムRawRowMapperを作成しました。これは、テーブルマッピングモデルに対応しないフィールドを持つクエリがある場合に便利です。

これは、クエリの自動マッピングを行いRowMapperのです:

public class GenericRowMapper<T> implements RawRowMapper<T> { 

private Class<T> entityClass; 
private Set<Field> fields = new HashSet<>(); 
private Map<String, Field> colNameFieldMap = new HashMap<>(); 

public GenericRowMapper(Class<T> entityClass) { 
    this.dbType = dbType; 
    this.entityClass = entityClass; 
    Class cl = entityClass; 
    do { 
     for (Field field : cl.getDeclaredFields()) { 
      if (field.isAnnotationPresent(DatabaseField.class)) { 
       DatabaseField an = field.getAnnotation(DatabaseField.class); 
       fields.add(field); 
       colNameFieldMap.put(an.columnName(), field); 
      } 
     } 
     cl = cl.getSuperclass(); 
    } while (cl != Object.class); 
} 

@Override 
public T mapRow(String[] columnNames, String[] resultColumns) throws SQLException { 
    try { 
     T entity = entityClass.newInstance(); 
     for (int i = 0; i < columnNames.length; i++) { 
      Field f = colNameFieldMap.get(columnNames[i]); 
      boolean accessible = f.isAccessible(); 
      f.setAccessible(true); 
      f.set(entity, stringToJavaObject(f.getType(), resultColumns[i])); 
      f.setAccessible(accessible); 
     } 
     return entity; 
    } catch (InstantiationException e) { 
     throw new RuntimeException(e); 
    } catch (IllegalAccessException e) { 
     throw new RuntimeException(e); 
    } 
} 

public Object stringToJavaObject(Class cl, String result) { 
    if (result == null){ 
     return null; 
    }else if (cl == Integer.class || int.class == cl) { 
     return Integer.parseInt(result); 
    } else if (cl == Float.class || float.class == cl) { 
     return Float.parseFloat(result); 
    } else if (cl == Double.class || double.class == cl) { 
     return Double.parseDouble(result); 
    } else if (cl == Boolean.class || cl == boolean.class) { 
     try{ 
      return Integer.valueOf(result) > 0; 
     }catch (NumberFormatException e){ 
      return Boolean.parseBoolean(result); 
     } 
    } else if (cl == Date.class) { 
     DateLongType lType = DateLongType.getSingleton(); 
     DateStringType sType = DateStringType.getSingleton(); 
     try { 
      return lType.resultStringToJava(null, result, -1); 
     } catch (NumberFormatException e) { 
      try { 
       return sType.resultStringToJava(null, result, -1); 
      } catch (SQLException e2) { 
       throw new RuntimeException(e); 
      } 
     } 
    } else { 
     return result; 
    } 
} 
} 

そしてここでは、使い方です:

class Model{ 
    @DatabaseField(columnName = "account_id") 
    String accId; 
    @DatabaseField(columnName = "amount") 
    int amount; 
} 

String sql = "select account_id,sum(amount) amount from orders group by account_id" 
return queryRaw(sql,new GenericRowMapper<>(Model.class)).getResults() 

これがあれば、クエリの列をモデル化するためにマッピングされた結果行でList<Model>を返します。名前と@DatabaseField(columnNameはFYI

関連する問題