在 ofbiz 中查找今天生日的人:如何从 Ofbiz 实体中提取月份和日期

Find the people whose birthday is today in ofbiz: how to extract month and day from Ofbiz entity

我有兴趣使用 ofbiz 查找今天生日的人。

这是用户的实体:

<entity entity-name="User">
    <field name="identifier" type="id-long"></field>
    <field name="dateOfBirth" type="date"></field>
</entity>

这是搜索今天生日用户的损坏代码:

SimpleDateFormat monthDayFormat = new SimpleDateFormat("MM-dd");
Calendar cal = Calendar.getInstance();
String today = monthDayFormat.format(cal.getTime());

List<GenericValue> people = dctx.getDelegator().findList("User",
    EntityCondition.makeCondition("dateOfBirth", EntityOperator.LIKE, "%".today),
    null, null, null, false);

这显然行不通,因为我们正在尝试比较字符串和日期对象。

另一种让它工作的尝试是创建一个视图实体,然后将日期转换为两个整数:日和月,或者使用上面的代码将日期转换为字符串。显然,我找不到任何让它工作的方法。

最有效的方法是构建视图实体。 以下定义应该适用于多个数据库(例如 PostgreSQL), i.e. the ones that support the EXTRACT 函数:

<view-entity entity-name="UserView">
  <member-entity entity-alias="USER" entity-name="User"/>
  <alias-all entity-alias="USER"/>
  <alias name="dayOfBirth" function="extract-day" entity-alias="USER" field="dateOfBirth"/>
  <alias name="monthOfBirth" function="extract-month" entity-alias="USER" field="dateOfBirth"/>
</view-entity>

通过上述视图,您可以通过限制两个新字段轻松执行查询:

List<GenericValue> users = EntityQuery.use(dctx.getDelegator()).from("UserView").where("dayOfBirth", day, "monthOfBirth", month).queryList();

或者,如果您正在编写 Groovy 脚本,它在 OFBiz DSL 中的等价物:

List<GenericValue> users = from("UserView").where("dayOfBirth", day, "monthOfBirth", month).queryList();

或者,采用完全不同的方法,您可以通过添加 "dayOfBirth" 和 "monthOfBirth" 字段("numeric" 类型)来扩展 "User" 实体:

<entity entity-name="User">
    <field name="identifier" type="id-long"></field>
    <field name="dateOfBirth" type="date"></field>
    <field name="dayOfBirth" type="numeric"></field>
    <field name="monthOfBirth" type="numeric"></field>
</entity>

然后您可以定义一个 eca 规则来触发服务的执行,以便在每次使用非空 dateOfBirth 字段创建或更新用户记录时填充两个新字段:

<eca entity="User" operation="create-store" event="return">
    <condition field-name="dateOfBirth" operator="is-not-empty"/>
    <action service="populateDayAndMonthOfBirth" mode="sync"/>
</eca>

populateDayAndMonthOfBirth 服务的服务定义如下所示:

<service name="populateDayAndMonthOfBirth">
    <attribute name="identifier" type="String" mode="IN" optional="false"/>
</service>

(请填写 "engine"、"location" 和 "invoke" 等缺失的属性。 该服务只是 select 记录,从其 dateOfBirth 字段中提取表示日期和月份的整数,并将它们存储在 dayOfBirth 和 monthOfBirth 字段中。

基本上你可以结合两个条件:

Calendar cal = Calendar.getInstance();      
cal.setTime(date);                          
cal.set(Calendar.HOUR_OF_DAY, 0);           
cal.set(Calendar.MINUTE, 0);                
cal.set(Calendar.SECOND, 0);                
cal.set(Calendar.MILLISECOND, 0);           
Date tmpDate = cal.getTime();      
Timestamp from = new Timestamp(tmpDate.getTime());
EntityCondition condf = EntityCondition.makeCondition("dateOfBirth", 
EntityOperator.GREATER_THAN_EQUAL_TO, from);

cal.set(Calendar.HOUR_OF_DAY, 23);           
cal.set(Calendar.MINUTE, 59);                
cal.set(Calendar.SECOND, 59);                
cal.set(Calendar.MILLISECOND, 999);           
tmpDate = cal.getTime();  
Timestamp thru = new Timestamp(tmpDate.getTime());
EntityCondition condt = EntityCondition.makeCondition("dateOfBirth", 
EntityOperator.LESS_THAN_EQUAL_TO, thru);

然后找到:

List<GenericValue> people = dctx.getDelegator().findList("User",
EntityCondition.makeCondition(condf, condt), null, null, null, false);