« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
Blog信息 |
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9692332 建立时间:2004年12月20日 |

| |
[java语言]JdbcTemplate和jav.sql.TIMESTAMP 原创空间
邢红瑞 发表于 2005/6/15 14:51:12 |
看了尚老大的blog关于oracle的日期类型字段的操作,受益很多,.不过不建议使用java.sql.Date,会丢失精度,java2已经不推荐使用了,spring操作oracle的日期类型字段问题也不少.
例如,使用 JdbcTemplate 执行select语句
JdbcTemplate jt = new JdbcTemplate(ds);List values = jt.queryForList("SELECT enterdate FROM acount");Map dt = (Map) values.get(0);
java.sql.Timestamp enterdate = (java.sql.Timestamp)dt.get("enterdate");
Object obj = dt.get("enterdate"); System.out.println("Classname: " + obj.getClass().getName());
数据库中enterdate是 TIMESTAMP字段,这段代码在mysql没有任何问题,但是移植到oracle马上抛出 ClassCastException 异常,因为 queryForList()/get()返回oracle.sql.TIMESTAMP 类型的对象,不是 java.sql.Timestamp 对象,数据库的移植成为不可能.
不过,可以使用 JdbcTemplate.query() 的getxxx类型,因为 QueryForList 和 QueryForObject 方法依靠 rs.getObject返回object类型
dbcTemplate jt = new JdbcTemplate(dataSource); final String sql = "select sysdate, systimestamp from dual"; List results = jt.query( new PreparedStatementCreator() { public PreparedStatement createPreparedStatement(Connection con) throws SQLException { PreparedStatement ps = con.prepareStatement(sql); return ps; } }, new ResultReader() { List results = new ArrayList(); public void processRow(ResultSet rs) throws SQLException { Map rowData = new LinkedHashMap(2); rowData.put("sysdate", rs.getTimestamp(1)); rowData.put("systimestamp", rs.getTimestamp(2)); results.add(rowData); } public List getResults() { return results; } } ); return results; }
更好的办法,使用 RowMapper 代替 RowCallbackHandler或ResultReader,使用sql语句代替 PreparedStatementCreator ,如果处理每一行,建议使用 RowMapper回调( callback).
JdbcTemplate jt = new JdbcTemplate(dataSource); List results = jt.query( "select sysdate, systimestamp from dual", new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { Map rowData = new LinkedHashMap(2); rowData.put("sysdate", rs.getTimestamp(1)); rowData.put("systimestamp", rs.getTimestamp(2)); return rowData; } });
可以修改spring的jdbctemplate.java的代码,
/** * ResultSetExtractor implementation that returns an ArrayList of HashMaps. */ private static class ListResultSetExtractor implements ResultSetExtractor {
public Object extractData(ResultSet rs) throws SQLException { List listOfRows = new ArrayList(); ResultSetMetaData rsmd = null; int numberOfColumns = -1; while (rs.next()) { if (rsmd == null) { // Lazily initialize meta data, to avoid unnecessary fetching // in case of an empty result set. rsmd = rs.getMetaData(); numberOfColumns = rsmd.getColumnCount(); } Map mapOfColValues = CollectionFactory.createLinkedMapIfPossible(numberOfColumns); for (int i = 1; i <= numberOfColumns; i++) { switch(rsmd.getColumnType(i)) { case java.sql.Types.TIMESTAMP: mapOfColValues.put(rsmd.getColumnName(i), rs.getTimestamp(i)); break; default: mapOfColValues.put(rsmd.getColumnName(i), rs.getObject(i)); } } listOfRows.add(mapOfColValues); } return listOfRows; } }
spring新的版本解决了这个问题,sqlserver的jdbc使用Jdbctemplate的getDate得不到时分秒,使用以下代码处理
List values = jt.queryForList("SELECT return_date FROM detail where order_id=9"); Map firstRow = (Map) values.get(0);
java.sql.Timestamp accountdate = (java.sql.Timestamp) firstRow.get("return_date"); System.out.println(accountdate); |
|
|