抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

MYBATIS-statement模块

概述

​ StatementHandler负责处理Mybatis与JDBC之间Statement的交互,而JDBC中的Statement,我们在学习JDBC的时候就了解过,就是负责与数据库进行交互的对象。这其中会涉及到一些对象,我们用到的时候再学习。首先,我们来看下StatementHandler的体系结构。

StatementHandler接口

statementHandler接口的实现大致有四个,其中三个实现类都是和JDBC中的Statement响对应的:

  1. SimpleStatementHandler,这个很简单了,就是对应我们JDBC中常用的Statement接口,用于简单SQL的处理;
  2. PreparedStatementHandler,这个对应JDBC中的PreparedStatement,预编译SQL的接口;
  3. CallableStatementHandler,这个对应JDBC中CallableStatement,用于执行存储过程相关的接口;
  4. RoutingStatementHandler,这个接口是以上三个接口的路由,没有实际操作,只是负责上面三个StatementHandler的创建及调用。
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
* @author Clinton Begin
*/
public interface StatementHandler {
/**
* 从connection中获取statement
*
* @param connection
* @param transactionTimeout
* @return
* @throws SQLException
*/
Statement prepare(Connection connection, Integer transactionTimeout)
throws SQLException;

/**
* sql参数设置
*
* @param statement
* @throws SQLException
*/
void parameterize(Statement statement)
throws SQLException;

/**
* 批量执行
*
* @param statement
* @throws SQLException
*/
void batch(Statement statement)
throws SQLException;

/**
* 更新
*
* @param statement
* @return
* @throws SQLException
*/
int update(Statement statement)
throws SQLException;

/**
* 查询
*
* @param statement
* @param resultHandler
* @param <E>
* @return
* @throws SQLException
*/
<E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException;

/**
* 游标查询
*
* @param statement
* @param <E>
* @return
* @throws SQLException
*/
<E> Cursor<E> queryCursor(Statement statement)
throws SQLException;

/*
获取BoundSql
*/
BoundSql getBoundSql();

/**
* 获取参数处理器
*
* @return
*/
ParameterHandler getParameterHandler();

}

RoutingStatementHandler

RoutingStatementHandler类似路由器,在其构造函数中会根据Mapper文件中设置的StatementType来选择使用SimpleStatementHandler、PreparedStatementHandler和CallableStatementHandler,其实现的接口StatementHandler的方法也是由这三个具体实现类来实现。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

/**
* 路由Statement处理器
* 装饰器模式
*
* @author Clinton Begin
*/
public class RoutingStatementHandler implements StatementHandler {
/**
* 装饰器的StatementHandler
*/
private final StatementHandler delegate;

/**
* 构造方法
* 选择三种Statement,SimpleStatementHandler、PreparedStatementHandler和CallableStatementHandler
*
* @param executor
* @param ms
* @param parameter
* @param rowBounds
* @param resultHandler
* @param boundSql
*/
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
//根据Statement类型选择不同的处理器
switch (ms.getStatementType()) {
//STATEMENT类型
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
//预处理类型
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
//存储过程类型
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}

}

/**
* 执行具体类型prepare
*
* @param connection
* @param transactionTimeout
* @return
* @throws SQLException
*/
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
return delegate.prepare(connection, transactionTimeout);
}

@Override
public void parameterize(Statement statement) throws SQLException {
delegate.parameterize(statement);
}

@Override
public void batch(Statement statement) throws SQLException {
delegate.batch(statement);
}

@Override
public int update(Statement statement) throws SQLException {
return delegate.update(statement);
}

@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return delegate.query(statement, resultHandler);
}

@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
return delegate.queryCursor(statement);
}

@Override
public BoundSql getBoundSql() {
return delegate.getBoundSql();
}

@Override
public ParameterHandler getParameterHandler() {
return delegate.getParameterHandler();
}
}

BaseStatementHandler类

BaseStatementHandler是一个抽象类,并没有实现和CURD相关的类,只是更多的设置了一些参数相关。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/**
* @author Clinton Begin
*/
public abstract class BaseStatementHandler implements StatementHandler {
//配置信息
protected final Configuration configuration;
//对象工厂
protected final ObjectFactory objectFactory;
//类型处理器注册
protected final TypeHandlerRegistry typeHandlerRegistry;
//结果集处理
protected final ResultSetHandler resultSetHandler;
//参数处理器
protected final ParameterHandler parameterHandler;
//执行器
protected final Executor executor;
protected final MappedStatement mappedStatement;
protected final RowBounds rowBounds;

protected BoundSql boundSql;

/**
* 构造方法
*
* @param executor
* @param mappedStatement
* @param parameterObject
* @param rowBounds
* @param resultHandler
* @param boundSql
*/
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
this.configuration = mappedStatement.getConfiguration();
this.executor = executor;
this.mappedStatement = mappedStatement;
this.rowBounds = rowBounds;
//从配置信息中获取类型处理器注册器
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
//从配置信息中获取对象工厂
this.objectFactory = configuration.getObjectFactory();
//处理sql之前生成key
if (boundSql == null) { // issue #435, get the key before calculating the statement
generateKeys(parameterObject);
boundSql = mappedStatement.getBoundSql(parameterObject);
}

this.boundSql = boundSql;
//创建参数处理器
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
//创建结果集处理器
this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
}

/**
* 获取boundSql
*
* @return
*/
@Override
public BoundSql getBoundSql() {
return boundSql;
}

/**
* 获取参数处理器
*
* @return
*/
@Override
public ParameterHandler getParameterHandler() {
return parameterHandler;
}

/**
* 从连接中获取Statement对象
*
* @param connection
* @param transactionTimeout
* @return
* @throws SQLException
*/
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
statement = instantiateStatement(connection);
//设置超时时间
setStatementTimeout(statement, transactionTimeout);
//设置读取条数,其实就是调用Statement.setFetchSize
setFetchSize(statement);
return statement;
} catch (SQLException e) {
closeStatement(statement);
throw e;
} catch (Exception e) {
closeStatement(statement);
throw new ExecutorException("Error preparing statement. Cause: " + e, e);
}
}

/**
* 如何实例化Statement,交给子类去做
* @param connection
* @return
* @throws SQLException
*/
protected abstract Statement instantiateStatement(Connection connection) throws SQLException;

/**
* 设置超时,实际就是调用Statement.setQueryTimeout
*
* @param stmt
* @param transactionTimeout
* @throws SQLException
*/
protected void setStatementTimeout(Statement stmt, Integer transactionTimeout) throws SQLException {
Integer queryTimeout = null;
if (mappedStatement.getTimeout() != null) {
queryTimeout = mappedStatement.getTimeout();
} else if (configuration.getDefaultStatementTimeout() != null) {
queryTimeout = configuration.getDefaultStatementTimeout();
}
if (queryTimeout != null) {
stmt.setQueryTimeout(queryTimeout);
}
StatementUtil.applyTransactionTimeout(stmt, queryTimeout, transactionTimeout);
}

/**
* 设置读取条数,其实就是调用Statement.setFetchSize
*
* @param stmt
* @throws SQLException
*/
protected void setFetchSize(Statement stmt) throws SQLException {
Integer fetchSize = mappedStatement.getFetchSize();
if (fetchSize != null) {
stmt.setFetchSize(fetchSize);
return;
}
Integer defaultFetchSize = configuration.getDefaultFetchSize();
if (defaultFetchSize != null) {
stmt.setFetchSize(defaultFetchSize);
}
}

/**
* 关闭Statement
*
* @param statement
*/
protected void closeStatement(Statement statement) {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
//ignore
}
}

/**
* 生成主键
*
* @param parameter
*/
protected void generateKeys(Object parameter) {
//获取主键生成器
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
ErrorContext.instance().store();
//生成主键
keyGenerator.processBefore(executor, mappedStatement, null, parameter);
ErrorContext.instance().recall();
}
}

SimpleStatementHandler类

SimpleStatementHandler就是使用基本的Statement来执行query、batch、update等操作,其实现还是比较简单的,当然在执行过程中会涉及keyGenerator和ResultHandler操作。SimpleStatementHandler用于执行简单的sql语句,这里简单的sql语句是指sql语句中没有变量,不会通过外部进行参数传入的sql语句。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

/**
* 简单Statement处理器
*
* @author Clinton Begin
*/
public class SimpleStatementHandler extends BaseStatementHandler {
/**
* 构造方法
*
* @param executor
* @param mappedStatement
* @param parameter
* @param rowBounds
* @param resultHandler
* @param boundSql
*/
public SimpleStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}

/**
* 更新操作
*
* @param statement
* @return
* @throws SQLException
*/
@Override
public int update(Statement statement) throws SQLException {
//获取sql
String sql = boundSql.getSql();
//获取参数
Object parameterObject = boundSql.getParameterObject();
//获取主键生成器
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
//操作行数
int rows;
//
if (keyGenerator instanceof Jdbc3KeyGenerator) {
//执行sql
statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
//获取更新条数
rows = statement.getUpdateCount();
//获取执行后的主键
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else if (keyGenerator instanceof SelectKeyGenerator) {
//执行sql
statement.execute(sql);
//获取执行行数
rows = statement.getUpdateCount();
//获取执行后的主键
keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
} else {
//如果没有keyGenerator,直接调用Statement.execute和Statement.getUpdateCount
statement.execute(sql);
rows = statement.getUpdateCount();
}
return rows;
}

/**
* 批量sql执行
*
* @param statement
* @throws SQLException
*/
@Override
public void batch(Statement statement) throws SQLException {
//获取sql
String sql = boundSql.getSql();
//添加批处理sql
statement.addBatch(sql);
}

/**
* 查询
* @param statement
* @param resultHandler
* @param <E>
* @return
* @throws SQLException
*/
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
//获取sql
String sql = boundSql.getSql();
//执行sql
statement.execute(sql);
//由结果处理器来处理结果
return resultSetHandler.handleResultSets(statement);
}

/**
* 游标查询
* @param statement
* @param <E>
* @return
* @throws SQLException
*/
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
//获取sql
String sql = boundSql.getSql();
//执行sql
statement.execute(sql);
//由结果集处理器处理游标数据
return resultSetHandler.handleCursorResultSets(statement);
}

/**
* 实例化Statement实现
* @param connection
* @return
* @throws SQLException
*/
@Override
protected Statement instantiateStatement(Connection connection) throws SQLException {
//如果是默认的结果集
if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
//直接创建Statement
return connection.createStatement();
} else {
//其他情况创建具体类型的Statement
return connection.createStatement(mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
}
}

/**
* 简单处理器不处理参数
* @param statement
*/
@Override
public void parameterize(Statement statement) {
// N/A
}

}

PreparedStatementHandler类

PreparedStatementHandler就是调用PreparedStatement来执行SQL语句,这样在第一次执行sql语句时会进行预编译,在接下来执行相同的SQL语句时会提高数据库性能

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* 预处理Statement处理器
*
* @author Clinton Begin
*/
public class PreparedStatementHandler extends BaseStatementHandler {
/**
* 构造方法
*
* @param executor
* @param mappedStatement
* @param parameter
* @param rowBounds
* @param resultHandler
* @param boundSql
*/
public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}

/**
* 更新操作
*
* @param statement
* @return
* @throws SQLException
*/
@Override
public int update(Statement statement) throws SQLException {
//转换成预编译的PreparedStatement
PreparedStatement ps = (PreparedStatement) statement;
//执行
ps.execute();
//获取执行行数
int rows = ps.getUpdateCount();
//获取参数
Object parameterObject = boundSql.getParameterObject();
//获取主键生成器
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
//设置主键
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}

/**
* 批量处理
*
* @param statement
* @throws SQLException
*/
@Override
public void batch(Statement statement) throws SQLException {
//转换成预编译的PreparedStatement
PreparedStatement ps = (PreparedStatement) statement;
//添加到批处理
ps.addBatch();
}

/**
* 查询操作
*
* @param statement
* @param resultHandler
* @param <E>
* @return
* @throws SQLException
*/
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
//转换成预编译的PreparedStatement
PreparedStatement ps = (PreparedStatement) statement;
//执行查询
ps.execute();
//交给结果集处理器处理
return resultSetHandler.handleResultSets(ps);
}

//游标查询
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
//转换成预编译的PreparedStatement
PreparedStatement ps = (PreparedStatement) statement;
//执行查询
ps.execute();
//交给结果集处理器处理
return resultSetHandler.handleCursorResultSets(ps);
}

/**
* 实例化Statement
*
* @param connection
* @return
* @throws SQLException
*/
@Override
protected Statement instantiateStatement(Connection connection) throws SQLException {
//获取sql
String sql = boundSql.getSql();
if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
//获取key的数组
String[] keyColumnNames = mappedStatement.getKeyColumns();
//没有key就直接创建prepareStatement
if (keyColumnNames == null) {
return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
} else {
//其他情况创建带有列明的prepareStatement
return connection.prepareStatement(sql, keyColumnNames);
}
//如果结果集类型是默认的
} else if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
//直接创建prepareStatement
return connection.prepareStatement(sql);
} else {
//其他情况根据类型创建prepareStatement
return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
}
}

/**
* 参数处理器处理参数
*
* @param statement
* @throws SQLException
*/
@Override
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}

}

CallableStatementHandler

CallableStatementHandler实际就是使用CallableStatement来执行SQL语句,当然它执行的是存储过程。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
* 存储过程处理器
* @author Clinton Begin
*/
public class CallableStatementHandler extends BaseStatementHandler {
/**
* 构造方法
* @param executor
* @param mappedStatement
* @param parameter
* @param rowBounds
* @param resultHandler
* @param boundSql
*/
public CallableStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}

/**
* 更新操作
* @param statement
* @return
* @throws SQLException
*/
@Override
public int update(Statement statement) throws SQLException {
//将statement转换为CallableStatement
CallableStatement cs = (CallableStatement) statement;
//执行execute操作
cs.execute();
//获取更新行数
int rows = cs.getUpdateCount();
//获取参数
Object parameterObject = boundSql.getParameterObject();
//获取主键生成器
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
//设置主键
keyGenerator.processAfter(executor, mappedStatement, cs, parameterObject);
//结果集进行处理
resultSetHandler.handleOutputParameters(cs);
return rows;
}

/**
* 批量处理
* @param statement
* @throws SQLException
*/
@Override
public void batch(Statement statement) throws SQLException {
//将statement转换为CallableStatement
CallableStatement cs = (CallableStatement) statement;
//添加到批处理
cs.addBatch();
}

/**
* 查询操作
* @param statement
* @param resultHandler
* @param <E>
* @return
* @throws SQLException
*/
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
//将statement转换为CallableStatement
CallableStatement cs = (CallableStatement) statement;
//执行查询
cs.execute();
//通过结果集处理器处理结果
List<E> resultList = resultSetHandler.handleResultSets(cs);
//处理参数
resultSetHandler.handleOutputParameters(cs);
return resultList;
}

/**
* 游标查询
* @param statement
* @param <E>
* @return
* @throws SQLException
*/
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
//将statement转换为CallableStatement
CallableStatement cs = (CallableStatement) statement;
//执行execute操作
cs.execute();
//结果集处理器处理游标数据
Cursor<E> resultList = resultSetHandler.handleCursorResultSets(cs);
//处理输出参数
resultSetHandler.handleOutputParameters(cs);
return resultList;
}

/**
* 实例化Statement
* @param connection
* @return
* @throws SQLException
*/
@Override
protected Statement instantiateStatement(Connection connection) throws SQLException {
//获取sql
String sql = boundSql.getSql();
//如果是默认的结果集处理器
if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
//创建存储过程Statement
return connection.prepareCall(sql);
} else {
//其他情况根据结果集类型创建存储过程Statement
return connection.prepareCall(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
}
}

/**
* 参数设置
* @param statement
* @throws SQLException
*/
@Override
public void parameterize(Statement statement) throws SQLException {
//注册输出参数
registerOutputParameters((CallableStatement) statement);
//参数处理器设置参数
parameterHandler.setParameters((CallableStatement) statement);
}

/**
* 注册输出参数
* @param cs
* @throws SQLException
*/
private void registerOutputParameters(CallableStatement cs) throws SQLException {
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
for (int i = 0, n = parameterMappings.size(); i < n; i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
//处理存储过程的INOUT和OUT
if (parameterMapping.getMode() == ParameterMode.OUT || parameterMapping.getMode() == ParameterMode.INOUT) {
if (null == parameterMapping.getJdbcType()) {
throw new ExecutorException("The JDBC Type must be specified for output parameter. Parameter: " + parameterMapping.getProperty());
} else {
if (parameterMapping.getNumericScale() != null && (parameterMapping.getJdbcType() == JdbcType.NUMERIC || parameterMapping.getJdbcType() == JdbcType.DECIMAL)) {
cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE, parameterMapping.getNumericScale());
} else {
if (parameterMapping.getJdbcTypeName() == null) {
cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE);
} else {
cs.registerOutParameter(i + 1, parameterMapping.getJdbcType().TYPE_CODE, parameterMapping.getJdbcTypeName());
}
}
}
}
}
}

}

评论