SpringJDBC解析3-回调函数(update为例)

PreparedStatementCallback作为一个接口,其中只有一个函数doInPrepatedStatement,这个函数是用于调用通用方法execute的时候无法处理的一些个性化处理方法,在update中的函数实现:

protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss)  throws DataAccessException {  logger.debug("Executing prepared SQL update");  return execute(psc, new PreparedStatementCallback<Integer>() {  public Integer doInPreparedStatement(PreparedStatement ps) throws SQLException {  try {  if (pss != null) {  pss.setValues(ps);  }  int rows = ps.executeUpdate();  if (logger.isDebugEnabled()) {  logger.debug("SQL update affected " + rows + " rows");  }  return rows;  }  finally {  if (pss instanceof ParameterDisposer) {  ((ParameterDisposer) pss).cleanupParameters();  }  }  }  });  
}  

其中真正执行SQL的ps.executeUpdate并没有太多需要讲的,但是,对于设置输入参数的函数pss.setValues(ps),可以分析一下。

在没有分析源码之前,我们至少可以知道其功能,回顾下Spring中使用SQL的执行过程,直接使用:

jdbcTemplate.update("insert into user(name,age,sex)values(?,?,?)",

new Object[] { user.getName(), user.getAge(),user.getSex() },

new int[] { java.sql.Types.VARCHAR,java.sql.Types.INTEGER, java.sql.Types.VARCHAR });

SQL语句对应的参数,对应参数的类型清晰明了,这都归功于Spring为我们做了封装,而真正的JDBC调用其实非常繁琐,你需要这么做:

PreparedStatement updateSales = con.prepareStatement("insert into user(name,age, sex)values(?,?,?)");

updateSales.setString(1, user.getName());

updateSales.setInt(2, user.getAge());

updateSales.setString(3, user.getSex());

那么看看Spring是如何做到封装上面的操作呢?首先,所有的操作都是以pss.setValues(ps)为入口的。这个pss所代表的正式ArgumentTypePreparedStatementSetter。其中的setValues如下:

public void setValues(PreparedStatement ps) throws SQLException {  int parameterPosition = 1;  if (this.args != null) {  //遍历每个参数以作类型匹配及转换  for (int i = 0; i < this.args.length; i++) {  Object arg = this.args[i];  //如果是集合类则需要进入集合类内部递归解析集合内部属性  if (arg instanceof Collection && this.argTypes[i] != Types.ARRAY) {  Collection entries = (Collection) arg;  for (Object entry : entries) {  if (entry instanceof Object[]) {  Object[] valueArray = ((Object[]) entry);  for (Object argValue : valueArray) {  doSetValue(ps, parameterPosition, this.argTypes[i], argValue);  parameterPosition++;  }  }  else {  doSetValue(ps, parameterPosition, this.argTypes[i], entry);  parameterPosition++;  }  }  }  else {  //解析当前属性  doSetValue(ps, parameterPosition, this.argTypes[i], arg);  parameterPosition++;  }  }  }  
}

对单个参数及类型的匹配处理:

private static void setParameterValueInternal(PreparedStatement ps, int paramIndex, int sqlType,  String typeName, Integer scale, Object inValue) throws SQLException {  String typeNameToUse = typeName;  int sqlTypeToUse = sqlType;  Object inValueToUse = inValue;  // override type info?  if (inValue instanceof SqlParameterValue) {  SqlParameterValue parameterValue = (SqlParameterValue) inValue;  if (logger.isDebugEnabled()) {  logger.debug("Overriding type info with runtime info from SqlParameterValue: column index " + paramIndex +  ", SQL type " + parameterValue.getSqlType() + ", type name " + parameterValue.getTypeName());  }  if (parameterValue.getSqlType() != SqlTypeValue.TYPE_UNKNOWN) {  sqlTypeToUse = parameterValue.getSqlType();  }  if (parameterValue.getTypeName() != null) {  typeNameToUse = parameterValue.getTypeName();  }  inValueToUse = parameterValue.getValue();  }  if (logger.isTraceEnabled()) {  logger.trace("Setting SQL statement parameter value: column index " + paramIndex +  ", parameter value [" + inValueToUse +  "], value class [" + (inValueToUse != null ? inValueToUse.getClass().getName() : "null") +  "], SQL type " + (sqlTypeToUse == SqlTypeValue.TYPE_UNKNOWN ? "unknown" : Integer.toString(sqlTypeToUse)));  }  if (inValueToUse == null) {  setNull(ps, paramIndex, sqlTypeToUse, typeNameToUse);  }  else {  setValue(ps, paramIndex, sqlTypeToUse, typeNameToUse, scale, inValueToUse);  }  
}  

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python上下文管理器

DAY 23. python上下文管理器 Python 的 with 语句支持通过上下文管理器所定义的运行时上下文这一概念。 此对象的实现使用了一对专门方法&#xff0c;允许用户自定义类来定义运行时上下文&#xff0c;在语句体被执行前进入该上下文&#xff0c;并在语句执行完毕时退出该上下文&…

勾股定理python思路_趣叮咚编程数学揭秘:为什么勾股定理a+b=c?

我们都知道&#xff1a;三角形3个外角之和360度可是谁知道为什么等于360度呢&#xff1f;其实利用编程制作动图演绎了解啦&#xff1a;那勾股定理abc又是为什么呢&#xff1f;还有很多有趣的数学公式都可以演绎&#xff1a;圆的面积公式、圆周长...通过动图演绎原来晦涩难懂的定…

System.InvalidOperationException : 不应有 Response xmlns=''。

xml如下&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <Response version"2"><datacash_reference>4700203048783633</datacash_reference><information>Failed to identify the card scheme of the supp…

Navicat Premium连接SQL Server

Navicat Premium连接SQL Server 步骤&#xff1a; 激活SQL Server 服务配置SQL Server网络配置连接SQL Server 激活SQLServer服务 直接搜索 计算机管理 点 服务和应用程序&#xff0c; 点 SQL Server配置管理器&#xff0c; 双击第一个SQL Server服务 不出意外的话&#xf…

mysql 单标递归_MySql8 WITH RECURSIVE递归查询父子集的方法

背景开发过程中遇到类似评论的功能是&#xff0c;需要时用查询所有评论的子集。不同数据库中实现方式也不同&#xff0c;本文使用Mysql数据库&#xff0c;版本为8.0Oracle数据库中可使用START [Param] CONNECT BY PRIORMysql 中需要使用 WITH RECURSIVE需求找到name为张三的孩子…

processon完全装逼指南

一、引言 作为一名IT从业者&#xff0c;不仅要有扎实的知识储备&#xff0c;出色的业务能力&#xff0c;还需要具备一定的软实力。软实力体现在具体事务的处理能力&#xff0c;包括沟通&#xff0c;协作&#xff0c;团队领导&#xff0c;问题的解决方案等&#xff0c;这些能力在…

mysql在空闲8小时之后会断开连接(默认情况)

调试程序的过程发现&#xff0c;在mysql连接空闲一定时间&#xff08;默认8小时&#xff09;之后会断开连接&#xff0c;需要重新连接&#xff0c;也引发我对重连机制的思考。转载于:https://www.cnblogs.com/ppzbty/p/5707576.html

selector多路复用_多路复用器Selector

Unix系统有五种IO模型分别是阻塞IO(blocking IO)&#xff0c;非阻塞IO( non-blocking IO)&#xff0c;IO多路复用(IO multiplexing)&#xff0c;信号驱动(SIGIO/Signal IO)和异步IO(Asynchronous IO)。而IO多路复用通常有select&#xff0c;poll&#xff0c;epoll&#xff0c;k…

解决svn log显示no author,no date的方法之一

只要把svnserve.conf中的anon-access read 的read 改为none&#xff0c;也不需要重启svnserve就行 sh-4.1# grep "none" /var/www/html/svn/pro/conf/svnserve.conf ### and "none". The sample settings below are the defaults. anon-access none转载…

REST framework 权限管理源码分析

REST framework 权限管理源码分析 同认证一样&#xff0c;dispatch()作为入口&#xff0c;从self.initial(request, *args, **kwargs)进入initial() def initial(self, request, *args, **kwargs):# .......# 用户认证self.perform_authentication(request)# 权限控制self.che…

解决larave-dompdf中文字体显示问题

0、使用MPDF dompdf个人感觉没有那么好用&#xff0c;最终的生产环境使用的是MPDF&#xff0c;github上有文档说明。如果你坚持使用&#xff0c;下面是解决办法。可以明确的说&#xff0c;中文乱码是可以解决的。 1、安装laravel-dompdf依赖。 Packagist&#xff1a;https://pa…

mfc程序转化为qt_小峰的QT学习笔记

我的专业是输电线路&#xff0c;上个学期&#xff0c;我们开了一门架空线路设计基础的课&#xff0c;当时有一个大作业是计算线路的比载&#xff0c;临界档距&#xff0c;弧垂最低点和安装曲线。恰逢一门结课考试结束&#xff0c;大作业ddl快到&#xff0c;我和另外两个同专业的…

MS SQL的存储过程

-- -- Author: -- Create date: 2016-07-01 -- Description: 注册信息 -- ALTER PROCEDURE [dbo].[sp_MebUser_Register]( UserType INT, MobileNumber VARCHAR(11), MobileCode VARCHAR(50), LoginPwd VARCHAR(50), PayPwd VARCHAR(50), PlateNumber VARCHAR(20), UserTr…

mysql 中 all any some 用法

-- 建表语句 CREATE TABLE score(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),SUBJECT VARCHAR(20),score INT);-- 添加数据 INSERT INTO score VALUES (NULL,张三,语文,81), (NULL,张三,数学,75), (NULL,李四,语文,76), (NULL,李四,数学,90), (NULL,王五,语文,81), (…

REST framework 用户认证源码

REST 用户认证源码 在Django中&#xff0c;从URL调度器中过来的HTTPRequest会传递给disatch(),使用REST后也一样 # REST的dispatch def dispatch(self, request, *args, **kwargs):""".dispatch() is pretty much the same as Djangos regular dispatch,but w…

scrapyd部署_如何通过 Scrapyd + ScrapydWeb 简单高效地部署和监控分布式爬虫项目

来自 Scrapy 官方账号的推荐需求分析初级用户&#xff1a;只有一台开发主机能够通过 Scrapyd-client 打包和部署 Scrapy 爬虫项目&#xff0c;以及通过 Scrapyd JSON API 来控制爬虫&#xff0c;感觉 命令行操作太麻烦 &#xff0c;希望能够通过浏览器直接部署和运行项目专业用…

最长上升子序列 (LIS算法(nlong(n)))

设 A[t]表示序列中的第t个数&#xff0c;F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度&#xff0c;初始时设F [t] 0(t 1, 2, ..., len(A))。则有动态规划方程&#xff1a;F[t] max{1, F[j] 1} (j 1, 2, ..., t - 1, 且A[j] < A[t])。 现在&#xff0c;我们仔细…

牛顿插值--python实现

from tabulate import tabulate import sympy""" 牛顿插值法 """class NewtonInterpolation:def __init__(self, x: list, y: list):self.Xi = xself

css摇曳的_HTML5+CSS3实现树被风吹动摇晃

1新建html文档。2书写hmtl代码。3书写css代码。.trunk, .trunk div { background: #136086; width: 100px; height: 10px; position: absolute; left: 50%; top: 70%; margin-left: -10px; -webkit-animation-name: rot; animation-name: rot; -webkit-animation-duration: 2.0…

素数路(prime)

素数路(prime) 题目描述 已知一个四位的素数&#xff0c;要求每次修改其中的一位&#xff0c;并且要保证修改的结果还是一个素数&#xff0c;还不能出现前导零。你要找到一个修改数最少的方案&#xff0c;得到我们所需要的素数。 例如把1033变到8179&#xff0c;这里是一个最短…