【问题标题】:How to use a java.sql.Timestamp in JSF view with converter如何在带有转换器的 JSF 视图中使用 java.sql.Timestamp
【发布时间】:2015-03-17 08:26:47
【问题描述】:

如何在 PrimeFaces <p:calendar> 这样的 JSF 日期组件中使用类型为 java.sql.Timestamp 的模型属性?该组件需要一个java.util.Date 的实例作为其输入,并且它还将返回相同类型的java.util.Date

是否可以为这种情况创建转换器?如何实现转换器以将java.sql.Timestamp 转换为java.util.Date?我想我需要一个带有getAsObject()getAsString() 的JSF 转换器,但我不知道应该在哪里进行转换?

实际上,在这种情况下,我有一个 List<Model> 要显示在 <p:dataTable> 中。在每一行中,我可以直接从表中设置 startDate 和 endDate。所以我需要在save()过程中直接使用model属性从表中获取最新/更新的数据。

这是我的模型的示例:

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;
    }

}

这是我的 bean 的示例:

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

【问题讨论】:

  • 你使用jpa框架吗?如果是这样,只需声明 java.util.date 的字段
  • 是的,但我无法将属性类型更改为java.util.Date,因为所有都已生成。

标签: java jsf jdbc timestamp converter


【解决方案1】:

首先,您的模型中不应该有持久层特定的类型属性。你的模型应该有一个java.util.Date 属性。相反,应该更改您的持久层以能够处理java.util.Date 模型属性。

改为在持久层中进行转换。

preparedStatement.setTimestamp(i, new Timestamp(model.getDate().getTime()));

不需要反过来,因为java.sql.Timestamp 已经是java.util.Date 的子类。

【讨论】:

  • 我编辑了我的问题,添加了示例代码。我想我需要直接在&lt;p:dataTable&gt; 中编辑startDateendDate,您明白了吗?
  • 我的回答很难理解吗?您需要将模型中的Timestamp startDateTimestamp endDate 替换为Date startDateDate endDate,并在持久层中进行转换。模型应该不知道任何持久层特定类型。否则,存在紧密耦合的方法(这会导致模型在持久层和视图层之间无法共享,就像您当前遇到的那样)。
  • 是的,我同意你的观点,但我正在寻找其他解决方案。我知道如果我将所有类型为Timestamp 的属性更改为Date 就可以了,但不幸的是我不可能这样做,因为我的所有模型和DAO 都是生成的。还是谢谢你。
  • 那么那个生成器就是做的不好。您需要修复/重新配置它,而不是寻找解决方法。
【解决方案2】:

您可以将时间戳委托给日期,反之亦然。

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

【讨论】:

  • 谢谢,我明白了你试图解释的内容。但我有一个列表可以直接在&lt;p:dataTable&gt; 中编辑。列表大小是不可预测的,所以我认为我不能使用任何变量作为中介。有什么建议吗?
【解决方案3】:

最佳实践是创建一个模型,该模型与@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 作为&lt;p:dataTable&gt; 值:

<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;
    }

}

在 bean 中:

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 作为&lt;p:dataTable&gt; 值:

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

这种解决方法不需要对实际模型进行修改,尽管我们需要做其他事情来将值移动到实际模型中。这对我来说很有用。希望对你有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 2017-08-30
    • 2012-05-12
    • 2013-07-18
    • 2013-04-04
    • 2012-06-27
    • 2011-05-31
    相关资源
    最近更新 更多