Skip to content

Commit

Permalink
解析xml配置时,添加查询结果集resultType
Browse files Browse the repository at this point in the history
  • Loading branch information
FuriousPws002 committed Apr 11, 2024
1 parent f3bb54f commit 001fe00
Show file tree
Hide file tree
Showing 14 changed files with 238 additions and 1 deletion.
15 changes: 15 additions & 0 deletions src/main/java/org/apache/ibatis/builder/BaseBuilder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.apache.ibatis.builder;

import java.util.Objects;

import org.apache.commons.lang3.ClassUtils;
import org.apache.ibatis.session.Configuration;

/**
Expand All @@ -16,4 +19,16 @@ public BaseBuilder(Configuration configuration) {
public Configuration getConfiguration() {
return configuration;
}

@SuppressWarnings("unchecked")
protected <T> Class<? extends T> resolveClass(String className) {
if (Objects.isNull(className)) {
return null;
}
try {
return (Class<? extends T>) ClassUtils.getClass(className);
} catch (Exception e) {
throw new BuilderException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.apache.ibatis.builder;


import java.util.Objects;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;
Expand Down Expand Up @@ -30,4 +33,21 @@ public void addMappedStatement(String id, SqlCommandType sqlCommandType, SqlSour
.build();
configuration.addMappedStatement(statement);
}

public void addMappedStatement(String id, SqlCommandType sqlCommandType, SqlSource sqlSource, Class<?> resultTypeClass) {
id = currentNamespace + "." + id;
MappedStatement statement = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
.resource(resource)
.resultMap(getStatementResultMap(resultTypeClass))
.build();
configuration.addMappedStatement(statement);
}

private ResultMap getStatementResultMap(Class<?> resultType) {
if (Objects.isNull(resultType)) {
return null;
}
return new ResultMap(configuration, resultType);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.Locale;

import org.apache.commons.lang3.ClassUtils;
import org.apache.ibatis.builder.BaseBuilder;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.builder.StaticSqlSource;
Expand Down Expand Up @@ -36,6 +37,8 @@ public void parseStatementNode() {
String nodeName = context.getName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
SqlSource sqlSource = configuration.getLanguageDriver().createSqlSource(configuration, context, null);
builderAssistant.addMappedStatement(id, sqlCommandType, sqlSource);
String resultType = context.getAttribute("resultType");
Class<?> resultTypeClass = resolveClass(resultType);
builderAssistant.addMappedStatement(id, sqlCommandType, sqlSource,resultTypeClass);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.apache.ibatis.executor.result;

/**
* @author furious 2024/4/11
*/
public class ResultMapException extends RuntimeException{

public ResultMapException() {
super();
}

public ResultMapException(String message) {
super(message);
}

public ResultMapException(String message, Throwable cause) {
super(message, cause);
}

public ResultMapException(Throwable cause) {
super(cause);
}

protected ResultMapException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.apache.ibatis.executor.resultset;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
* @author furious 2024/4/11
*/
public interface ResultSetHandler {

<T> List<T> handleResultSets(Statement stmt) throws SQLException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.apache.ibatis.executor.resultset;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;

/**
* @author furious 2024/4/11
*/
public class ResultSetWrapper {

private final ResultSet resultSet;
private final TypeHandlerRegistry typeHandlerRegistry;
private final List<String> columnLabels = new ArrayList<>();
private final List<String> classNames = new ArrayList<>();
private final List<Integer> jdbcTypes = new ArrayList<>();

public ResultSetWrapper(ResultSet rs, Configuration configuration) throws SQLException {
this.resultSet = rs;
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
columnLabels.add(metaData.getColumnLabel(i));
classNames.add(metaData.getColumnClassName(i));
jdbcTypes.add(metaData.getColumnType(i));
}
}

}
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/mapping/MappedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public class MappedStatement {
private String id;
private SqlSource sqlSource;
private SqlCommandType sqlCommandType;
private ResultMap resultMap;

public String getId() {
return id;
Expand Down Expand Up @@ -45,6 +46,11 @@ public Builder resource(String resource) {
return this;
}

public Builder resultMap(ResultMap resultMap) {
mappedStatement.resultMap = resultMap;
return this;
}

public MappedStatement build() {
return mappedStatement;
}
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/org/apache/ibatis/mapping/ResultMap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.apache.ibatis.mapping;

import org.apache.ibatis.session.Configuration;

/**
* @author furious 2024/4/11
*/
public class ResultMap {

private Configuration configuration;
/**
* select标签中的resultType
*/
private Class<?> type;

public ResultMap() {
}

public ResultMap(Configuration configuration, Class<?> type) {
this.configuration = configuration;
this.type = type;
}

public Configuration getConfiguration() {
return configuration;
}

public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}

public Class<?> getType() {
return type;
}

public void setType(Class<?> type) {
this.type = type;
}
}
21 changes: 21 additions & 0 deletions src/main/java/org/apache/ibatis/type/BaseTypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Objects;

import org.apache.ibatis.executor.result.ResultMapException;

/**
* @author furious 2024/4/9
*/
Expand All @@ -19,6 +22,15 @@ public void setParameter(PreparedStatement ps, int i, T parameter) throws SQLExc
setNonNullParameter(ps, i, parameter);
}

@Override
public T getResult(ResultSet rs, String columnLabel) throws SQLException {
try {
return getNullableResult(rs, columnLabel);
} catch (Exception e) {
throw new ResultMapException(e);
}
}

/**
* 设置非空值
*
Expand All @@ -28,4 +40,13 @@ public void setParameter(PreparedStatement ps, int i, T parameter) throws SQLExc
* @throws SQLException SQLException
*/
protected abstract void setNonNullParameter(PreparedStatement ps, int i, T parameter) throws SQLException;

/**
* 获取ResultSet中指定列的值
*
* @param rs ResultSet
* @param columnLabel as别名值,无as时就是列名
* @return 获取值
*/
protected abstract T getNullableResult(ResultSet rs, String columnLabel) throws SQLException;
}
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/type/IntegerTypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
Expand All @@ -11,4 +12,9 @@ public class IntegerTypeHandler extends BaseTypeHandler<Integer> {
protected void setNonNullParameter(PreparedStatement ps, int i, Integer parameter) throws SQLException {
ps.setInt(i, parameter);
}

@Override
protected Integer getNullableResult(ResultSet rs, String columnLabel) throws SQLException {
return rs.getInt(columnLabel);
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/type/ObjectTypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
Expand All @@ -11,4 +12,9 @@ public class ObjectTypeHandler extends BaseTypeHandler<Object> {
protected void setNonNullParameter(PreparedStatement ps, int i, Object parameter) throws SQLException {
ps.setObject(i, parameter);
}

@Override
protected Object getNullableResult(ResultSet rs, String columnLabel) throws SQLException {
return rs.getObject(columnLabel);
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/apache/ibatis/type/StringTypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
Expand All @@ -11,4 +12,9 @@ public class StringTypeHandler extends BaseTypeHandler<String> {
protected void setNonNullParameter(PreparedStatement ps, int i, String parameter) throws SQLException {
ps.setString(i, parameter);
}

@Override
protected String getNullableResult(ResultSet rs, String columnLabel) throws SQLException {
return rs.getString(columnLabel);
}
}
3 changes: 3 additions & 0 deletions src/main/java/org/apache/ibatis/type/TypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
Expand All @@ -11,4 +12,6 @@
public interface TypeHandler<T> {

void setParameter(PreparedStatement ps, int i, T parameter) throws SQLException;

T getResult(ResultSet rs, String columnLabel) throws SQLException;
}
34 changes: 34 additions & 0 deletions src/main/java/org/apache/ibatis/type/UnknownTypeHandler.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package org.apache.ibatis.type;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Objects;

import org.apache.commons.lang3.ClassUtils;

/**
* @author furious 2024/4/9
*/
Expand All @@ -26,4 +30,34 @@ protected void setNonNullParameter(PreparedStatement ps, int i, Object parameter
}
handler.setParameter(ps, i, parameter);
}

@Override
protected Object getNullableResult(ResultSet rs, String columnLabel) throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
int columnIndex = -1;
for (int i = 1; i < columnCount; i++) {
if (Objects.equals(metaData.getColumnLabel(i), columnLabel)) {
columnIndex = i;
break;
}
}

TypeHandler<?> handler = null;
if (columnIndex != -1) {
handler = typeHandlerRegistry.getTypeHandler(safeGetClassForColumn(metaData, columnIndex));
}
if (handler == null || handler instanceof UnknownTypeHandler) {
handler = OBJECT_TYPE_HANDLER;
}
return handler.getResult(rs, columnLabel);
}

private Class<?> safeGetClassForColumn(ResultSetMetaData metaData, Integer columnIndex) {
try {
return ClassUtils.getClass(metaData.getColumnClassName(columnIndex));
} catch (Exception e) {
return null;
}
}
}

0 comments on commit 001fe00

Please sign in to comment.