hibernate - 持久化策略模式的组合接口
hibernate - Persisting a composition interface of strategy pattern
我有以下 class 结构:
public abstract class Creature{
private String name;
//strategy pattern composition
private SkillInterface skill;
}
public interface SkillInterface {
void attack();
}
public class NoSkill implements SkillInterface {
@Override
public void attack() {
//statements
}
}
我的目标是将 Creature 对象持久保存在数据库中的一个 table 处。 SkillInterface 的 Subclasses 没有任何字段。当他们确定行为时,我想将选定的 SkillInterface class 名称转换为字符串,因为我只需要保留生物当前技能策略的 class 名称,使用 [=17 这样的字符串=]().getSimpleName()。我尝试用@Converter注解实现,使用AttributeConverterclass将SkillInterface转成String并保存,但总是映射异常。我希望能够将其保存为字符串并检索为 SkillInterface 对象。
但是我如何用 Hibernate 实现它呢?还是我设计有误?
您可以为此使用代理字段,如下所示:
abstract class Creature {
@Column
private String name;
// strategy pattern composition
private SkillInterface skill;
@Column
private String skillName;
public String getSkillName() {
return skill.getClass().getSimpleName();
}
public void setSkillName(String skillName) {
//ignore
}
}
好的,看来我找到了一个基本解决方案,可用于持久化策略模式接口实现。我使用 @Converter 注释和 AttributeConverter class 将策略 class 名称转换为列,同时保存到数据库并将检索到的字符串转换回策略 class,如下所示:
@Entity
public class Creature {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Convert(converter = SkillConverter.class)
private SkillInterface skill;
}
public class SkillConverter implements AttributeConverter<SkillInterface,String> {
@Override
public String convertToDatabaseColumn(SkillInterface skill) {
return skill.getClass().getSimpleName().toLowerCase();
}
@Override
public SkillInterface convertToEntityAttribute(String dbData) {
//works as a factory
if (dbData.equals("noskill")) {
return new NoSkill();
} else if (dbData.equals("axe")) {
return new Axe();
}
return null;
}
}
public interface SkillInterface {
public String getSkill();
void attack();
}
public class NoSkill implements SkillInterface{
public String getSkill() {
return getClass().getSimpleName();
}
@Override
public void attack() {
//strategy statements
}
}
我有以下 class 结构:
public abstract class Creature{
private String name;
//strategy pattern composition
private SkillInterface skill;
}
public interface SkillInterface {
void attack();
}
public class NoSkill implements SkillInterface {
@Override
public void attack() {
//statements
}
}
我的目标是将 Creature 对象持久保存在数据库中的一个 table 处。 SkillInterface 的 Subclasses 没有任何字段。当他们确定行为时,我想将选定的 SkillInterface class 名称转换为字符串,因为我只需要保留生物当前技能策略的 class 名称,使用 [=17 这样的字符串=]().getSimpleName()。我尝试用@Converter注解实现,使用AttributeConverterclass将SkillInterface转成String并保存,但总是映射异常。我希望能够将其保存为字符串并检索为 SkillInterface 对象。
但是我如何用 Hibernate 实现它呢?还是我设计有误?
您可以为此使用代理字段,如下所示:
abstract class Creature {
@Column
private String name;
// strategy pattern composition
private SkillInterface skill;
@Column
private String skillName;
public String getSkillName() {
return skill.getClass().getSimpleName();
}
public void setSkillName(String skillName) {
//ignore
}
}
好的,看来我找到了一个基本解决方案,可用于持久化策略模式接口实现。我使用 @Converter 注释和 AttributeConverter class 将策略 class 名称转换为列,同时保存到数据库并将检索到的字符串转换回策略 class,如下所示:
@Entity
public class Creature {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Convert(converter = SkillConverter.class)
private SkillInterface skill;
}
public class SkillConverter implements AttributeConverter<SkillInterface,String> {
@Override
public String convertToDatabaseColumn(SkillInterface skill) {
return skill.getClass().getSimpleName().toLowerCase();
}
@Override
public SkillInterface convertToEntityAttribute(String dbData) {
//works as a factory
if (dbData.equals("noskill")) {
return new NoSkill();
} else if (dbData.equals("axe")) {
return new Axe();
}
return null;
}
}
public interface SkillInterface {
public String getSkill();
void attack();
}
public class NoSkill implements SkillInterface{
public String getSkill() {
return getClass().getSimpleName();
}
@Override
public void attack() {
//strategy statements
}
}