1

我想要实现的是对我的数据库表的一个很好的抽象。我正在寻找的结果是能够做到这一点:

System.out.println(Table.Appointment);    // prints the name of the table 
System.out.println(Table.Appointment.ID); // prints the name of the column

这是我已经接近的内容,但字段似乎优先于静态内部类。

public class Table {

    // attempt to allow 'Table.Appointment' to resolve to a String
    public static final Table Appointment = new Table("Appointment");

    // attempt to give access to column names within the table,
    // these class names should be the same as its name field above.
    public static final class Appointment{
        public static final String ID = "AppointmentId";
    };

    private String name; 
    private Table(String name){ this.name = name; }
    public String toString() { return name; }
}

这真的可以实现吗?

4

2 回答 2

2

虽然我强烈反对您正在做的事情,只是因为它使您的应用程序过于稳固,但这是有效的(已编辑以避免循环引用。):

public final class Table {

    // ===== DECLARE YOUR INSTANCES HERE =====

    static public final AppointmentTable Appointment = new AppointmentTable();
    // static public final FooTable Foo = new FooTable();

    // =======================================

    static private abstract class TableImpl {
        public abstract String getTableName();
        public String toString() { return getTableName(); }
    }

    // ==== DECLARE YOUR DEFINITIONS BELOW ====

    static public class AppointmentTable extends TableImpl {
        public final String ID = "appointmentId";
        // public final <type> <columnName> = <dbFieldName>;

        public String getTableName() { return "appointment"; }
        private AppointmentTable() {}
    }

    // static public class FooTable extends TableImpl { ... }

}

这是尽可能接近你想要的。请注意,用户实际上不会看到这种设计,只有程序员会……所以谁在乎呢?

此外,访问Table.AppointmentTable是正常的。这是您可以访问的方式Table.Appointment.ID。但是您不能创建它的实例,也不能扩展它,这一切都很好。

**编辑**

为什么会有这个限制?因为您不能只使用类型并将其视为值。类型定义容器,而不是内容。尽管你不能System.out.println(int);,因为int它是一个标记(或一个类型,或一个容器),你不能将一个类名视为一个可以回显的值。除其他外,这就是您拥有Table.AppointmentTable.class.getSimpleName()(或.getName())的原因。

您只能使用值。类定义不是一个值,它是一个值的容器的定义。该类定义的变量包含该容器的内容,您可以从中回显或操作。

未分配的变量也是如此。如果你试试 :

int foo;
System.out.println(foo);

编译器会抱怨foo未初始化。这是因为声明一个变量不会为其分配任何内容(您声明一个int名为类型的容器foo),除非您为其分配某些内容(内容),否则不会使其包含任何内容。

于 2013-01-19T02:58:35.567 回答
0

我会做类似的事情

Table appointment = new Table("appointment" // table name
                            , "appointmentId"  // id column name);

System.out.println(appointment.getTableName());    
System.out.println(appointment.getIdColumnName()); 

如果您想将完成的事情推送到编译时,您可以使用子类。

class Appointment extends Table{
    Appointment(){  super("appointment", "appointmentId"); }
}
于 2013-01-19T02:58:44.683 回答