插入时的 iBatis 判别器

发布于 2024-11-29 20:26:19 字数 1431 浏览 1 评论 0原文

我有一个抽象类 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"/>
[...]

因此,我有一个 AlabamaState 对象(抽象 Example 对象的子类) ),他身上没有任何属性。这是人为的,但要点是我没有任何唯一标识对象类型的属性——如果不是这种情况,我没有理由这样做。

注意:这些类不是空的,它们是行为的,因此重构它们使其不存在并不是一种选择。)

如何保存它返回数据库?

理想情况下,ParameterMap 应该有一个鉴别器,但似乎没有。

据我所知,有许多不需要的解决方案,其中包括:

  • 放弃并在我的所有子类上添加一个返回静态字符串的“getType()”方法。在本例中为AL。 (请注意,我非常努力地避免在我的所有代码中都需要这个,所以有这个= OOD-defeat)。
  • 创建一个与我的大而复杂的对象完全相同的“DB”对象,但碰巧还有一个额外的字符串,表示“哦,顺便说一句,我的类型是 AL”。
  • 在插入对象之前,将我想要保留的所有 20 个属性提取到 HashMap 中。
  • 其他一些疯狂的事情,比如使用 toString() 或其他东西来帮助我。

我可能会选择第一个选项,但这看起来相当荒谬,不是吗?如果iBatis可以创建它,那它不应该能够持久化它吗?我真正需要的是插入鉴别器。

我是运气不好,还是我只是忽略了一些显而易见的事情?

I have an abstract class Example and concrete subclasses to go along with it. I used a discriminator to pull data out of the database, like so:

<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"/>
[...]

Thus I have an AlabamaState object (a subclass of the abstract Example object) with no attributes of any kind on him. This is contrived, but the gist is that I don't have any attribute that uniquely identifies the object's type--and there's no reason I would if not for this case.

(Note: The classes aren't empty, they're behavioral, so refactoring them out of existence isn't an option.)

How do I save it back to the database?

Ideally there would be a Discriminator for ParameterMaps, but there doesn't seem to be one.

As far as I can tell, there are a number of undesirable solutions, among them:

  • Give up and add a "getType()" method on all my subclasses that returns a static string. In this case, AL. (Note that I tried pretty hard to avoid needing this throughout all my code, so having this = OOD-defeat).
  • Make a "DB" object that's exactly like my big, complex object but happens to also have an extra string saying "Oh, btw, my TYPE is AL."
  • Extract all 20 attributes I want to persist into a HashMap before inserting the object.
  • Some other craziness like using the toString() or something to help me out.

Likely I'll go with the first option, but it seems rather ridiculous, doesn't it? If iBatis can create it, shouldn't it be able to persist it? What I really need is a discriminator for insert.

Am I out of luck, or am I just overlooking something obvious?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

毁虫ゝ 2024-12-06 20:26:20

如果您没有属于子类的属性,则应考虑删除这些子类并向以前的基类添加枚举,因为子类服务的唯一目的是区分对象的类型(如果我理解正确的话)。为此使用枚举更容易扩展,并且在客户端代码中更优雅(因为您可以打开枚举而不是使用 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();
    }

}

If you have no attributes belonging to your subclasses, you should consider removing these subclasses and add an enum to your former base-class, since the only purpose your subclasses serve is to differentiate the type of your objects (if I understood you correctly). Using an enum for this is easier to extend and more elegant in client code (since you can switch on the enum instead of using blocks of instanceof expressions).

If are having special implementations of certain operations on your subclasses, you could move them to the enum as well, and have your base class delegate to the implementation on the enum.

EDIT

Here is an example:

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();
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文