下面列出了org.apache.ibatis.annotations.Update#org.apache.ibatis.mapping.StatementType 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public MappedStatement parseStatement(Configuration configuration, Method method,
Class<?> targetClass) {
String resourceName = targetClass.toString();
if (!configuration.isResourceLoaded(resourceName)) {
configuration.addLoadedResource(resourceName);
}
String targetClassName = targetClass.getName();
Class<?> type = super.recognizeEntityType(method, targetClass);
LanguageDriver languageDriver = Constant.XML_LANGUAGE_DRIVER;
SqlSource sqlSource = languageDriver
.createSqlSource(configuration, "<script> " + parseSQL(method, type) + "</script>",
Object.class);
String statementId = targetClassName + "." + method.getName();
MappedStatement.Builder builder = new MappedStatement.Builder(configuration, statementId,
sqlSource, SqlCommandType.UPDATE);
builder.resource(super.recognizeResource(targetClassName)).lang(languageDriver)
.statementType(StatementType.PREPARED);
return builder.build();
}
protected void addMappedStatement(String id, String[] sqls,
SqlCommandType sqlCommandType, Class<?> parameterType, String resultMap,
Class<?> resultType, KeyGenerator keyGenerator, String keyProperty,
String keyColumn) {
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = !isSelect;
boolean useCache = isSelect;
addMappedStatement(id, buildSqlSourceFromStrings(sqls, parameterType),
StatementType.PREPARED, sqlCommandType, null, null, null, parameterType,
resultMap, resultType, null, flushCache, useCache, false, keyGenerator,
keyProperty, keyColumn, null, getLanguageDriver(), null);
if (log.isDebugEnabled()) {
System.out.println("/*【" + this.assistant.getCurrentNamespace() + '.' + id
+ "】ResultMap=" + resultMap + " */");
System.out.println((sqls.length > 1 ? sqls[1] : sqls[0]) + ";\n");
}
}
private void handleLocallyCachedOutputParameters(MappedStatement ms, CacheKey key, Object parameter, BoundSql boundSql) {
//处理存储过程的OUT参数
if (ms.getStatementType() == StatementType.CALLABLE) {
final Object cachedParameter = localOutputParameterCache.getObject(key);
if (cachedParameter != null && parameter != null) {
final MetaObject metaCachedParameter = configuration.newMetaObject(cachedParameter);
final MetaObject metaParameter = configuration.newMetaObject(parameter);
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
final String parameterName = parameterMapping.getProperty();
final Object cachedValue = metaCachedParameter.getValue(parameterName);
metaParameter.setValue(parameterName, cachedValue);
}
}
}
}
}
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
//先向缓存中放入占位符???
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
//最后删除占位符
localCache.removeObject(key);
}
//加入缓存
localCache.putObject(key, list);
//如果是存储过程,OUT参数也加入缓存
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
}
public static MappedStatement prepareSelectAuthorViaOutParams(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectAuthorViaOutParams", new StaticSqlSource(config, "{call selectAuthorViaOutParams(?,?,?,?,?)}"), SqlCommandType.SELECT)
.statementType(StatementType.CALLABLE)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>() {
{
add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
}
}).build())
.resultMaps(new ArrayList<ResultMap>())
.cache(authorCache).build();
return ms;
}
public static MappedStatement createSelectAuthorWithIDof99MappedStatement(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectAuthor", new StaticSqlSource(config,"SELECT * FROM author WHERE id = 99"), SqlCommandType.SELECT)
.statementType(StatementType.STATEMENT)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class, new ArrayList<ParameterMapping>()).build())
.resultMaps(new ArrayList<ResultMap>() {
{
add(new ResultMap.Builder(config, "defaultResultMap", Author.class, new ArrayList<ResultMapping>() {
{
add(new ResultMapping.Builder(config, "id", "id", registry.getTypeHandler(int.class)).build());
add(new ResultMapping.Builder(config, "username", "username", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "password", "password", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "email", "email", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "bio", "bio", registry.getTypeHandler(String.class)).build());
}
}).build());
}
}).build();
return ms;
}
private void bindingLog(Invocation invocation) throws SQLException {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameterObject = args[1];
StatementType statementType = ms.getStatementType();
if (StatementType.PREPARED == statementType || StatementType.CALLABLE == statementType) {
Log statementLog = ms.getStatementLog();
if (isDebugEnable(statementLog)) {
BoundSql boundSql = ms.getBoundSql(parameterObject);
String sql = boundSql.getSql();
List<String> parameterList = getParameters(ms, parameterObject, boundSql);
debug(statementLog, "==> BindingLog: " + bindLogFormatter.format(sql, parameterList));
}
}
}
private void handleLocallyCachedOutputParameters(MappedStatement ms, CacheKey key, Object parameter, BoundSql boundSql) {
//处理存储过程的OUT参数
if (ms.getStatementType() == StatementType.CALLABLE) {
final Object cachedParameter = localOutputParameterCache.getObject(key);
if (cachedParameter != null && parameter != null) {
final MetaObject metaCachedParameter = configuration.newMetaObject(cachedParameter);
final MetaObject metaParameter = configuration.newMetaObject(parameter);
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
final String parameterName = parameterMapping.getProperty();
final Object cachedValue = metaCachedParameter.getValue(parameterName);
metaParameter.setValue(parameterName, cachedValue);
}
}
}
}
}
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
//先向缓存中放入占位符???
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
//最后删除占位符
localCache.removeObject(key);
}
//加入缓存
localCache.putObject(key, list);
//如果是存储过程,OUT参数也加入缓存
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
}
public static MappedStatement prepareSelectAuthorViaOutParams(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectAuthorViaOutParams", new StaticSqlSource(config, "{call selectAuthorViaOutParams(?,?,?,?,?)}"), SqlCommandType.SELECT)
.statementType(StatementType.CALLABLE)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>() {
{
add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(int.class)).build());
add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).mode(ParameterMode.OUT).build());
}
}).build())
.resultMaps(new ArrayList<ResultMap>())
.cache(authorCache).build();
return ms;
}
public static MappedStatement createSelectAuthorWithIDof99MappedStatement(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectAuthor", new StaticSqlSource(config,"SELECT * FROM author WHERE id = 99"), SqlCommandType.SELECT)
.statementType(StatementType.STATEMENT)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class, new ArrayList<ParameterMapping>()).build())
.resultMaps(new ArrayList<ResultMap>() {
{
add(new ResultMap.Builder(config, "defaultResultMap", Author.class, new ArrayList<ResultMapping>() {
{
add(new ResultMapping.Builder(config, "id", "id", registry.getTypeHandler(int.class)).build());
add(new ResultMapping.Builder(config, "username", "username", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "password", "password", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "email", "email", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "bio", "bio", registry.getTypeHandler(String.class)).build());
}
}).build());
}
}).build();
return ms;
}
@Insert({"insert into blog_view " ,
"(date,title,article,tags,md) " ,
"values(#{bv.date},#{bv.title}," ,
"#{bv.article},#{bv.tags},#{bv.md})"})
@SelectKey(before=false,keyProperty="bv.vid",resultType=Integer.class,
statementType= StatementType.STATEMENT,statement="SELECT LAST_INSERT_ID() AS id")
int insertBlog(@Param("bv") BlogView blogView);
@Insert({"insert into blog_view " ,
"(date,title,article,tags,md) " ,
"values(#{bv.date},#{bv.title}," ,
"#{bv.article},#{bv.tags},#{bv.md})"})
@SelectKey(before=false,keyProperty="bv.vid",resultType=Integer.class,
statementType= StatementType.STATEMENT,statement="SELECT LAST_INSERT_ID() AS id")
int insertBlog(@Param("bv") BlogView blogView) throws RuntimeException;
protected void addMappedStatement(String id, SqlSource sqlSource,
StatementType statementType, SqlCommandType sqlCommandType, Integer fetchSize,
Integer timeout, String parameterMap, Class<?> parameterType,
String resultMap, Class<?> resultType, ResultSetType resultSetType,
boolean flushCache, boolean useCache, boolean resultOrdered,
KeyGenerator keyGenerator, String keyProperty, String keyColumn,
String databaseId, LanguageDriver lang, String resultSets) {
assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterType, resultMap, resultType,
resultSetType, flushCache, useCache, resultOrdered, keyGenerator,
keyProperty, keyColumn, databaseId, lang, resultSets);
}
private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId, Class<?> parameterTypeClass, LanguageDriver languageDriver) {
String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
Class<?> resultTypeClass = selectKeyAnnotation.resultType();
StatementType statementType = selectKeyAnnotation.statementType();
String keyProperty = selectKeyAnnotation.keyProperty();
String keyColumn = selectKeyAnnotation.keyColumn();
boolean executeBefore = selectKeyAnnotation.before();
// defaults
boolean useCache = false;
KeyGenerator keyGenerator = new NoKeyGenerator();
Integer fetchSize = null;
Integer timeout = null;
boolean flushCache = false;
String parameterMap = null;
String resultMap = null;
ResultSetType resultSetTypeEnum = null;
SqlSource sqlSource = buildSqlSourceFromStrings(selectKeyAnnotation.statement(), parameterTypeClass, languageDriver);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
flushCache, useCache, false,
keyGenerator, keyProperty, keyColumn, null, languageDriver, null);
id = assistant.applyCurrentNamespace(id, false);
MappedStatement keyStatement = configuration.getMappedStatement(id, false);
SelectKeyGenerator answer = new SelectKeyGenerator(keyStatement, executeBefore);
configuration.addKeyGenerator(id, answer);
return answer;
}
/** Backward compatibility signature */
//向后兼容方法
public MappedStatement addMappedStatement(
String id,
SqlSource sqlSource,
StatementType statementType,
SqlCommandType sqlCommandType,
Integer fetchSize,
Integer timeout,
String parameterMap,
Class<?> parameterType,
String resultMap,
Class<?> resultType,
ResultSetType resultSetType,
boolean flushCache,
boolean useCache,
boolean resultOrdered,
KeyGenerator keyGenerator,
String keyProperty,
String keyColumn,
String databaseId,
LanguageDriver lang) {
return addMappedStatement(
id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
parameterMap, parameterType, resultMap, resultType, resultSetType,
flushCache, useCache, resultOrdered, keyGenerator, keyProperty,
keyColumn, databaseId, lang, null);
}
private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> parameterTypeClass, LanguageDriver langDriver, String databaseId) {
String resultType = nodeToHandle.getStringAttribute("resultType");
Class<?> resultTypeClass = resolveClass(resultType);
StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
String keyColumn = nodeToHandle.getStringAttribute("keyColumn");
boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));
//defaults
boolean useCache = false;
boolean resultOrdered = false;
KeyGenerator keyGenerator = new NoKeyGenerator();
Integer fetchSize = null;
Integer timeout = null;
boolean flushCache = false;
String parameterMap = null;
String resultMap = null;
ResultSetType resultSetTypeEnum = null;
SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);
id = builderAssistant.applyCurrentNamespace(id, false);
MappedStatement keyStatement = configuration.getMappedStatement(id, false);
configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
}
private void ensureNoOutParams(MappedStatement ms, Object parameter, BoundSql boundSql) {
if (ms.getStatementType() == StatementType.CALLABLE) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
throw new ExecutorException("Caching stored procedures with OUT params is not supported. Please configure useCache=false in " + ms.getId() + " statement.");
}
}
}
}
public static MappedStatement prepareSelectTwoSetsOfAuthorsProc(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectTwoSetsOfAuthors", new StaticSqlSource(config,"{call selectTwoSetsOfAuthors(?,?)}"), SqlCommandType.SELECT)
.statementType(StatementType.CALLABLE)
.parameterMap(new ParameterMap.Builder(
config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>() {
{
add(new ParameterMapping.Builder(config, "id1", registry.getTypeHandler(int.class)).build());
add(new ParameterMapping.Builder(config, "id2", registry.getTypeHandler(int.class)).build());
}
}).build())
.resultMaps(new ArrayList<ResultMap>() {
{
ResultMap map = new ResultMap.Builder(config, "defaultResultMap", Author.class, new ArrayList<ResultMapping>() {
{
add(new ResultMapping.Builder(config, "id", "id", registry.getTypeHandler(int.class)).build());
add(new ResultMapping.Builder(config, "username", "username", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "password", "password", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "email", "email", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "bio", "bio", registry.getTypeHandler(String.class)).build());
}
}).build();
add(map);
add(map);
}
}).build();
return ms;
}
public static MappedStatement createInsertAuthorWithIDof99MappedStatement(final Configuration config) {
MappedStatement ms = new MappedStatement.Builder(config, "insertAuthor", new StaticSqlSource(config,"INSERT INTO author (id,username,password,email,bio) values(99,'someone','******','[email protected]',null)"), SqlCommandType.INSERT)
.statementType(StatementType.STATEMENT)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>()).build())
.cache(authorCache)
.build();
return ms;
}
/**
* コンストラクタです。
* @param normalize 正規化するかどうか
*/
public QueryBuilderFactory(boolean normalize) {
registory = new HashMap<StatementType, QueryBuilder>();
registory.put(StatementType.STATEMENT, new SimpleQueryBuilder(normalize));
registory.put(StatementType.PREPARED, new PreparedQueryBuilder(normalize));
registory.put(StatementType.CALLABLE, new CallableQueryBuilder(normalize));
}
private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId, Class<?> parameterTypeClass, LanguageDriver languageDriver) {
String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
Class<?> resultTypeClass = selectKeyAnnotation.resultType();
StatementType statementType = selectKeyAnnotation.statementType();
String keyProperty = selectKeyAnnotation.keyProperty();
String keyColumn = selectKeyAnnotation.keyColumn();
boolean executeBefore = selectKeyAnnotation.before();
// defaults
boolean useCache = false;
KeyGenerator keyGenerator = new NoKeyGenerator();
Integer fetchSize = null;
Integer timeout = null;
boolean flushCache = false;
String parameterMap = null;
String resultMap = null;
ResultSetType resultSetTypeEnum = null;
SqlSource sqlSource = buildSqlSourceFromStrings(selectKeyAnnotation.statement(), parameterTypeClass, languageDriver);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
flushCache, useCache, false,
keyGenerator, keyProperty, keyColumn, null, languageDriver, null);
id = assistant.applyCurrentNamespace(id, false);
MappedStatement keyStatement = configuration.getMappedStatement(id, false);
SelectKeyGenerator answer = new SelectKeyGenerator(keyStatement, executeBefore);
configuration.addKeyGenerator(id, answer);
return answer;
}
/** Backward compatibility signature */
//向后兼容方法
public MappedStatement addMappedStatement(
String id,
SqlSource sqlSource,
StatementType statementType,
SqlCommandType sqlCommandType,
Integer fetchSize,
Integer timeout,
String parameterMap,
Class<?> parameterType,
String resultMap,
Class<?> resultType,
ResultSetType resultSetType,
boolean flushCache,
boolean useCache,
boolean resultOrdered,
KeyGenerator keyGenerator,
String keyProperty,
String keyColumn,
String databaseId,
LanguageDriver lang) {
return addMappedStatement(
id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
parameterMap, parameterType, resultMap, resultType, resultSetType,
flushCache, useCache, resultOrdered, keyGenerator, keyProperty,
keyColumn, databaseId, lang, null);
}
private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> parameterTypeClass, LanguageDriver langDriver, String databaseId) {
String resultType = nodeToHandle.getStringAttribute("resultType");
Class<?> resultTypeClass = resolveClass(resultType);
StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
String keyColumn = nodeToHandle.getStringAttribute("keyColumn");
boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));
//defaults
boolean useCache = false;
boolean resultOrdered = false;
KeyGenerator keyGenerator = new NoKeyGenerator();
Integer fetchSize = null;
Integer timeout = null;
boolean flushCache = false;
String parameterMap = null;
String resultMap = null;
ResultSetType resultSetTypeEnum = null;
SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);
id = builderAssistant.applyCurrentNamespace(id, false);
MappedStatement keyStatement = configuration.getMappedStatement(id, false);
configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
}
private void ensureNoOutParams(MappedStatement ms, Object parameter, BoundSql boundSql) {
if (ms.getStatementType() == StatementType.CALLABLE) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
throw new ExecutorException("Caching stored procedures with OUT params is not supported. Please configure useCache=false in " + ms.getId() + " statement.");
}
}
}
}
public static MappedStatement prepareSelectTwoSetsOfAuthorsProc(final Configuration config) {
final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
MappedStatement ms = new MappedStatement.Builder(config, "selectTwoSetsOfAuthors", new StaticSqlSource(config,"{call selectTwoSetsOfAuthors(?,?)}"), SqlCommandType.SELECT)
.statementType(StatementType.CALLABLE)
.parameterMap(new ParameterMap.Builder(
config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>() {
{
add(new ParameterMapping.Builder(config, "id1", registry.getTypeHandler(int.class)).build());
add(new ParameterMapping.Builder(config, "id2", registry.getTypeHandler(int.class)).build());
}
}).build())
.resultMaps(new ArrayList<ResultMap>() {
{
ResultMap map = new ResultMap.Builder(config, "defaultResultMap", Author.class, new ArrayList<ResultMapping>() {
{
add(new ResultMapping.Builder(config, "id", "id", registry.getTypeHandler(int.class)).build());
add(new ResultMapping.Builder(config, "username", "username", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "password", "password", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "email", "email", registry.getTypeHandler(String.class)).build());
add(new ResultMapping.Builder(config, "bio", "bio", registry.getTypeHandler(String.class)).build());
}
}).build();
add(map);
add(map);
}
}).build();
return ms;
}
public static MappedStatement createInsertAuthorWithIDof99MappedStatement(final Configuration config) {
MappedStatement ms = new MappedStatement.Builder(config, "insertAuthor", new StaticSqlSource(config,"INSERT INTO author (id,username,password,email,bio) values(99,'someone','******','[email protected]',null)"), SqlCommandType.INSERT)
.statementType(StatementType.STATEMENT)
.parameterMap(new ParameterMap.Builder(config, "defaultParameterMap", Author.class,
new ArrayList<ParameterMapping>()).build())
.cache(authorCache)
.build();
return ms;
}
public MappedStatement addMappedStatement(
String id,
SqlSource sqlSource,
StatementType statementType,
SqlCommandType sqlCommandType,
Integer fetchSize,
Integer timeout,
String parameterMap,
Class<?> parameterType,
String resultMap,
Class<?> resultType,
ResultSetType resultSetType,
boolean flushCache,
boolean useCache,
boolean resultOrdered,
KeyGenerator keyGenerator,
String keyProperty,
String keyColumn,
String databaseId,
LanguageDriver lang,
String resultSets) {
if (unresolvedCacheRef) {
throw new IncompleteElementException("Cache-ref not yet resolved");
}
//为id加上namespace前缀
id = applyCurrentNamespace(id, false);
//是否是select语句
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
//又是建造者模式
MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
statementBuilder.resource(resource);
statementBuilder.fetchSize(fetchSize);
statementBuilder.statementType(statementType);
statementBuilder.keyGenerator(keyGenerator);
statementBuilder.keyProperty(keyProperty);
statementBuilder.keyColumn(keyColumn);
statementBuilder.databaseId(databaseId);
statementBuilder.lang(lang);
statementBuilder.resultOrdered(resultOrdered);
statementBuilder.resulSets(resultSets);
setStatementTimeout(timeout, statementBuilder);
//1.参数映射
setStatementParameterMap(parameterMap, parameterType, statementBuilder);
//2.结果映射
setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);
MappedStatement statement = statementBuilder.build();
//建造好调用configuration.addMappedStatement
configuration.addMappedStatement(statement);
return statement;
}
public void parseStatementNode() {
String id = context.getStringAttribute("id");
String databaseId = context.getStringAttribute("databaseId");
//如果databaseId不匹配,退出
if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
return;
}
//暗示驱动程序每次批量返回的结果行数
Integer fetchSize = context.getIntAttribute("fetchSize");
//超时时间
Integer timeout = context.getIntAttribute("timeout");
//引用外部 parameterMap,已废弃
String parameterMap = context.getStringAttribute("parameterMap");
//参数类型
String parameterType = context.getStringAttribute("parameterType");
Class<?> parameterTypeClass = resolveClass(parameterType);
//引用外部的 resultMap(高级功能)
String resultMap = context.getStringAttribute("resultMap");
//结果类型
String resultType = context.getStringAttribute("resultType");
//脚本语言,mybatis3.2的新功能
String lang = context.getStringAttribute("lang");
//得到语言驱动
LanguageDriver langDriver = getLanguageDriver(lang);
Class<?> resultTypeClass = resolveClass(resultType);
//结果集类型,FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE 中的一种
String resultSetType = context.getStringAttribute("resultSetType");
//语句类型, STATEMENT|PREPARED|CALLABLE 的一种
StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
//获取命令类型(select|insert|update|delete)
String nodeName = context.getNode().getNodeName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
//是否要缓存select结果
boolean useCache = context.getBooleanAttribute("useCache", isSelect);
//仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。
//这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。
boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);
// Include Fragments before parsing
//解析之前先解析<include>SQL片段
XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
includeParser.applyIncludes(context.getNode());
// Parse selectKey after includes and remove them.
//解析之前先解析<selectKey>
processSelectKeyNodes(id, parameterTypeClass, langDriver);
// Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
//解析成SqlSource,一般是DynamicSqlSource
SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
String resultSets = context.getStringAttribute("resultSets");
//(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
String keyProperty = context.getStringAttribute("keyProperty");
//(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
String keyColumn = context.getStringAttribute("keyColumn");
KeyGenerator keyGenerator;
String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
if (configuration.hasKeyGenerator(keyStatementId)) {
keyGenerator = configuration.getKeyGenerator(keyStatementId);
} else {
keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
? new Jdbc3KeyGenerator() : new NoKeyGenerator();
}
//又去调助手类
builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}
@Select({ "{call sptest.adder(", "#{addend1,jdbcType=INTEGER,mode=IN},", "#{addend2,jdbcType=INTEGER,mode=IN},", "#{sum,jdbcType=INTEGER,mode=OUT})}" })
@Options(statementType = StatementType.CALLABLE)
Object adderAsSelectAnnotated(Parameter parameter);