- 浏览: 240952 次
- 性别:
- 来自: 皇城根儿下
文章分类
最新评论
-
悦悦余音:
楼主妙笔生花的文章解决了我的问题
hessian http response code:411 -
297434791:
返回对象有警告··返回String就没警告了,什么原因
hessian异常 -
lsjinpeng:
这个中文乱码怎么弄啊?
Kaptcha使用 -
zcs540061627:
wangjian95 写道我也遇到了这个问题
2012-7-1 ...
hessian异常 -
wangjian95:
哈哈,哥刚试了,数组是可以的,嘎嘎
hessian异常
spring的jdbctemplate提供的方案:
jdbctemplate中执行的相关源码
查看相关PreparedStatement对象的具体执行源码
查看jdbc的Connection源码
经过MysqlIo对象的处理,最后封装一个包含updateCount和updateID两个主要数据的ResultSet对象
回到PreparedStatement对象的executeUpdate方法
再回到jdbctemplate源码的update方法,第一步:通过PreparedStatement对象先执行相关sql 【这部分执行已经完成,得到的ResultSet对象值已经交给ps对象】
然后通过ps对象ps.getGeneratedKeys()获得generateKeys的值,具体处理在PreparedStatement父类Statement对象中
KeyHolder keyHolder = new GeneratedKeyHolder(); int updatecount = jdbcTemplate.update(new PreparedStatementCreator() { @Override public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { PreparedStatement ps = (PreparedStatement) connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); return ps; } }, keyHolder); long id = keyHolder.getKey().longValue();
jdbctemplate中执行的相关源码
public int update(PreparedStatementCreator psc, final KeyHolder generatedKeyHolder) throws DataAccessException { Assert.notNull(generatedKeyHolder, "KeyHolder must not be null"); logger.debug("Executing SQL update and returning generated keys"); Integer result = (Integer)execute(psc, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { //第一步:通过PreparedStatement对象先执行相关sql int rows = ps.executeUpdate(); List generatedKeys = generatedKeyHolder.getKeyList(); generatedKeys.clear(); //第二步:通过同一个PreparedStatement取得产生的auto-generated keys ResultSet keys = ps.getGeneratedKeys(); if(keys != null) try { RowMapper rowMapper = getColumnMapRowMapper(); RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1); //解析取得的ResultSet,放入到holder对象的,供我们的应用程序使用 generatedKeys.addAll((List)rse.extractData(keys)); } finally { JdbcUtils.closeResultSet(keys); } if(JdbcTemplate.this.this$0.isDebugEnabled()) JdbcTemplate.this.this$0.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys"); return new Integer(rows); } { super(); } } ); return result.intValue(); }
查看相关PreparedStatement对象的具体执行源码
public int executeUpdate() throws SQLException { return executeUpdate(true, false); } protected int executeUpdate(boolean clearBatchedGeneratedKeysAndWarnings, boolean isBatch) throws SQLException { if(clearBatchedGeneratedKeysAndWarnings) { clearWarnings(); batchedGeneratedKeys = null; } return executeUpdate(parameterValues, parameterStreams, isStream, streamLengths, isNull, isBatch); } protected int executeUpdate(byte batchedParameterStrings[][], InputStream batchedParameterStreams[], boolean batchedIsStream[], int batchedStreamLengths[], boolean batchedIsNull[], boolean isReallyBatch) throws SQLException { checkClosed(); //这个connection就是我们具体使用的连接的对象,具体实现就是jdbc的connection对象 Connection locallyScopedConn = connection; if(locallyScopedConn.isReadOnly()) throw SQLError.createSQLException(Messages.getString("PreparedStatement.34") + Messages.getString("PreparedStatement.35"), "S1009"); if(firstCharOfStmt == 'S' && StringUtils.startsWithIgnoreCaseAndWs(originalSql, "SELECT")) throw SQLError.createSQLException(Messages.getString("PreparedStatement.37"), "01S03"); if(results != null && !locallyScopedConn.getHoldResultsOpenOverStatementClose()) results.realClose(false); com.mysql.jdbc.ResultSet rs = null; synchronized(locallyScopedConn.getMutex()) { Buffer sendPacket = fillSendPacket(batchedParameterStrings, batchedParameterStreams, batchedIsStream, batchedStreamLengths); String oldCatalog = null; if(!locallyScopedConn.getCatalog().equals(currentCatalog)) { oldCatalog = locallyScopedConn.getCatalog(); locallyScopedConn.setCatalog(currentCatalog); } if(locallyScopedConn.useMaxRows()) locallyScopedConn.execSQL(this, "SET OPTION SQL_SELECT_LIMIT=DEFAULT", -1, null, 1003, 1007, false, currentCatalog, true); boolean oldInfoMsgState = false; if(retrieveGeneratedKeys) { oldInfoMsgState = locallyScopedConn.isReadInfoMsgEnabled(); locallyScopedConn.setReadInfoMsgEnabled(true); } //内部方法,执行得到ResultSet对象,executeInternal方法调用传入的connection对象的execSQL方法完成数据库操作并得到返回的ResultSet对象 rs = executeInternal(-1, sendPacket, false, false, true, null, isReallyBatch); if(retrieveGeneratedKeys) { locallyScopedConn.setReadInfoMsgEnabled(oldInfoMsgState); rs.setFirstCharOfQuery(firstCharOfStmt); } if(oldCatalog != null) locallyScopedConn.setCatalog(oldCatalog); } results = rs; updateCount = rs.getUpdateCount(); int truncatedUpdateCount = 0; if(updateCount > 2147483647L) truncatedUpdateCount = 2147483647; else truncatedUpdateCount = (int)updateCount; lastInsertId = rs.getUpdateID(); return truncatedUpdateCount; }
查看jdbc的Connection源码
com.mysql.jdbc.ResultSet execSQL(com.mysql.jdbc.Statement callingStatement, String sql, int maxRows, Buffer packet, int resultSetType, int resultSetConcurrency, boolean streamResults, String catalog, boolean unpackFields, boolean isBatch) throws SQLException{ ... //关键执行语句,this.io是一个jdbc的mysqlio对象 return this.io.sqlQueryDirect(callingStatement, null, null, packet, maxRows, this, resultSetType, resultSetConcurrency, streamResults, catalog, unpackFields);
经过MysqlIo对象的处理,最后封装一个包含updateCount和updateID两个主要数据的ResultSet对象
private com.mysql.jdbc.ResultSet buildResultSetWithUpdates( Statement callingStatement, Buffer resultPacket) throws SQLException { long updateCount = -1; long updateID = -1; String info = null; try { if (this.useNewUpdateCounts) { updateCount = resultPacket.newReadLength(); updateID = resultPacket.newReadLength(); } else { updateCount = resultPacket.readLength(); updateID = resultPacket.readLength(); } if (this.use41Extensions) { this.serverStatus = resultPacket.readInt(); this.warningCount = resultPacket.readInt(); if (this.warningCount > 0) { this.hadWarnings = true; // this is a 'latch', it's reset by sendCommand() } resultPacket.readByte(); // advance pointer if (this.profileSql) { this.queryNoIndexUsed = (this.serverStatus & SERVER_QUERY_NO_GOOD_INDEX_USED) != 0; this.queryBadIndexUsed = (this.serverStatus & SERVER_QUERY_NO_INDEX_USED) != 0; } } if (this.connection.isReadInfoMsgEnabled()) { info = resultPacket.readString(); } } catch (Exception ex) { throw SQLError.createSQLException(SQLError.get( SQLError.SQL_STATE_GENERAL_ERROR) + ": " //$NON-NLS-1$ +ex.getClass().getName(), SQLError.SQL_STATE_GENERAL_ERROR, -1); } ResultSet updateRs = new com.mysql.jdbc.ResultSet(updateCount, updateID, this.connection, callingStatement); if (info != null) { updateRs.setServerInfo(info); } return updateRs; }
回到PreparedStatement对象的executeUpdate方法
//把语句执行得到的结果集交给当前对象 this.results = rs; //更新条数 this.updateCount = rs.getUpdateCount(); int truncatedUpdateCount = 0; if (this.updateCount > Integer.MAX_VALUE) { truncatedUpdateCount = Integer.MAX_VALUE; } else { truncatedUpdateCount = (int) this.updateCount; } //LAST_INSERT_ID值 this.lastInsertId = rs.getUpdateID(); return truncatedUpdateCount;
再回到jdbctemplate源码的update方法,第一步:通过PreparedStatement对象先执行相关sql 【这部分执行已经完成,得到的ResultSet对象值已经交给ps对象】
然后通过ps对象ps.getGeneratedKeys()获得generateKeys的值,具体处理在PreparedStatement父类Statement对象中
public ResultSet getGeneratedKeys() throws SQLException { if(batchedGeneratedKeys == null) { return getGeneratedKeysInternal(); } else { Field fields[] = new Field[1]; fields[0] = new Field("", "GENERATED_KEY", -5, 17); fields[0].setConnection(connection); return new com.mysql.jdbc.ResultSet(currentCatalog, fields, new RowDataStatic(batchedGeneratedKeys), connection, this); } } protected ResultSet getGeneratedKeysInternal() throws SQLException { Field fields[] = new Field[1]; fields[0] = new Field("", "GENERATED_KEY", -5, 17); fields[0].setConnection(connection); ArrayList rowSet = new ArrayList(); long beginAt = getLastInsertID(); int numKeys = getUpdateCount(); if(results != null) { String serverInfo = results.getServerInfo(); if(numKeys > 0 && results.getFirstCharOfQuery() == 'R' && serverInfo != null && serverInfo.length() > 0) numKeys = getRecordCountFromInfo(serverInfo); if(beginAt > 0L && numKeys > 0) { //根据更新条数会累加LastInsertID的值,因为在插入多条的时候只会默认返回第一条执行后产生的ID for(int i = 0; i < numKeys; i++) { byte row[][] = new byte[1][]; row[0] = Long.toString(beginAt++).getBytes(); rowSet.add(row); } } } return new com.mysql.jdbc.ResultSet(currentCatalog, fields, new RowDataStatic(rowSet), connection, this); }
发表评论
-
xmemcached 一致性hash
2012-12-11 18:22 0应用中使用xmemcached做为memcached的客户端, ... -
spring mvc 内存泄露
2012-12-11 16:30 4573有一个项目使用了spring mvc,以前因为各种原因一两个月 ... -
spring mvc annotation-driven
2012-11-08 12:03 2418使用spring mvc时,我们会在配置文件里添加<mv ... -
hessian spring overloadEnabled
2012-11-06 17:40 2615用spring+hessian构建远程服务,遇到有的服务接口存 ... -
hessian http response code:411
2012-11-06 17:31 4783记录一个很久以前的遇到的一个关于hessian的问题。 用 ... -
htmlunit抓取小说网站JS加载内容
2012-10-31 13:25 6636http://www.17k.com/chapter/76 ... -
spring mvc请求映射关系处理
2012-01-04 18:05 78651:看DispatcherServlet的初始化策略 pr ... -
spring mvc异常处理设置
2011-12-09 16:23 21832最近使用spring mvc开发一个web系统,发现在cont ... -
取得用户IP地址
2011-11-17 12:45 1311public static String getIpAdd ... -
泛型类的编译导致的错误
2011-10-25 16:16 1362这是前段时间遇到的一个问题,确定是因为泛型编译导致的,但是特别 ... -
mysql变更AUTO_INCREMENT值
2011-10-24 17:54 1753数据库中id的值 mysql> select * ... -
Kaptcha使用
2011-08-11 18:32 12162简单的装备起来很简单,网上一大把,就不说了。 但是许多时候因为 ... -
spring-JavaMailSenderImpl
2011-07-12 16:11 2823使用spring的JavaMailSenderImpl J ... -
分库主键设计-Mysql
2011-07-06 18:21 3130常见的两种方案,遍布网络: 第一种: replace方案,m ... -
resin容器配置影响listener加载时机
2011-06-08 17:57 1580项目使用resin容器,发现resin容器启动时不加载list ... -
java求质数
2011-04-12 17:19 1411这两天JE求质数的帖子火了好几个哈 先介绍下质数的解释: 就 ... -
spring mvc异常设置
2011-03-17 18:10 15423spring mvc异常设置,做个记录 此段代码ZZ ... -
去除标签段的小代码
2011-03-14 15:45 1068private String removeImg(Str ... -
非注入方式取得spring注入bean的util类实现
2011-03-14 15:07 4793import org.springframework.be ... -
java.util.Set转换为Object[]
2011-03-10 14:49 1238Set<String> set = map.k ...
相关推荐
Spring JDBC通过提供JdbcTemplate和SimpleJdbcTemplate等工具类,帮助开发者以更安全、更易于管理的方式与数据库进行交互,降低了传统JDBC代码的复杂性。下面我们将详细探讨Spring JDBC的核心概念、工作原理以及如何...
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> ``` 其中,`dataSource`是指向数据库连接池的bean,如`Apache Commons DBCP`或`HikariCP`。 ### 4. 创建数据库访问层(DAO)...
1. **JdbcTemplate对象**:这是Spring JdbcTemplate的核心,它包含了执行SQL语句的所有方法,如update()用于更新,query()用于查询,insert()用于插入等。 2. **参数绑定**:JdbcTemplate支持多种方式的参数绑定,...
标题中的"java-web-project.zip_jdbctemplate_js项目_spring jdbctemplate"表明这是一个Java Web项目,使用了Spring框架的JdbcTemplate模块,并且前端部分使用了JavaScript和Ajax技术。这个项目可能是为了演示如何在...
以上就是关于Spring JdbcTemplate的基本介绍及其在实际项目中的应用。由于这个库主要是针对Oracle数据库设计的,所以很多特定的方法可能只适用于Oracle,比如处理lob类型数据、序列或者触发器相关的操作。在使用时,...
SpringJdbcTemplate是Spring框架中用于简化Java数据库访问的工具,它是Spring JDBC模块的核心。这个封装工具类的出现是为了提供一种更简洁、易于使用的接口来执行SQL操作,减轻开发者处理数据库连接、事务管理以及...
使用 Spring JdbcTemplate 调用 Oracle 存储过程实现 CRUD 在本文中,我们将讨论如何使用 Spring JdbcTemplate 调用 Oracle 存储过程来实现 CRUD(Create、Read、Update、Delete)操作。我们将首先编写 Oracle 存储...
SSH整合JdbcTemplate_dao)_方式_总结
3. `spring-jdbc-5.0.0.RELEASE.jar`:包含Spring对JDBC的支持,包括JDBCTemplate和DataSourceTransactionManager,它们是与数据库交互和管理事务的关键。 4. `spring-tx-5.0.0.RELEASE.jar`:提供了事务管理功能,...
在Spring框架中,JdbcTemplate是用于简化数据库操作的重要工具,它是Spring JDBC模块的一部分。通过使用JdbcTemplate,开发者可以避免编写大量的重复代码,如手动管理连接、处理结果集等,从而专注于业务逻辑。本文...
Spring的JdbcTemplate是Spring框架中用于简化数据库操作的工具类,它是基于JDBC但又抽象出了一层,避免了直接与数据库驱动API交互,从而提高了代码的可读性和可维护性。本文将深入探讨Spring JdbcTemplate的常用方法...
Druid数据库连接池的SpringJDBCTemplate所需的jar包,Druid数据库连接池的SpringJDBCTemplate所需的jar包,Druid数据库连接池的SpringJDBCTemplate所需的jar包,Druid数据库连接池的SpringJDBCTemplate所需的jar包,...
Struts2、Spring和Spring JDBC Template是Java Web开发中常用的三个框架,它们分别负责不同的职责。Struts2作为MVC(Model-View-Controller)框架,主要处理前端请求和业务逻辑;Spring则是一个全面的后端框架,提供...
Spring JdbcTemplate是Spring框架中的一个核心组件,主要用来简化数据库操作。它提供了一种模板方法设计模式,将SQL语句的执行与结果处理进行了抽象,使得开发者可以更加专注于业务逻辑,而无需关心底层数据访问的...
Spring JdbcTemplate是Spring框架中用于简化数据库操作的一个重要组件,它是Spring对JDBC的轻量级封装,旨在提供一种结构良好、易于使用的SQL执行机制,同时保持了JDBC的灵活性。在本实例中,我们将深入探讨Spring ...
模仿spring jdbcTemplate的粗略实现,只有很小的参考价值,如果是java初学者可以使用这个封装好的工具进行数据库操作,只需要在db.properties里配置好driver,url等信息
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> ``` 或者使用Java配置: ```java @Configuration public class AppConfig { @Bean public DataSource dataSource() { ...
在Spring框架中,`JdbcTemplate`是用于简化Java数据库连接(JDBC)操作的一个核心组件。这个类提供了很多方法来执行SQL查询、更新语句,包括批处理操作。本篇文章将详细探讨`batchUpdate`方法及其在实际开发中的应用...