我正在使用 Spring JdbcTemplate 。我有查询通过ID获取数据。 我有这个表模式:
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| id | varchar(150) | NO | PRI | NULL | |
| position_name | varchar(150) | NO | | NULL | |
| description | text | YES | | NULL | |
+---------------+--------------+------+-----+---------+-------+
我使用这个模板运行:
public Position fetchById(final String id) throws Exception {
// TODO Auto-generated method stub
String sql = "SELECT * FROM position WHERE id = ?";
return jdbcTemplate.query(sql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
// TODO Auto-generated method stub
ps.setString(1, id);
}
}, new ResultSetExtractor<Position>() {
public Position extractData(ResultSet rs) throws SQLException,
DataAccessException {
// TODO Auto-generated method stub
Position p = new Position();
p.setId(rs.getString("id"));
p.setPositionName(rs.getString("position_name"));
p.setDescription(rs.getString("description"));
return p;
}
});
}
但是当我像这样进行单元测试时:
@Test
public void getPositionByIdTest() throws Exception {
String id = "35910510-ef2f-11e5-9ce9-5e5517507c66";
Position p = positionService.getPositionById(id);
Assert.assertNotNull(p);
Assert.assertEquals("Project Manager", p.getPositionName());
}
我收到以下错误:
org.springframework.dao.TransientDataAccessResourceException: PreparedStatementCallback; SQL [SELECT * FROM position WHERE id = ?]; Before start of result set; nested exception is java.sql.SQLException: Before start of result set
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:108)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
...
Caused by: java.sql.SQLException: Before start of result set
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)
...
如何在Select query JDBC Template中使用PreparedStatement? 谢谢。
答案 0 :(得分:3)
你有一个简单的用例并使用一种更复杂的查询方法,为什么?接下来您使用的是<form:form name="wblCaseType" method="post" modelAttribute="wblCaseType" action="${saveWblCaseType}">
<form:hidden path="wblCaseTypeId" />
<br/>
<table style="margin-left:80px">
<tbody>
<tr>
<td><form:label path="type"><liferay-ui:message key="type"/></form:label></td>
<td><form:input path="type" /><form:errors path="type" cssClass="errorClass" /></td>
</tr>
<tr>
<td><form:label path="createRoleIds"><liferay-ui:message key="roles"/></form:label></td>
<td><form:checkboxes path="createRoleIds" items="${roles}" value="${wblCaseType.createRoleIds}" itemValue="name" itemLabel="roleId" /></td>
</tr>
,而您可能需要ResultSetExtractor
。如果您使用RowMapper
,则必须自己迭代结果集。用以下
ResultSetExtractor
因此,不要使用其中一种更复杂的方法,而是使用适合您需要的方法。 return getJdbcTemplate.query(sql, new RowMapper<Position>() {
public Position mapRow(ResultSet rs, int row) throws SQLException,
DataAccessException {
Position p = new Position();
p.setId(rs.getString("id"));
p.setPositionName(rs.getString("position_name"));
p.setDescription(rs.getString("description"));
return p;
}, id);
}
无论如何都使用了JdbcTemplate
。
答案 1 :(得分:3)
您需要将ResultSet#next()
调用到&#34;将光标从当前位置向前移动一行。&#34;由于您希望从查询中返回单行,因此可以在if
语句中调用此行,如下所示:
public Position extractData(ResultSet rs) throws SQLException,
DataAccessException {
Position p = new Position();
if(rs.next()) {
p.setId(rs.getString("id"));
p.setPositionName(rs.getString("position_name"));
p.setDescription(rs.getString("description"));
}
return p;
}
如果您希望处理多个结果并返回某种类型的集合,那么您将执行while(rs.next())
并在循环的每次迭代中处理一行。
另外,在使用JdbcTemplate
时,您可以考虑使用RowMapper
代替,这可能会略微简化您的实施。
答案 2 :(得分:1)
如果您使用ResultSetExtractor
,则必须遍历结果以使用next()
来电。这解释了错误,因为ResultSet
仍然位于第一行之前,当您读取其值时。
对于您的用例 - 选择给定ID的记录 - 使用JdbcTemplate.queryForObject
和RowMapper
lambda有一个更简单的解决方案:
String sql = "SELECT * FROM position WHERE id = ?";
Position position = (Position) jdbcTemplate.queryForObject(
sql, new Object[] { id }, (ResultSet rs, int rowNum) -> {
Position p = new Position();
p.setId(rs.getString("id"));
p.setPositionName(rs.getString("position_name"));
p.setDescription(rs.getString("description"));
r eturn p;
});