java - Realm 没有为反射对象的字段设置值(Android)

标签 java android reflection realm abstraction

我正在尝试实现对 Realm 的抽象,以便在对数据库使用 CURD 操作时可以节省一些时间。

我构建的抽象是数据库操作的 controller,这样我就可以使用这个 controller 对任何表执行 CURD 操作。

即我所说的 controller 只是一个 Java class 有四个方法 创建 更新 读取 删除

这是 create,它使用反射创建 db 对象 并将传递的 data object 的字段绑定(bind)到 数据库对象

 /**
     * this method will delete the old data "you can change that"
     * of the table then store the passed data array in the table
     *
     * @param datum    the data Object you want to
     *                 save in the database
     * @param map      this map will contain which field
     *                 value in the data class will be
     *                 binded to which field in the db class
     *                 and will have this form dataFieldName => dbFieldName
     * @param callback when the function finish it's work it will
     *                 return a boolean value indicate whether
     *                 the function successfully finish it's work
     */
    public void create(
            Object datum,
            Class dataClass,
            HashMap<String, String> map,
            SaveDataCallback callback
    ) {
        Realm realm = Realm.getInstance(configuration);
        realm.executeTransactionAsync(bgRealm -> {
                    long id;

                    Number currentId = bgRealm.where(clacc).max("id");//the clacc object is passed in the constructor of the controller  
                    if (currentId == null)
                        id = 1;
                    else
                        id = currentId.longValue() + 1;

                    RealmObject dbObject = bgRealm.createObject(clacc, id++);//the clacc object is passed in the constructor of the controller 
                    mapObjects(datum, dataClass, dbObject, clacc, map);



                }
                , () -> callback.onSavingDataFinished(true)
                , error -> callback.onSavingDataFinished(false));
    }


private void mapObjects(
            Object source,
            Class sourceClass,
            Object destination,
            Class destinationClass,
            HashMap<String, String> map) {
        String[] sourceFieldNames = map.keySet().toArray(new String[map.size()]);

        try {

            for (int i = 0; i < map.size(); i++) {
                Field sourceField = sourceClass.getDeclaredField(sourceFieldNames[i]);
                sourceField.setAccessible(true);
                Object sourceValue = sourceField.get(source);

                String destinationFieldName = map.get(sourceFieldNames[i]);
                Field destinationField = destinationClass.getDeclaredField(destinationFieldName);
                destinationField.setAccessible(true);

                if (sourceField.getType() == Short.TYPE) {
                    destinationField.set(destination, Short.parseShort(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Integer.TYPE) {
                    destinationField.set(destination, Integer.parseInt(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Long.TYPE) {
                    destinationField.set(destination, Long.parseLong(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Float.TYPE) {
                    destinationField.set(destination, Float.parseFloat(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Double.TYPE) {
                    destinationField.set(destination, Double.parseDouble(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Byte.TYPE) {
                    destinationField.set(destination, Byte.parseByte(sourceValue.toString()));
                    continue;
                }
                if (sourceField.getType() == Boolean.TYPE) {
                    destinationField.set(destination, Boolean.parseBoolean(sourceValue.toString()));
                    continue;
                }
                destinationField.set(destination, sourceValue);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

问题如下:

当我尝试查询数据库以在过程完成后获取对象时,数据库返回我使用此函数创建的对象,但这些对象没有数据实际上返回的数据设置为默认值每种类型的值,即字符串到 null boolean 值到 false 等......

我的问题是:

是我的代码有什么问题,还是 realm 数据库不支持在反射时为对象设置值?

最佳答案

Realm 不支持通过反射设置托管对象的字段值。

但是,如果您通过反射调用 setter 方法,它将起作用。

关于java - Realm 没有为反射对象的字段设置值(Android),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52567877/

相关文章:

MySQL 存储过程 - 将 SELECT 作为参数传递

java - 启动 Spring 应用程序时出错 : Initialization of bean failed; nested exception is AbstractMethodError

java - 如何使用 Java 反射来调用引用变量上的方法?

java - 查找 PI 具有特定值的术语

Android 仪器测试和库项目

android - Facebook 深层链接打开 Google Play 而不是应用程序(即使已安装)

android - 关于辞职apk的建议

java - 使用类名调用不同类的方法

java - Java 库类的源代码

java - 类在什么情况下实现接口(interface)?