我正在尝试实现对 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/