IBatis Discriminator on Insert
У меня есть абстрактный класс Example
и конкретные подклассы, чтобы идти вместе с ним. Я использовал дискриминатор для вывода данных out из базы данных, например:
<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
s будет Discriminator
, но, похоже, не существует.
Насколько я могу судить, существует ряд нежелательных решений, среди которых:
- Откажитесь и добавьте метод getType() во всех моих подклассах, который возвращает статическую строку. В этом случае
AL
. (Обратите внимание, что я очень старался избежать этого во всем моем коде, поэтому, имея это = OOD-поражение).
- Создайте объект "DB", который точно так же, как мой большой сложный объект, но также имеет дополнительную строку: "О, кстати, мой ТИП - это AL".
- Извлеките все 20 атрибутов, которые я хочу сохранить в HashMap, прежде чем вставлять объект.
- Некоторые другие сумасшествия, такие как использование toString() или что-то, что поможет мне.
Вероятно, я поеду с первым вариантом, но это кажется довольно смешным, не так ли? Если iBatis может его создать, разве он не сможет его сохранить? Мне действительно нужен дискриминатор для вставки.
Мне повезло, или я просто не замечаю ничего очевидного?
Ответы
Ответ 1
Если у вас нет атрибутов, принадлежащих вашим подклассам, вам следует рассмотреть возможность удаления этих подклассов и добавить перечисление в ваш прежний базовый класс, поскольку единственная цель, которую выполняют ваши подклассы, - это различать типы ваших объектов (если я понял вас правильно). Использование перечисления для этого проще расширить и более элегантно в клиентском коде (поскольку вы можете включить перечисление вместо использования блоков экземпляров expression).
Если у вас есть специальные реализации определенных операций над вашими подклассами, вы также можете перенести их в перечисление и предоставить делегат базового класса для реализации в перечислении.
ИЗМЕНИТЬ
Вот пример:
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();
}
}