你好吗?我正在尝试执行一些动态方法调用以在Java(Android)中的各种对象上获取sql字符串,但是我仍然遇到一些有关性能和稳定性的问题。
上下文示例::存储库类onCreate方法获取所有实体对象(表)并调用方法(例如getCreateTable)以获取要执行的sql字符串。
当然,我可以通过对每个方法进行类校准来显式调用类,但是我还有其他调用,例如“ dropTables”,“ truncateTables”等,而且我不想一直重复相同的结构。
public void CreateTables() {
execute(Entity1.getCreateTable());
execute(Entity2.getCreateTable());
execute(Entity3.getCreateTable());
[..]
execute(Entity50.getCreateTable());
}
public void DropTables() {
execute(Entity1.getDropTable());
execute(Entity2.getDropTable());
execute(Entity3.getDropTable());
[..]
execute(Entity50.getDropTable());
}
直到现在我知道我可以通过3种不同的方式做到这一点。
1)使用反射(当前正在使用):基本上,我将所有对象类存储在列表中,然后使用反射调用所需的静态方法。但是我知道反射不是永远应该是第一选择。
private final List<Class> entityList = new ArrayList<Class>() {
{
add(Entity1.class);
add(Entity2.class);
add(Entity3.class);
}
};
public void createTables() {
/* get all query strings */
List<String> queryList = getQueryList("createTable");
try {
for (String query : queryList) {
execute(query);
}
} catch (SQLException e) {
[...]
}
}
private List<String> getQueryList(String methodName) {
List<String> queryList = new ArrayList<>();
for (Class<?> objectClass : entityList) {
try {
Method[] ms = objectClass.getMethods();
for (Method me : ms) {
if (me.getName().equals(methodName)) {
String query = (String) me.invoke(null);
if (query != null && query.length() > 0) {
queryList.add((String) me.invoke(null));
}
break;
}
}
} catch (Exception e) {
[...]
}
}
return queryList;
}
2)将对象实例存储在列表中:我可以创建一个包含实例对象的列表,然后将其强制转换为抽象父类(或接口),并调用方法以获取sql字符串。在这种情况下,我不知道在内存中保留实例对象列表是否是一个好习惯,也许这比根据列表大小使用反射更糟糕。
private final List<BaseEntity> entityList = new ArrayList<BaseEntity>() {
{
add(new Entity1(context));
add(new Entity2(context));
add(new Entity3(context));
}
};
public void createTables() {
for (BaseEntity entity : entityList) {
try {
execute(entity.getCreateTable());
} catch (Exception e) {
[...]
}
}
}
3)将所有字符串存储到JSON对象中:我尚未测试过该字符串,但是我敢肯定它可以使用。我可以调用“ init”方法来遍历所有对象,并使用所有sql字符串(删除,创建,截断等)创建JSON对象/数组。
非常感谢您与我分享您对这些方法(利弊)或其他更好解决方案的看法。
答案 0 :(得分:0)
正如评论中指出的那样,这显然是一个糟糕的设计(这是我正在重构的一个旧项目)。因此,我决定摆脱反思,花一些时间重新设计代码本身。
我创建了一个基础超类来处理所有类似方法,并让实体/模型仅实现所需的单个规则,因此,数据库访问仅作为Singleton存储在一个类中。最好使用接口多态性。
通过这种方式,db类处理了动态SQL生成,以避免在各处重复相同的代码,并重复使用/回收实例列表以提高性能。
糟糕。 1:反射会降低性能,通常会使调试更加困难。当然,它可以节省一些时间,因为它实现起来很快,但是会禁用大多数IDE功能,因此在大多数情况下毫无用处。
糟糕。 2:也不应该使数据库实例列表保持活动状态。让多个实例同时访问数据库绝不是一个好主意,它可能导致DB锁定并重现意外的问题。
糟糕。 3:那个JSON东西……算了吧。我很抱歉建议这么丑。