使用Groovy将枚举映射到实体
我有以下数据库表:使用Groovy将枚举映射到实体,groovy,enums,Groovy,Enums,我有以下数据库表: widget_types ------------ widget_type_id widget_type_name widget_type_alias widget_type_description 这对应于以下Groovy实体类: class WidgetType extends BaseLookupEntity { Long id String name String alias String description } 实际上,Wid
widget_types
------------
widget_type_id
widget_type_name
widget_type_alias
widget_type_description
这对应于以下Groovy实体类:
class WidgetType extends BaseLookupEntity {
Long id
String name
String alias
String description
}
实际上,WidgetType
/widget\u类型
确实应该是enum
,因为它们是引用/查找类型,具有少量有效值:
RedWidget
SillyWidget
HappyWidget
BerserkingWidget
香肠小部件
小部件类型
表映射到枚举
。因此,我创建了一个“助手枚举”:
这里的想法是JPA/OR层将创建WidgetType
实例,但为了能够真正使用它们(类型安全等),我希望能够将它们转换为WidgetTypeLookups
:
// Inside some method...
WidgetType widgetType = getSomehowButStillNotSureWhichTypeItIs()
WidgetTypeLookup wtLookup = WidgetTypeLookup.toWidgetTypeLookup(widgetType)
switch(wtLookup) {
case Happy:
// etc...
}
因此,我正在努力寻找一种在POGO类型和enum之间进行转换的高效“Groovy方式”。基本上实现了helper方法。有什么想法吗?枚举是数量有限的固定元素,除非该表只有固定行,
Widget Red/Silly/etc
应该是子类
您可以在WidgetType
类中实现helper方法,并从内部枚举操作专门化(尽管它们不能引用外部类)
我认为widget.install()
更酷、更面向对象(从某种意义上说,我不需要拉着对象的内脏去做一些事情)
另一种解决方案是,如果WidgetType
是一个抽象类,并且您的ORM将基于特定值实例化正确的具体类型:
abstract class WidgetType {
Long id
String name
String alias
String description
abstract install(container)
enum Type {
RED(RedWidget),
SAUSAGE(SausageWidget),
}
static WidgetType from(type, properties) {
Type.values().find { it.name() == type }
.clazz
.newInstance(properties: properties)
}
}
class RedWidget extends WidgetType {
def install(container) { 'red installing into $container' }
}
class SausageWidget extends WidgetType {
def install(container) { 'elongated component installing into $container' }
}
假ORM:
class ORM {
def container = [
(1) : [
id: 1,
name: 'RED',
alias: 'my red alias',
description: 'this art red' ],
(2) : [
id: 2,
name: 'SAUSAGE',
alias: 'long component',
description: 'sausage component' ]
]
def get(id) {
container[it].with {
WidgetType.from(it.name, id)
}
}
}
测试:
red = new ORM().get(1)
assert red.install('main') ==
'red installing into main'
sausage = new ORM().get(2)
assert sausage.install('display') ==
'elongated component installing into display'
我同意另一个答案,即可能有更好的方法通过改进OO设计来解决您的问题。尽管我会尽量适应你的方法 首先-您不能按照下面的步骤操作,并立即将名称映射为enum吗
class WidgetType extends BaseLookupEntity {
Long id
WidgetName name
String alias
String description
enum WidgetName {
Red,
Silly,
Happy,
Berserking,
Sausage
}
}
Second-您想要实现的方法可以实现为:
static WidgetTypeLookup toWidgetTypeLookup(WidgetType type) {
values().find {
it.name() == type.name
}
}
然而:
- 如果名称不完全匹配,则可能需要调整条件
- 当找不到匹配的枚举时,可能需要以某种方式处理该情况
- 方法的名称应该是
,然后您将有类似fromWidgetType()
的调用,而不是冗余的WidgetTypeLookup.fromWidgetType(widgetType)
WidgetTypeLookup.toWidgetTypeLookup(widgetType)
WidgetType widgetType = new WidgetTypeDetails(name: 'Red') as WidgetType
让我觉得“哦,哦”的部分是开关(wtLookup)块。你会在这样一个开关块中写些什么?Emanuel,任何类型的条件逻辑。也许“快乐”小部件应该向左,但“狂暴”小部件应该向右。我发现使用类型安全枚举更容易做到这一点,而不是像这样做:
if(widgetType.alias.equals('HAPPY')){goLeft()}
,等等。
static WidgetTypeLookup toWidgetTypeLookup(WidgetType type) {
values().find {
it.name() == type.name
}
}
enum WidgetType {
Red,
Silly,
Happy,
Berserking,
Sausage
}
class WidgetTypeDetails {
Long id
String name
String alias
String description
Object asType(Class clazz) {
if (clazz == WidgetType) {
WidgetType.values().find {
it.name() == this.name
}
}
}
}
WidgetType widgetType = new WidgetTypeDetails(name: 'Red') as WidgetType