Java 插入式iBatis鉴别器

Java 插入式iBatis鉴别器,java,ibatis,Java,Ibatis,我有一个抽象类Example和具体的子类。我使用鉴别器从数据库中提取数据,如下所示: <resultMap id="ExampleResultMap" class="Example"> <discriminator column="stateCode" javaType="java.lang.String"> <subMap value="AL" resultMap="AlabamaStateResultMap"/> &

我有一个抽象类
Example
和具体的子类。我使用鉴别器从数据库中提取数据,如下所示:

<resultMap id="ExampleResultMap" class="Example">
    <discriminator column="stateCode" javaType="java.lang.String">
        <subMap value="AL" resultMap="AlabamaStateResultMap"/>
        <subMap value="AR" resultMap="ArkansasStateResultMap"/>
        [...]
    </discriminator>
</resultMap>

<resultMap extends="ExampleResultMap" 
           id="AlabamaStateResultMap"
           class="AlabamaState"/>
<resultMap extends="ExampleResultMap" 
           id="ArkansasStateResultMap"
           class="ArkansasState"/>
[...]

[...]
[...]
因此,我有一个
阿拉巴马州
对象(抽象
示例
对象的子类),没有任何类型的属性。这是人为的,但要点是我没有任何唯一标识对象类型的属性——如果不是在这种情况下,我没有理由这么做

注意:类不是空的,它们是行为的,因此重构它们使其不存在不是一个选项。)

如何将其保存回数据库?

理想情况下,
ParameterMap
s会有一个
鉴别器,但似乎没有

据我所知,有许多不受欢迎的解决方案,其中包括:

  • 放弃并在所有返回静态字符串的子类上添加“getType()”方法。在这种情况下,
    AL
    。(请注意,在我的所有代码中,我都非常努力地避免使用此选项,因此使用此选项=OOD失败)
  • 制作一个“DB”对象,它与我的大而复杂的对象完全相同,但碰巧还有一个额外的字符串,上面写着“哦,顺便说一句,我的类型是AL。”
  • 在插入对象之前,提取我想要保留到HashMap中的所有20个属性
  • 一些其他的疯狂行为,比如使用toString()或其他什么来帮助我
我很可能会选择第一种,但这似乎很荒谬,不是吗?如果iBatis可以创建它,它不应该能够保持它吗?我真正需要的是插入的鉴别器


<>我运气不好,还是我忽略了一些明显的东西?

如果你没有属于你的子类的属性,你应该考虑删除这些子类,并给你的前一个基类添加一个枚举,因为你的子类服务的唯一目的是区分你的对象的类型(如果我理解正确的话)。为此使用枚举更易于扩展,在客户端代码中也更优雅(因为您可以打开枚举而不是使用instanceof表达式块)

如果您的子类上有特定操作的特殊实现,您也可以将它们移动到枚举中,并让基类委托给枚举中的实现

编辑

以下是一个例子:

public interface GreetingStrategy {
    abstract String sayHello();
}

enum UserType implements GreetingStrategy {
    ADMIN {
        @Override
        public String sayHello() {
            return "hello from admin";
        }
    },

    GUEST {
        @Override
        public String sayHello() {
            return "hello from guest";
        }
    };

}

class User {

    private final GreetingStrategy greetingStrategy;

    public User(GreetingStrategy greetingStrategy) {
        this.greetingStrategy = greetingStrategy;
    }

    public String sayHello() {
        return greetingStrategy.sayHello();
    }

}

你能发布你的示例结果图吗?我重写了这个问题。。。希望现在更清楚了。请注意,resultMap是创建对象(db->java)的一个示例,现在我想将其保存回db;CaliforniState对象是否可能声明了一个其他州没有的变量?@Gabriel你找到解决方案了吗?很遗憾,我将该类型添加到了我的对象中。实际上无法扩展枚举,所以我假设你建议我在枚举的自定义方法中创建一个巨大的if-else块?不是粉丝!此外,当您确切地知道要处理的选项(例如状态机)时,拥有一个实际的类在代码可读性方面是非常有益的。“扩展”并不是指继承。引入这样的枚举将不需要编写giant if else块。(如果您的客户端代码中还没有带有instanceof tests的giant if-else块来确定子类型,那么至少不会)。我的观点是:1。如果有没有声明字段和方法的子类,则应该考虑用枚举替换它们。如果您的子类没有字段,只有方法,那么您也可以用枚举替换它们,并在枚举本身上声明方法。我在原始答案中添加了一个示例。我同意,在某些情况下,使用简单枚举比使用臃肿的子类设计更好。此问题专门用于解决枚举不足的情况。在我的例子中,我的“空”(从db的角度)类充满了行为。类本身是父对象(has-a)的状态,每个对象包含六条基于事件的规则。尽管如此,最终,父对象只需要持久化状态(您的状态最终是哪个子类)。如果您的子类上没有任何可变状态,那么枚举是您的场景的完美匹配。枚举在设计上是可变的和单一的。如果你只是用你的子类来表示一个状态,我肯定会选择枚举。我想不出子类的优劣,除了不能单独声明单个枚举常量上的操作(但可以有固定操作集的不同实现)。但我不想听起来很武断——也许我只是在你的特殊场景中遗漏了一些重要的东西。