领域未为反射对象的字段设置值 (Android)
Realm isn't set value to the fields of the objects on reflection (Android)
我正在尝试实现对领域的抽象,以便在对数据库使用 CURD 操作时可以节省一些时间。
我构建的抽象是 controller
到数据库操作,这样我就可以使用这个 controller
对任何 table.
执行 CURD 操作
即我说的 controller
只是一个 Java class
有四个方法
create
update
read
delete
.
这是 create
,它使用反射创建 db objects
并将传递的 data object
的字段绑定到那个 db object
/**
* 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();
}
}
问题如下:
当我尝试查询数据库以在处理完数据库后获取对象时,数据库 return 我使用此函数创建的对象,但这些对象没有数据 actually the returned data is set to default value to each type i.e. string to null boolean to false etc...
我的问题是:
我的代码有什么问题吗,或者领域数据库不支持在反射时为对象设置值?
Realm 不支持通过反射设置托管对象的字段值。
但是,如果您通过反射调用 setter 方法,它将起作用。
我正在尝试实现对领域的抽象,以便在对数据库使用 CURD 操作时可以节省一些时间。
我构建的抽象是 controller
到数据库操作,这样我就可以使用这个 controller
对任何 table.
即我说的 controller
只是一个 Java class
有四个方法
create
update
read
delete
.
这是 create
,它使用反射创建 db objects
并将传递的 data object
的字段绑定到那个 db object
/**
* 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();
}
}
问题如下:
当我尝试查询数据库以在处理完数据库后获取对象时,数据库 return 我使用此函数创建的对象,但这些对象没有数据 actually the returned data is set to default value to each type i.e. string to null boolean to false etc...
我的问题是:
我的代码有什么问题吗,或者领域数据库不支持在反射时为对象设置值?
Realm 不支持通过反射设置托管对象的字段值。
但是,如果您通过反射调用 setter 方法,它将起作用。