javascript
SpringJDBC解析3-回调函数(update为例)
PreparedStatementCallback作為一個(gè)接口,其中只有一個(gè)函數(shù)doInPrepatedStatement,這個(gè)函數(shù)是用于調(diào)用通用方法execute的時(shí)候無(wú)法處理的一些個(gè)性化處理方法,在update中的函數(shù)實(shí)現(xiàn):
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(); } } } }); }其中真正執(zhí)行SQL的ps.executeUpdate并沒(méi)有太多需要講的,但是,對(duì)于設(shè)置輸入?yún)?shù)的函數(shù)pss.setValues(ps),可以分析一下。
在沒(méi)有分析源碼之前,我們至少可以知道其功能,回顧下Spring中使用SQL的執(zhí)行過(guò)程,直接使用:
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語(yǔ)句對(duì)應(yīng)的參數(shù),對(duì)應(yīng)參數(shù)的類型清晰明了,這都?xì)w功于Spring為我們做了封裝,而真正的JDBC調(diào)用其實(shí)非常繁瑣,你需要這么做:
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)為入口的。這個(gè)pss所代表的正式ArgumentTypePreparedStatementSetter。其中的setValues如下:
public void setValues(PreparedStatement ps) throws SQLException { int parameterPosition = 1; if (this.args != null) { //遍歷每個(gè)參數(shù)以作類型匹配及轉(zhuǎn)換 for (int i = 0; i < this.args.length; i++) { Object arg = this.args[i]; //如果是集合類則需要進(jìn)入集合類內(nèi)部遞歸解析集合內(nè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 { //解析當(dāng)前屬性 doSetValue(ps, parameterPosition, this.argTypes[i], arg); parameterPosition++; } } } }對(duì)單個(gè)參數(shù)及類型的匹配處理:
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); } }?
?
總結(jié)
以上是生活随笔為你收集整理的SpringJDBC解析3-回调函数(update为例)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 基于物品的协同过滤推荐算法_《推荐系统实
- 下一篇: mysql数据版本控制_如何对MySQL