データ更新を行うユーティリティ
検索条件作成ユーティリティ向けに定義したプロパティを再利用して、データの更新を行うユーティリティも作ってみました。専用のユーティリティとペアで使うことで、
↓のような感じで指定したモデルの属性を更新(以下の例では、年齢を"2"に更新)できるようにするものです。
// 更新対象のモデル Kitten mii = null; // 略 //mii の age プロパティを2に更新 set( KittenProperties.AGE, 2 ).update( mii );
Google App Engineでは、取り出したモデルの属性を再設定すれば、データストアで記録された値も更新されるので、
public void update(Class<X> clazz, Key key, Values<? super X> values) throws UpdateFailedException { X object = (X) Tx.getPersistenceManager().getObjectById(clazz, key); values.update(object); }
のような感じでデータ更新APIが作れます。
登場人物
実装
Values
/** * 更新データ * * @param <X> モデルの型 */ public interface Values<X> { /** * モデルのデータを更新する * @param item モデル * @return 更新後のモデル * @throws UpdateFailedException 更新時に何らかのエラーが発生した場合 */ X update( X item ) throws UpdateFailedException; /** * 更新データを追加する。 * @param <V> 値の型 * @param property プロパティ * @param value 更新後の値 * @return 自身 */ <V> Values<X> set( Property<X,V> property, V value ); }
ValuesImpl
import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; /** * {@link Values}の実装。 * * @param <X> モデルの型 */ public class ValuesImpl<X> implements Values<X> { /** * 更新データセット */ Map<Property<X, ?>, Object> values = new HashMap<Property<X, ?>, Object>(); @Override public <V> Values<X> set(Property<X, V> property, V value) { values.put(property, value); return this; } @Override public X update(X item) throws UpdateFailedException { for ( Map.Entry<Property<X, ?>, Object> e : values.entrySet() ) { try { PropertyDescriptor pd = new PropertyDescriptor( e.getKey().getName(), item.getClass() ); pd.getWriteMethod().invoke(item, e.getValue()); } catch (SecurityException ex) { throw new UpdateFailedException(ex); } catch (IllegalArgumentException ex) { throw new UpdateFailedException(ex); } catch (IllegalAccessException ex) { throw new UpdateFailedException(ex); } catch (InvocationTargetException ex) { throw new UpdateFailedException(ex); } catch (IntrospectionException ex) { throw new UpdateFailedException(ex); } } return item; } }
setメソッド
/** * 更新データを作成する。 * @param <X> モデルの型 * @param <V> 値の型 * @param property 更新するプロパティ * @param value 更新後の値 * @return 更新データ */ public static <X, V> Values<X> set( Property<X, V> property, V value ) { return new ValuesImpl<X>().set(property, value); }