假设我有一个预定义的值列表( RW,FW,4W ),表示车辆的驱动类型:
RW - 后轮
FW - Front Wheet
4W - 四轮
现在,我想从上面的3个值中取一个值作为我用户的输入,然后将其存储在数据库中。
据我所知,我可以借助以下任何一种方法执行此操作:
- 对UI上的值进行硬编码,以便UI显示仅包含上述3个值的下拉列表。然后将该值存储在String vehicleType
对象的Vehicle vehicle
字段中,然后将其作为String
存储在数据库中。
缺点:
i)中。没有验证对象级别的值
ⅱ)。没有验证数据库级别的值。
ⅲ)。虽然很少需要为列表添加新值,但用户仍然无法在运行时添加新值
- 优点:
i)中。数据库中不需要join
来检索vehicle
对象
或
在包含所有3个值的数据库中创建一个单独的表VEHICLE_TYPE
,并将其与VEHICLE
表通过。外键。然后从VEHICLE_TYPE
表填充UI的下拉列表。将值存储在vehicle
对象中String
- 缺点:
i)中。在对象级别没有验证
ⅱ)。在DB处需要join
来检索vehicle
对象
- 优点:
i)中。验证DB级别的值(通过外键)
ⅱ)。用户可以在运行时向列表中添加新值
或
在数据库中创建一个单独的表VEHICLE_TYPE
,其中包含所有3个值,但不要链接它使用VEHICLE
表格。外键。然后从VEHICLE_TYPE
表填充UI的下拉列表。将值存储在vehicle
对象和数据库中String
- 缺点:
i)中。在对象级别没有验证
ⅱ)。没有DB级别的验证
- 优点:
i)中。数据库级别不需要join
ⅱ)。用户可以将新值添加到列表
或
在包含所有3个值的数据库中创建一个单独的表VEHICLE_TYPE
,并将其与VEHICLE
表通过。外键。然后从VEHICLE_TYPE
表填充UI的下拉列表。在java中创建enum VehicleType
,然后在VehicleType vehicleType
类中添加字段Vehicle
。根据用户的输入,在VehicleType
字段中存储vehicleType
枚举的值。
-Cons:
i)中。必须在两个位置更新列表:VehicleType
枚举和VEHICLE_TYPE
表。可能导致不一致。
ⅱ)。用户无法在列表中添加新值(他可以在表中添加值但不能更改枚举)
- 优点:
i)中。在UI级别进行验证
ⅱ)。对象级别的验证
ⅲ)。数据库级别的验证
问题: 还有其他方法可以执行上述没有任何上述缺点的任务吗?
答案 0 :(得分:2)
不确定。你的第二个修改:
在DB中创建一个具有所有3个值的单独表VEHICLE_TYPE
,并将其与VEHICLE
表通过。外键。然后从VEHICLE_TYPE
表填充UI的下拉列表。将值存储在车辆对象中String
。调用vehicle.setVehicleType()
时,通过检查数据库中的可能值来验证分配的值是否有效。如果它无效,则抛出InvalidArgumentException
或子类。
现在您已在对象中进行验证。而且,我不认为必须加入骗局。没有加入表格,你无法做很多事情。这就是你有很多桌子的原因。
答案 1 :(得分:1)
我也会选择第二种方法。你已经回答了第一个问题。
关于第二个问题,如果性能如此重要,您可以使用以下方法之一:
如果类型车辆在应用中使用不多,则延迟加载车辆的类型。
如果您没有使用数据库ID,因为您使用车辆类型的代码作为主键,您可以将codeType属性添加到您的车辆类,并加载此属性而不是类型(可以也可以直接从车辆表中懒散地装载,视具体需要而定。那你就没有任何加入。
答案 2 :(得分:1)
我不认为联接应该引起您的关注 - 您可能会发现,为了减少JOIN的开销而牺牲设计很可能会浪费精力。您对db的网络延迟可能高于JOIN开销。
如何处理用户输入的其他值取决于您希望如何处理它们:
将它们视为真正的附加值。它们被添加到数据库中的VEHICLE_TYPE,一旦添加,就可供所有用户选择。
将它们视为该特定字段的自定义值。即VEHICLE_TYPE包含“其他”类型,用户可以在单独的字段中输入其他详细信息。这些不会与其他用户共享,也不会显示在下拉列表中。
要获得对象级验证,请针对VEHICLE_TYPE进行验证。这可以使用现代OIM和ORM框架自动完成。这些允许您在模型上定义验证规则,然后将其传播到UI以便及早捕获验证错误,然后向后传递到数据库以确保数据存储的一致性。
您可以将车辆ID存储为常规键或类型字符串本身(RW,FW等)。如果使用类型字符串本身,则不必加入VEHICLE_TYPE表。您可以直接显示字符串,或者如果需要本地化,您可以从资源包中获取表示字符串。
编辑:要了解ORM和OIM如何将模型验证元数据返回到数据库并返回到用户界面,请参阅DZone:Hibernate 4 Validation和Metawidget。使用JSR 303,您可以在UI,业务层和后端验证对象。
答案 3 :(得分:1)
创建一个单独的表Vehicle_type(Vehicle_type_id int,description varchar(您需要确定适当的大小))以用作下拉菜单的查找。如果您希望在查找更改时在主表中更改值(例如adimin将seden更改为sedan),则将typeid存储在车辆表中。如果您希望这是历史数据(可能不再有类型轿车,但旧车仍应标记为轿车),则将类型的描述存储在车辆表中。在第二种情况下,您无法强制执行FK关系,因此您需要确保插入(以及仅更新该值)不能选择当前不在表中的值。应用程序可能会执行此操作,但如果值可能在应用程序外部更改,则可以编写触发器来执行此操作。