レルムの "カスケード削除"操作に関する検索を行いました。残念ながらその機能はまだ実装されていません。私は自分でそれを実装してここで共有しました。レルムの "カスケード削除"
レルム「カスケード削除」操作の汎用コードの作成方法は?
レルムの "カスケード削除"操作に関する検索を行いました。残念ながらその機能はまだ実装されていません。私は自分でそれを実装してここで共有しました。レルムの "カスケード削除"
レルム「カスケード削除」操作の汎用コードの作成方法は?
1)プロジェクト
import android.util.Log;
import java.lang.reflect.Method;
import io.realm.RealmList;
import io.realm.RealmObject;
import com.company.project.models.IRealmCascade;
/**
*/
public class RealmUtils
{
public static void deleteCascade(RealmObject dataObject)
{
if (dataObject == null)
{
return;
}
if(IRealmCascade.class.isAssignableFrom(dataObject.getClass()))
{
for(Method method : dataObject.getClass().getSuperclass().getDeclaredMethods())
{
try {
//Ignore generated methods
if((method.getName().contains("realmGet$")) || (method.getName().contains("access$super")))
{
continue;
}
Class<?> resultType = method.getReturnType();
//Ignore non object members
if (resultType.isPrimitive()) {
continue;
}
if (RealmObject.class.isAssignableFrom(resultType)) {
//Delete Realm object
try {
RealmObject childObject = (RealmObject) method.invoke(dataObject);
RealmUtils.deleteCascade(childObject);
} catch (Exception ex) {
Log.e("REALM", "CASCADE DELETE OBJECT: " + ex.toString());
}
} else if (RealmList.class.isAssignableFrom(resultType)) {
//Delete RealmList items
try {
RealmList childList = (RealmList) method.invoke(dataObject);
while(childList.iterator().hasNext())
{
RealmObject listItem = (RealmObject)childList.iterator().next();
RealmUtils.deleteCascade(listItem);
}
} catch (Exception ex) {
Log.e("REALM", "CASCADE DELETE LIST: " + ex.toString());
}
}
}
catch (Exception ex)
{
Log.e("REALM", "CASCADE DELETE ITERATION: " + ex.toString());
}
}
}
dataObject.deleteFromRealm();
}
}
2)プロジェクトにインターフェイスを追加するには、このコードをコピーしてください。 Realmオブジェクトがこのインタフェースを実装している場合、deleteCascadeの呼び出し後にすべての子オブジェクトが削除されます。インタフェースが実装されていない場合、この関数はRealmオブジェクトを削除しますが、子オブジェクトは削除しません。
public interface IRealmCascade {
}
3)Realmオブジェクトを宣言します。以下の例。
4)RealmUtils.deleteCascade(realmObject)を呼び出す必要があります。代わりにrealmObject.removeFromRealm();ローカルデータベースに 更新データ
for(NodeModel nodeItem: incomingData.getNodesList())
{
RealmResults<NodeModel> results = bgRealm.where(NodeModel.class).equalTo("objId", nodeItem.getObjId()).findAll();
if (results.size() > 0)
{
RealmUtils.deleteCascade(results.first());
}
bgRealm.copyToRealm(nodeItem);
}
以下 の例は、あなたのきれいなDBをお楽しみください! :)
私はこの実装にバリエーションがあり、他の人が役に立つと思うかもしれません。
元の実装では、トラバース可能なRealmObjectサブクラス「implement IRealmCascade」。インタフェースを実装していないRealmObjectsは、リーフノードとして扱われます(オブジェクトは削除されますが、その子は削除されません)。
私の実装では:どのRealmObject/RealmListもトラバース可能です(インターフェイスを実装する必要はありません)。クラスに、走査されないメンバーがある場合、そのメンバーのゲッターには "@SkipDelete"という注釈が付けられます。
/**
* Traverse the tree of RealmObjects, deleting the RealmObject/RealmList children
* and the root RealmObject.
* <br><br>
* This method uses reflection to get the rootObject's "getter" methods. The
* getter methods are called to get the RealmObject/RealmList children, and
* those objects are deleted from the Realm.
* <br><br>
* If any of the getter methods return a RealmObject/RealmList that should NOT be
* deleted, those getter methods should be annotated with {@link SkipDelete}.
*
* @param rootObject The root of the RealmObject tree
*/
public static void delete(RealmObject rootObject) {
if (rootObject == null) {
return;
}
for (Method method : rootObject.getClass().getSuperclass().getDeclaredMethods()) {
try {
// Ignore non-getter methods
boolean noParams = method.getParameterTypes().length == 0;
if (!(method.getName().startsWith("get")) || !noParams) {
continue;
}
// Ignore primitive members
Class<?> resultType = method.getReturnType();
if (resultType.isPrimitive()) {
continue;
}
// Ignore methods annotated with SkipDelete
if (method.isAnnotationPresent(SkipDelete.class)) {
continue;
}
if (RealmObject.class.isAssignableFrom(resultType)) {
// getter method returns a RealmObject, delete it
try {
RealmObject childObject = (RealmObject) method.invoke(rootObject);
delete(childObject, true);
} catch (Exception ex) {
Log.e("delete: RealmObject " + resultType.getSimpleName(), ex);
}
} else if (RealmList.class.isAssignableFrom(resultType)) {
// getter method returns a RealmList, delete the objects in the list
try {
RealmList childList = (RealmList) method.invoke(rootObject);
while (childList.iterator().hasNext()) {
RealmObject listItem = (RealmObject)childList.iterator().next();
delete(listItem, true);
}
} catch (Exception ex) {
Log.e("delete: RealmList " + resultType.getSimpleName(), ex);
}
}
}
catch (Exception ex) {
Log.e("delete: ", ex);
}
}
rootObject.deleteFromRealm();
}
/**
* This annotation is used to mark a "getter" method that should be skipped
* over on the cascading delete traversal of the RealmObject/RealmList tree.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SkipDelete {
}
あなたRealmObjectで
public class Design extends RealmObject {
private MyRealmObject1 obj1; // do CascadeDelete on this member
private MyRealmObject2 obj2; // don't do CascadeDelete on this member
....
public MyRealmObject1 getObj1() {
return obj1;
}
@CascadeDelete.SkipDelete // don't do CascadeDelete of obj2
public MyRealmObject2 getObj2() {
return obj2;
}
}
スタックオーバーフローは、プログラミングの質問です。あなたの質問は何ですか? – CommonsWare
私はそれを終了させてください...私はそれを公開しています。 –