尝试创建自己的闪亮ORM系统(不是那些重要信息),我目前正在努力克服java继承限制。这是概念:
public class UserDescriptor implements TableDescriptor {
public static final UserDescriptor INSTANCE = new UserDescriptor();
private UserDescriptor() {
}
public String getTableName() {
return "user";
}
// ======= Columns definition
public static final AbstractColumn<Integer> ID =
new IntegerColumn("id", AbstractColumn.Attribute.NOT_NULL);
public static final AbstractColumn<String> ALIAS =
new StringColumn("alias");
// ... and some more...
}
希望它足够清楚。然后将它们与静态导入一起使用,如:
map = JDBCHelper.selectFirst(UserDescriptor.INSTANCE, Arrays.asList(ID, ALIAS));
其中列表(2. param)是我需要从UserDescriptor定义的表中获取的内容。 map
变量包含自定义地图,其内部具有类似于<AbstractColumn<T>, T>
和方法
public T getValue(AbstractColumn<T> col);
所以我得到的值是类型安全的
Integer id = map.getValue(ID);
String alias = map.getValue(ALIAS);
这个概念目前正在运作,但是:
TableDescriptor概念有点冗长。我有很多表,需要多次写入两次类型和每个列定义的长开头
public static final AbstractColumn<Integer>
这一行是众所周知的java限制的结果 - 不可能扩展枚举类。否则TableDescriptor
将是抽象类,其中字段AbstractColumn<T>
由显式构造函数定义,并且每个后继将枚举实例中定义的列。
这将带来以下优势:
getAllColumns
功能可以在没有反射的情况下完成。遗憾的是,这是不可能的,所以你现在是我最后的希望。我知道enum继承的东西很多次,但我已经有了解决方案,也许在这种特殊情况下可以用其他方式改进它。
什么可能是某种提示 - 这些描述符现在必须是项目的API部分才能选择。我正在努力解决这个问题。并且在API I中,只允许列出列的概述:
public enum UserTableColumns {
ID,
ALIAS
}
并以某种方式将其映射到UserDescriptor - 然后我能够在大多数情况下仅使用此枚举,但我还没有弄清楚它应该如何工作..
selectFisrt
方法的当前签名如下:
CustomResultMap selectFirst(TableDescriptor td, List<AbstractColumn<?>> cols);
并且可能的一个修改是将List<AbstractColumn<?>>
更改为某个枚举值列表,这些值将映射到TableDescriptor
,以便我可以检查这些值是否来自单个表。
编辑:澄清
答案 0 :(得分:0)
我会尝试总结一下我从您的问题和评论中理解的内容:
您的API应包含类似UserTableColumn
的枚举以及当前类似T get(AbstractColumn<T>)
的方法,但应根据列的泛型类型返回正确的类型。由于AbstractColumn
基本上是一个实现细节,因此您希望将其替换为枚举,例如得到这样的东西(不会编译):T get(UserTableColumn<T>)
。
(如果我在某个地方犯了错误,请纠正我。)
问题在于泛型是编译时工具,即编译器需要知道正在使用的类型。但是,枚举值不能具有泛型类型,并且任何参数(例如ID(Integer.class)
)在编译时都不可用,因为它基本上是实例(即运行时)值。
因此,您需要AbstractColumn<T>
之类的东西,尽管这可能是另一个只包含泛型类型的类(并实现了一些接口)。这可能需要一些手动定义或使用预处理器(看看Hibernate如何为其标准api做这件事)。