0

我想保留一些必须实现这样的接口的类:

@DatabaseTable(tableName = "conditions")
abstract public class Condition implements Configurable {

    @DatabaseField(id = true, foreign = true)
    private Accion belong_to;

    @DatabaseField
    private HashMap<String, String> config = new HashMap<String, String>();

    @DatabaseField
    protected String className = this.getClass().getName();

    protected final HashMap<String, String> getConfig() {/* */}
    protected final void setConfig(HashMap<String, String> config) {/* */}
    protected void setConfig(String string, String value) {/* */}
    abstract public String getName();
    abstract public int getImageResource();
    abstract public String getShortDesc();
}

问题是,我必须在Condition创建它们时实例化正确的孩子(因为 Condition 本身是抽象的)。

在编写 DAO 时有什么办法可以做到这一点(为此我记录了 className)?或者我应该以任何其他方式做到这一点?

我的Accion对象应该Condition附有一个对象。Accion 也是持久化的,所以获取条件的方法也是通过 Dao。


更新:我现在使用public interface Configurable extends Serializable { /*...*/ }Java 可以序列化 Configurable 对象,并将其存储在 Accion 对象中。

那行得通吗?

4

1 回答 1

0

存储的类不应该是抽象类,ClassInstantiationException因为类反射用于实例化检索到的记录。

这里有一个使用包装类发布的解决方法,但到目前为止我的方法是将“类”(在我的情况下为 serverType)存储为一个字段,并且在检索基类时将基类传递给所需子类的构造函数并复制它的属性。

用法

        Dao<BaseConnectionInfo, Integer> connections = DatabaseManager
                .getInstance(this).getDatabaseHelper()
                .getDao(BaseConnectionInfo.class);

        BaseConnectionInfo connection = connections.queryForId(1);

        if (connection.isServerType(BaseConnectionInfo.SERVER_TYPE_MSSQL)) {
            connection = new MsSqlConnectionInfo(connection);
        } else if (connection
                .isServerType(BaseConnectionInfo.SERVER_TYPE_MYSQL)) {
            connection = new MySqlConnectionInfo(connection);
        }

基本连接信息

@DatabaseTable(tableName = "connections")
public class BaseConnectionInfo implements SqlDriverInterface {

    public static final String TAG = "BaseConnection";

    public static final String SERVER_TYPE_MYSQL = "MYSQL";
    public static final String SERVER_TYPE_MSSQL = "MSSQL";
    public static final String SERVER_TYPE_SYBASE = "SYBASE";
    public static final String SERVER_TYPE_POSTGRESQL = "POSTGRESQL";

    @DatabaseField(generatedId = true)
    private int id;

    @DatabaseField
    protected String serverType;

    @DatabaseField
    private String name;

    ...

    public boolean isServerType(String serverType) {
        return this.serverType.equals(serverType);
    }

    ...
}

MySqlConnectionInfo

public class MySqlConnectionInfo extends BaseConnectionInfo {

    public MySqlConnectionInfo() {
        // FOR ORMLITE
        serverType = SERVER_TYPE_MYSQL;
    }

    /**
     * Constructor used to convert {@link BaseConnectionInfo} to
     * {@link MySqlConnectionInfo}
     * 
     * @param baseConnectionInfo
     */
    public MySqlConnectionInfo(BaseConnectionInfo b) {
        setId(b.getId());
        setName(b.getName());
        setHost(b.getHost());
        setOptionsJson(b.getOptionsJson());
    }
    ...
}

MsSqlConnectionInfo

public class MsSqlConnectionInfo extends BaseConnectionInfo {

    public MsSqlConnectionInfo() {
        // FOR ORMLITE
        serverType = SERVER_TYPE_MSSQL;
    }

    /**
     * Constructor used to convert {@link BaseConnectionInfo} to
     * {@link MsSqlConnectionInfo}
     * 
     * @param baseConnectionInfo
     */
    public MsSqlConnectionInfo(BaseConnectionInfo b) {
        setId(b.getId());
        setName(b.getName());
        setHost(b.getHost());
        setOptionsJson(b.getOptionsJson());
    }
    ...
 }
于 2013-03-03T08:50:25.310 回答