14

我正在做一些需要从数据库中提取数据的项目,我使用 Spring MVC 从数据库中构建模型以选择数据。

这是我的JSP 页面的问题:

<form action="result" method="get" >
<table>
<thead>
<tr>
<th>Date to select:</th>
<th>Name to select:</th>
<th>Type to select:</th>
</tr>
</thead>

<tbody>
<tr>
<td><form:select  path="listOfDates">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfDates}"></form:options>
</form:select>
</td>  
<td><form:select  path="listOfInstitutionsNames">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfInstitutionsNames}"></form:options>
</form:select>
</td>
<td>
<form:select  path="listOfInstitutionsTypes">
<form:option value="NONE"> --SELECT--</form:option>
<form:options items="${listOfInstitutionsTypes}"></form:options>
</form:select>
</td>
</tr>
</tbody>

<tfoot>
<tr>
<td><input type="submit" value="Извлечь"/></td>
</tr>
</tfoot>

</table>
</form>

如您所见,我尝试<form:select>Spring标签库中使用。
问题:
但是当它用这个控制器准备我的模型时:

@Controller
public class HomeController{ 

    @Autowired
    private ControllerSupportClass controllerSupportClass; 


        @RequestMapping(value="/search", method=RequestMethod.GET)
        public String search(Model model) {
            List<Date> listOfDates = controllerSupportClass.findAllDatesForm();
            List<String> listOfInstitutionsNames = controllerSupportClass.findAllInstitutionsForm();
            List<String> listOfInstitutionsTypes = controllerSupportClass.findAllTypesForm();
            model.addAttribute("listOfInstitutionsTypes", listOfInstitutionsTypes);
            model.addAttribute("listOfInstitutionsNames", listOfInstitutionsNames);
            model.addAttribute("listOfDates", listOfDates);
            return "search";    
        }


        @RequestMapping(value ="/result", method=RequestMethod.GET)
        public String SecondActionPage(@RequestParam String particularDate, 
                                       @RequestParam String nameOfInstitution, 
                                       @RequestParam String typeName,
                                       Model model) throws Exception {


                if(particularDate !="" && nameOfInstitution.trim() !="" && typeName.trim()=="") {                   
                    controllerSupportClass.findWithDateAndName(nameOfInstitution, particularDate, model);                   
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() =="" && typeName.trim() !="") {                    
                    controllerSupportClass.findWithAddedDateAndType(typeName, particularDate, model);                   
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() =="" && typeName.trim() ==""){         
                    controllerSupportClass.findWithAddedDate(particularDate, model);    
                } else if(particularDate.trim() !="" && nameOfInstitution.trim() !="" && typeName.trim() !="") {
                    throw new Exception("Search by choose all parameters is not exceptable");   
                } else {    
                    throw new Exception("You didn't put any search parameters");    
                }           
            return "search";
        }

}

它给了我这样的错误:

带有路径 [/controller] 的 servlet [appServlet] 的 service() 引发异常 [请求处理失败;嵌套异常是 org.hibernate.exception.GenericJDBCException:无法执行查询],根本原因是 java.sql.SQLException:值 '0000-00-00' 不能表示为 java.sql.Date

如果您需要我的 Entity 类,我在这里使用Datefrom java.util,但我使用@Temporal注释将其从 SQL 转换Date为我理解的单元:

@Entity
@Table(name="CREATION_DATE")
public class CreationDate implements Serializable {


    private int dateId;

        @Id
        @GeneratedValue(strategy=IDENTITY)
        @Column(name="DATE_ID")
        public int getDateId() {
            return dateId;
        }

        public void setDateId(int dateId) {
            this.dateId = dateId;
        }


    private int version;

        @Version
        @Column(name="VERSION")
        public int getVersion() {
            return version;
        }

        public void setVersion(int version) {
            this.version = version;
        }


    private Date particularDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="PARTICULAR_DATE")
        public Date getParticularDate() {
            return particularDate;
        }

        public void setParticularDate(Date particularDate) {
            this.particularDate = particularDate;
        }


    private Date childGoSchoolDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="CHILD_GO_SCHOOL_DATE")
        public Date getChildGoSchoolDate() {
            return childGoSchoolDate;
        }

        public void setChildGoSchoolDate(Date childGoSchoolDate) {
            this.childGoSchoolDate = childGoSchoolDate;
        }


    private Date childAdmissionDate;

        @Temporal(TemporalType.DATE)
        @DateTimeFormat(pattern="yyyy-MM-dd")
        @Column(name="CHILD_ADMISSION_DATE")
        public Date getChildAdmissionDate() {
            return childAdmissionDate;
        }

        public void setChildAdmissionDate(Date childAdmissionDate) {
            this.childAdmissionDate = childAdmissionDate;
        }


}

假设数据类型转换的问题是因为MVC使用String的,但实际类型是Date.

4

6 回答 6

38

在 MySql'0000-00-00'中被认为是一个有效的日期,但它不能被表示为 java.sql.Date。

如果 date 是 ,您可以使用返回 NULL 的查询,'0000-00-00'否则返回实际值:

SELECT
  CASE WHEN `date`!='0000-00-00' THEN `date` END new_date
FROM
  yourtable

或者您可以将以下内容添加到您的数据源连接字符串中:

zeroDateTimeBehavior=convertToNull

和日期'0000-00-00'将自动转换为 NULL。

于 2013-06-19T16:22:20.163 回答
23

使用 JDBC-mysql 协议附加以下语句:

"?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8"

例如:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8
于 2014-06-07T04:52:50.687 回答
6

添加zeroDateTimeBehavior=convertToNull 到 jdbc 连接 URL。

String jdbcUrl="jdbc:mysql://localhost:3306/master_schema?zeroDateTimeBehavior=convertToNull"
于 2018-09-26T08:30:15.093 回答
3

这并不总是NULL问题。您的数据集可能包含格式中的日期,05/23/2005并且运行加载程序将导致它插入0000-00-00到您的 DATE 类型列中。无效DATE的 , DATETIME, 或TIMESTAMP值被转换为适当类型的“零”值('0000-00-00' 或 '0000-00-00 00:00:00')(来自 MySQL 手册)

在使用 aSELECT检索时,MySQL 会检索toYYYY-MM-DD'范围内的 format值。所以你所有的开始搞砸了。'1000-01-01''9999-12-31'0000-00-00

因此,不仅要注意,NULLs还要注意 MySQL 不支持的日期格式。

支持 RELAXED 模式,其中任何字符都可以用作分隔符,如/in 05/23/2005- 您可能也想尝试一下。

于 2013-11-05T21:54:36.270 回答
3

对我来说,以下工作很简单。感谢@Yogesh H Bhosale@fthiella在同一个 QA 线程中的回答,我找到了提示,并对其进行了改进。

代码片段:
连接字符串:

private static String CONNECTION_STR = "jdbc:mysql://localhost:3306/water_billing?zeroDateTimeBehavior=convertToNull";

SQL-DB 实现:

并且为了防止在从返回的数据集中提取数据(日期字段)时出现空指针异常,我将以下代码添加到 Prepared Statement 中。

Connection conn = DriverManager.getConnection(CONNECTION_STR,USERNAME,PASSWORD);   //   Get connection to the DB to execute the query. You will have to handle exceptions here too..
String SQL = "SELECT dateField FROM my_payments_tbl";
ResultSet rs = conn.createStatement().executeQuery(SQL);
LocalDate prvPaymentDate = null;

while (rs.next())
{
     // Following is the next Important line.
     prvPaymentDate = (rs.getDate(1) != null) ? rs.getDate(1).toLocalDate() : null;    // Checks if it comes as a Null or a Real java.sql.Date object.

     // Depending on the value of the column in the current row, prvPaymentDate could be null.
     // Specially as we instructed via the Connection String, 0000-00-00 00:00:00 will come now as SQL NULL objects.
     // So we filter out them in the above line and assigns null, instead of LocalDate objects.
     if (prvPaymentDate != null)
        System.out.println("date "+prvPaymentDate.toString());
}

注意:
请阅读答案中的所有评论以获得良好的理解。

于 2015-10-08T07:00:33.927 回答
2

我的猜测是您使用的是 MySQL,您的日期列不是强制性的,因此可以包含 NULL,但是 MySQL 会做一些愚蠢的事情,除非您修复 MySQL 服务器设置,否则它将返回 0000-00-00 而不是 NULL。

于 2013-06-19T15:43:17.187 回答