带有通用类的Java枚举

我正在从解释的世界转换齿轮,我试图复制我在传递中使用的模式,但在Java中取得了巨大的成功.

缺点是我正在制作一个自定义DAO(不使用Hibernate或类似的东西……最终处理不同的数据库引擎(SQL和NoSQL)将是通用的.为了突破我只是使用MySQL / Prepared Statementments .

我想基本上定义一个DataMapper对象,负责将记录的字段映射到数据库中的字段.我试图封装任何冗余逻辑,以实现将类型转换为数据库期望格式的实现细节.在DataMapper中,我试图利用枚举列出字段:

public abstract class AbstractDataMapper<X> {

public static abstract class Field<Y> {
    protected String name;
    public Field(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
    public abstract void setValue(PreparedStatement stmt, int parameterIndex, Y value) 
        throws SQLException;
    public abstract Y getValue(ResultSet rset)
        throws SQLException;
}

public static class IntegerField extends AbstractDataMapper.Field<Integer> {

    public IntegerField(String name) {
        super(name);
    }

    @Override
    public void setValue(PreparedStatement stmt, int parameterIndex,
            Integer value) throws SQLException {
        stmt.setInt(parameterIndex, value.intValue());
    }

    @Override
    public Integer getValue(ResultSet rset) throws SQLException {
        return new Integer(rset.getInt(this.name));
    }
}
}


public class UserDataMapper extends AbstractDataMapper<UserDataRecord>{
    public static enum Field {
    entryId(new AbstractDataMapper.IntegerField("entryid"));

    AbstractDataMapper.Field<?> field = null;

    Field(AbstractDataMapper.Field<?> field) {
        this.field = field;
    }

    public AbstractDataMapper.Field<?> getField() {
        return this.field;
    }

    public String getName() {
        return this.field.getName();
    }
}

显然,我试图将示例截断为有意义的部分.
用于执行此操作的客户端代码

    public int insert(UserDataRecord user) {
    ...
        final String query = 
            "INSERT INTO users SET "
            + UserDataMapper.Field.entryId.getName() + " = ? ";

        stmt = conn.prepareStatement(query);
        UserDataMapper.Field.entryId.getField()
            .setValue(stmt, 1, user.getEntryId());

       }

我遇到的问题是最后一行.我试图使用与entryId枚举关联的泛型对象来使用它的特殊setValue函数,该函数处理将Integer转换为正确的格式.我的IDE给了我以下错误:
    AbstractDataMapper.Field类型中的方法setValue(PreparedStatement,int,capture#13-of?)不适用于参数(PreparedStatement,int,Integer).

我相信我可以进入一系列疯狂的类型转换……但在那时,它可能会更容易暴露翻译细节.

有关实现此功能或修改此模式的任何想法更好吗?

解决方法:

枚举不能是通用的,所以你的情况有问题.

一种更简单的铸造方式

public static enum Field {

public <T> AbstractDataMapper.Field<T> getField() {
    return (AbstractDataMapper.Field<T>)this.field;
}

// usage
UserDataMapper.Field.entryId.<Integer>getField()

更大的问题是,在这里使用枚举有什么意义?使用一些静态公共最终字段会简单得多.

public class UserDataMapper extends AbstractDataMapper<UserDataRecord>{

    public interface Fields {
        IntegerField entryId = new IntegerField("entryid"));

----

    final String query = 
        "INSERT INTO users SET "
        + UserDataMapper.Field.entryId.getName() + " = ? ";

    stmt = conn.prepareStatement(query);
    UserDataMapper.Field.entryId
        .setValue(stmt, 1, user.getEntryId());
上一篇:java – JAX-RPC Web服务中的多态性


下一篇:Java中的多态如何适用于这种一般情况(带参数的方法)?