如何在 JSF 日期组件(如 PrimeFaces <p:calendar>
)中使用具有java.sql.Timestamp
类型的模型属性?此组件需要 java.util.Date
实例作为其输入,并且它还将返回相同类型的java.util.Date
。
是否可以为这种情况创建一个转换器?如何实现转换器以将java.sql.Timestamp
转换为java.util.Date
?我想我需要一个具有getAsObject()
和getAsString()
的 JSF 转换器,但我不知道我应该在哪里进行转换?
实际上在这种情况下,我有一个List<Model>
要在<p:dataTable>
中显示的。在每一行中,我可以直接从表中设置开始日期和结束日期。所以我需要直接使用模型属性来save()
过程中从表中获取最新/更新的数据。
这是我的模型的示例:
public class Model {
private Timestamp startDate;
private Timestamp endDate;
public Timestamp getStartDate() {
return startDate;
}
public void setStartDate(Timestamp startDate) {
this.startDate = startDate;
}
public Timestamp getEndDate() {
return endDate;
}
public void setEndDate(Timestamp endDate) {
this.endDate = endDate;
}
}
这是我的豆子的示例:
public class PageBean {
private List<Model> listModel;
public String save() {
// Process insert / update listModel to database here
return "next-page"
}
public List<Model> getListModel() {
return listModel;
}
public void setListModel(List<Model> listModel) {
this.listModel = listModel;
}
}
这是我的 xhtml 的示例:
<p:dataTable value="#{pageBean.listModel}" var="model" >
<p:column headerText="Start Date">
<p:calendar value="#{model.startDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
<p:column headerText="End Date">
<p:calendar value="#{model.endDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
</p:dataTable>
<p:commandButton value="Save" action="#{pageBean.save()}" ajax="false" />
我认为如果模型属性类型为 java.util.Date
,可以直接使用模型,但我在这里得到了java.sql.Timestamp
的类型。
您首先不应该在模型中具有特定于持久性层的类型属性。模型应具有java.util.Date
属性。相反,应更改持久性层,以便能够处理java.util.Date
模型属性。
改为在持久性层中进行转换。
preparedStatement.setTimestamp(i, new Timestamp(model.getDate().getTime()));
反之则没有必要,因为java.sql.Timestamp
已经是java.util.Date
的子类。
您可以将时间戳委托给日期,反之亦然。
import java.sql.Timestamp;
import java.util.Date;
...
private Timestamp timestamp;
...
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public Date getDate() {
return timestamp == null ? null : new Date(timestamp.getTime());
}
public void setDate(Date date) {
timestamp = date == null ? null : new Timestamp(date.getTime())
}
JSF:
<p:calendar id="button" value="#{bean.date}" showOn="button" />
最佳做法是创建一个模型,该模型与 @BaulusC 提到的持久性层类型分开。但是我找到了一个适合我情况的解决方案(实际上是一个技巧),即通过使用java.util.Map
或创建另一个模型来绑定视图,但它需要更多的工作。您需要将地图或模型映射器中的值放入实际模型。
- 通过使用
java.util.Map
这是示例 bean:
public class PageBean {
private List<Model> listModel;
private List<Map> listMap;
public String save() {
// Move the values from listMap to listModel
listModel = new ArrayList<Model>();
for (Map map : listMap) {
Model model = new Model();
model.setStartDate(new Timestamp(((Date) map.get("startDate")).getTime());
model.setEndDate(new Timestamp(((Date) map.get("endDate")).getTime());
listModel.add(model);
}
// Process listModel to database ...
return "next-page"
}
public List<Map> getListMap() {
return listMap;
}
public void setListMap(List<Map> listMap) {
this.listMap = listMap;
}
}
在 XHTML 页面中,我们使用 listMap
表示<p:dataTable>
值:
<p:dataTable value="#{pageBean.listMap}" var="map" >
<p:column headerText="Start Date">
<p:calendar value="#{map.startDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
<p:column headerText="End Date">
<p:calendar value="#{map.endDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
</p:dataTable>
<p:commandButton value="Save" action="#{pageBean.save()}" ajax="false" />
- 通过创建另一个模型
用于与视图绑定的新模型示例:
public class ModelMapper {
private Date startDate;
private Date endDate;
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
}
在豆中:
public class PageBean {
private List<Model> listModel;
private List<ModelMapper> listModelMapper;
public String save() {
// Move the values from listModelMapper to listModel
listModel = new ArrayList<Model>();
for (ModelMapper modelMapper : listModelBinder) {
Model model = new Model();
model.setStartDate(new Timestamp(modelMapper.getStartdate().getTime());
model.setEndDate(new Timestamp(modelMapper.getEndDate().getTime());
listModel.add(model);
}
// Process listModel to database ...
return "next-page"
}
public List<ModelMapper> getListModelMapper() {
return listModelMapper;
}
public void setListModelMapper(List<ModelMapper> listModelMapper) {
this.listModelMapper = listModelMapper;
}
}
在 XHTML 页面中,我们使用 listModelMapper
表示<p:dataTable>
值:
<p:dataTable value="#{pageBean.listModelMapper}" var="mapper" >
<p:column headerText="Start Date">
<p:calendar value="#{mapper.startDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
<p:column headerText="End Date">
<p:calendar value="#{mapper.endDate}" pattern="dd-MMM-yyyy" ></p:calendar>
</p:column>
</p:dataTable>
<p:commandButton value="Save" action="#{pageBean.save()}" ajax="false" />
此解决方法不需要修改实际模型,尽管我们需要执行其他操作才能将值移动到实际模型。它对我来说效果很好。希望它会有用。