如何在带有转换器的 JSF 视图中使用 java.sql.Timestamp



如何在 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或创建另一个模型来绑定视图,但它需要更多的工作。您需要将地图或模型映射器中的值放入实际模型。

  1. 通过使用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" />
  1. 通过创建另一个模型

用于与视图绑定的新模型示例:

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" />

此解决方法不需要修改实际模型,尽管我们需要执行其他操作才能将值移动到实际模型。它对我来说效果很好。希望它会有用。

最新更新