3.2.2.3.2. 自定义数据类型示例

假设应用程序中实体的某些属性用来存储日期的年份,用整数数字表示。用户能查看和编辑年份,并且如果用户只是输入两个数字,应用程序会将其转换为 2000 至 2100 之间的一个年份,否则,将整个输入的数字作为年份。

首先,在 global 模块创建下面的类:

  1. package com.company.sample.entity;
  2. import com.google.common.base.Strings;
  3. import com.haulmont.chile.core.annotations.JavaClass;
  4. import com.haulmont.chile.core.datatypes.Datatype;
  5. import javax.annotation.Nullable;
  6. import java.text.DecimalFormat;
  7. import java.text.ParseException;
  8. import java.util.Locale;
  9. @JavaClass(Integer.class)
  10. public class YearDatatype implements Datatype<Integer> {
  11. private static final String PATTERN = "##00";
  12. @Override
  13. public String format(@Nullable Object value) {
  14. if (value == null)
  15. return "";
  16. DecimalFormat format = new DecimalFormat(PATTERN);
  17. return format.format(value);
  18. }
  19. @Override
  20. public String format(@Nullable Object value, Locale locale) {
  21. return format(value);
  22. }
  23. @Nullable
  24. @Override
  25. public Integer parse(@Nullable String value) throws ParseException {
  26. if (Strings.isNullOrEmpty(value))
  27. return null;
  28. DecimalFormat format = new DecimalFormat(PATTERN);
  29. int year = format.parse(value).intValue();
  30. if (year > 2100 || year < 0)
  31. throw new ParseException("Invalid year", 0);
  32. if (year < 100)
  33. year += 2000;
  34. return year;
  35. }
  36. @Nullable
  37. @Override
  38. public Integer parse(@Nullable String value, Locale locale) throws ParseException {
  39. return parse(value);
  40. }
  41. }

然后在项目的 metadata.xml 文件中添加 datatypes 元素:

  1. <metadata xmlns="http://schemas.haulmont.com/cuba/metadata.xsd">
  2. <datatypes>
  3. <datatype id="year" class="com.company.sample.entity.YearDatatype"/>
  4. </datatypes>
  5. <!-- ... -->
  6. </metadata>

datatype 元素中,还可以指定 sqlType 属性来包含一个数据库的 SQL 类型,这个 SQL 类型适合在数据库保存这个新类型。SQL 类型会在 CUBA Studio 生成数据库脚本的时候使用。Studio 可以为下面这些 Java 类型自动确定 SQL 类型:

  • java.lang.Boolean

  • java.lang.Integer

  • java.lang.Long

  • java.math.BigDecimal

  • java.lang.Double

  • java.lang.String

  • java.util.Date

  • java.util.UUID

  • byte[]

在上面的例子中,年份应该绑定 Integer 类型(这个类型通过 @JavaClass 注解的 Integer.class 值指定),所以 sqlType 可以省去。

最终,为实体属性设置新的数据类型(编程的方式或者通过 Studio 的帮助):

  1. @MetaProperty(datatype = "year")
  2. @Column(name = "ISSUE_YEAR")
  3. private Integer issueYear;