ActiveObjects
昨日のtwitterの内容を
http://d.hatena.ne.jp/yuripop/20080927/p1
で紹介いただいて感動したので、以下を三つについて、コードからわかったことを整理しました。
- EntityManager.get(Class
, K ) 行エンティティを取得する。(キャッシュ管理と生成も行う) - EntityManager.find(Class
, String, Query) 行を選択とデータのキャッシュ - EntityManager.findWithSQL SQLを指定して行エンティティを取得する。
EntityManager.get(Class
... // エンティティキャッシュから行エンティティを取得する。 Reference reference = entityCache.get(new CacheKey(key, type)); Reference ref = (Reference ) reference; T entity = (ref == null ? null : ref.get()); // エンティティが取得できたことを確認する: if (entity != null) { // エンティティキャッシュから取得したエンティティを戻り値とする。 back[index++] = entity; } else { // 取得できない: // エンティティをインスタンス化する。(エンティティキャッシュにも追加。) back[index++] = getAndInstantiate(type, key); } ...
EntityManager.find(Class
... // クエリからSQLを作成する。 sql = query.toSQL(type, provider, tableNameConverter, getFieldNameConverter(), false);^ ... // SQLを実行し、結果セットを取得する。 ResultSet res = stmt.executeQuery();^M // 結果セットのメタデータを取得する。 ResultSetMetaData md = res.getMetaData();^M provider.setQueryResultSetProperties(res, query); // 選択行ごとに、以下を繰り返す。 while (res.next()) { // 行の主キーの値から、エンティティを取得する。 T entity = get(type, Common.getPrimaryKeyType(type).pullFromDatabase(this, res, Common.getPrimaryKeyClassType(type), field)); // エンティティーをキーに、データ用キャッシュを取得する。 CacheLayer cacheLayer = getCache().getCacheLayer(entity); // 結果セットのすべての行のデータを、データ用のキャッシュに追加する。 for (int i = 0; i < md.getColumnCount(); i++) { cacheLayer.put(md.getColumnLabel(i + 1), res.getObject(i + 1)); } back.add(entity); }
EntityManager.findWithSQL SQLを指定して行エンティティを取得する。
... // SQLを実行し、結果セットを取得する。 ResultSet res = stmt.executeQuery(); // 結果セットのすべての行について繰り返す。 while (res.next()) { // 行の主キーの値から、エンティティを取得する。 back.add(get(type, Common.getPrimaryKeyType(type).pullFromDatabase(this, res, (Class) type, keyField))); } ...
[おまけ]Preloadアノテーション
EntityManager.find(Class
... // Preloadアノテーションが設定されていることを確認する。 Preload preloadAnnotation = type.getAnnotation(Preload.class); if (preloadAnnotation != null) { // 以下を確認する。 // ・*指定でない。 // ・joinでない。 if (!query.getFields()[0].equals("*") && query.getJoins().isEmpty()) { // クエリに新たな選択項目を設定する。 String[] oldFields = query.getFields(); ListnewFields = new ArrayList (); // Preloadアノテーションに指定された選択項目を、新たな選択項目とする。 for (String newField : preloadAnnotation.value()) { newField = newField.trim(); int fieldLoc = -1; for (int i = 0; i < oldFields.length; i++) { if (oldFields[i].equals(newField)) { fieldLoc = i; break; } } if (fieldLoc < 0) { newFields.add(newField); } else { newFields.add(oldFields[fieldLoc]); } } // Preloadアノテーションが"*"が指定された場合、クエリに従来含まれていた選択項目も、新たな選択項目に追加する。 if (!newFields.contains("*")) { for (String oldField : oldFields) { if (!newFields.contains(oldField)) { newFields.add(oldField); } } } query.setFields(newFields.toArray(new String[newFields.size()])); } } ...