这一数据验证过程将会为每一个数据库运行一次查询,并且将结果映射到展示出针对特定业务记录类型所有字段的实体bean中. 映射数据实体的每一个字段上的注解会告诉处理器如何为特定字段及在每个数据库中找到的其值执行数据比对. 因此让我们来看几个示例来了解这些注解是如何被运用于不同的数据比对配置的.
为了验证现有的值并同每个数据源中的只精确匹配,你只需要提供一个字段ID以及将会展示在报表上字段的标记. 1 2 | @ReconField (id = CUSTOMER_ID, label = "Customer ID" )
private String customerId;
|
为了展示在每个数据源中找到的值,但不做任何数据比对,你可能需要制定 compareSources 元素,并将其值设置为false. 1 2 | @ReconField (id = NAME, label = "NAME" , compareSources = false )
private String name;
|
为了验证在指定数据源中找到的值,而不是全部,你可能会使用到 elementsourcesToCompare. 使用这个东西会展示所有找到的值,但是只对在元素中列出的数据源中找到的值进行比对. 这样就能处理有些不是在每一个数据源中都会存储的数据场景了. ReconSource 是一个包含了可以用来进行比对的数据源的枚举类型.
1 2 | @ReconField (id = PRIVATE_PLACEMENT_FLAG, label = "PRIVATE PLACEMENT FLAG" , sourcesToCompare ={ ReconSource.LEGACY, ReconSource.PACE })
private String privatePlacementFlag;
|
现在我们已经满足了我们的基本需求,我们需要解决实现指定字段来进行复杂数据比对能力的问题. 为此,我们将创建第二个注解,来驱动定制规则处理. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Target (ElementType.FIELD)
@Retention (RetentionPolicy.RUNTIME)
public @interface ReconCustomRule {
/**
* Value indicates the parameters used to instantiate a custom rule processor, the default value is no parameters.
*
* @return The String[] of parameters to instantiate a custom rule processor.
*/
String[] params() default {};
/**
* Value indicates the class of the custom rule processor to be used in comparing the values from each source.
*
* @return The class of the custom rule processor.
*/
Class<?> processor() default DefaultReconRule. class ;
}
|
同之前的注解非常类似,最大的不同在于 @ReconCustomRule 注解中我们指定了一个类,它可以在重建处理执行时执行数据比对. 你可以只定义将会被用到的类,那样你的处理器就可以实例化并初始化你所指定的类. 在这个注解中指定的类将需要实现一个通用的规则接口,它将会被规则处理器用来执行规则.
现在让我们来看看使用这个注解 的例子.
在本例中,我们使用了一个自定义的规则,它将会检查股票交易所是不是 United States,如果是则跳过这条数据. 为此,这条规则将需要检查同一记录中的 exchange country 字段. 1 2 3 | @ReconField (id = STREET_CUSIP, label = "STREET CUSIP" , compareSources = false )
@ReconCustomRule (processor = SkipNonUSExchangeComparisonRule. class )
private String streetCusip;
|
这里的示例我们为自定义规则指定了一个参数,这里它是一个包容量. 对于这种特殊的数据比对,被比较的值不能偏离超过1000.通过使用指定了包容量的参数,我们就可以使用不同的包容量将同一套自定义规则运用到多个字段上. 唯一的缺点就是,由于注解的性质,这些参数都只能是静态的,所以不能动态的修改. 1 2 3 4 | @ReconField (id = USD_MKT_CAP, label = "MARKET CAP USD" , displayFormat = ReconDisplayFormat.NUMERIC_WHOLE, sourcesToCompare =
{ ReconSource.LEGACY, ReconSource.PACE, ReconSource.BOB_PRCM })
@ReconCustomRule (processor = ToleranceAmountRule. class , params = { "10000" })
private BigDecimal usdMktCap;
|
如你所见,我们只使用了几个简单的注解,就设计出了一个具有相当程度灵活性的面向多数据库场景的数据验证报告功能. 在这个特殊情况下,注解驱动了数据的比对过程,因此我们实际上就是使用了注解在找到的映射数据实体上进行计算并直接使用它们进行处理.
结论 关于Java注解能做什么以及它们的使用规则,已经有了相当多的文章。 本文更多的是聚焦于一个实例,借以说明为什么你需要考虑使用注解,同时也能直观的看看有什么好处。
要记住这只是一个起步,一旦你决定要创建使用注解,你还要想清楚要怎样处理它们才能真正发挥他们的长处。在后面的文章中,我将向你们展示如何使用Java反射来处理注解。在那之前,有一些不错的关于Java注解的资料可以看看: – Jonny Hackett, asktheteam@keyholesoftware.com |