@
目錄
- 1 成員變量
- 2 構造函數
- 3 其他函數
- 3.1 setter 和 getter 函數
- 3.2 equals 和 hashCode 函數
- 3.3 toString 函數
- 4 内部類 Builder
- 4.1 成員變量
- 4.2 構造函數
- 4.3 建造者模式相關函數
- 一起學 mybatis
ResultMapping
對象是 mybatis 的 <resultMap> 節點在
ResultMap
對象中基礎組成部分.
ResultMapping
對象記錄了結果集中一列與隊友JavaBean中一個屬性的對應關系。
// Configuration 對象, 看過前面源碼的應該知道這個對象的含義
private Configuration configuration;
// 對應相應 JavaBean 中的成員變量
private String property;
// 對應節點的 column 屬性, 對應檢索出來的列名(别名)
private String column;
// 對應節點的 javaType 屬性
private Class<?> javaType;
// 對應節點的 jdbcType 屬性, 表示映射列的JDBC屬性
private JdbcType jdbcType;
// 類型處理器
private TypeHandler<?> typeHandler;
// 對應另一個 resultMap 的 id, 負責将結果集中的一部分映射成其他對象。
private String nestedResultMapId;
//
private String nestedQueryId;
// 對應節點的 notNullColumns 屬性拆分後的結果
private Set<String> notNullColumns;
// 對應節點的 columnPrefix 屬性
private String columnPrefix;
// 處理後的标記, 有兩種:id和constructor
private List<ResultFlag> flags;
//
private List<ResultMapping> composites;
// 對應節點的 resultSet 屬性
private String resultSet;
// 對應節點的 foreignColumn 屬性
private String foreignColumn;
// 是否延遲加載, 對應節點的 fetchType 屬性
private boolean lazy;
ResultMapping() {
}
就是一個空的構造函數
ResultMapping
對象建立使用的是建造者模式, 是以,隻有部分成員變量含有 setter 函數。而除了 Configuration 對象, 其他都含有 getter 函數。
該函數重寫了 equals 方法。
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ResultMapping that = (ResultMapping) o;
if (property == null || !property.equals(that.property)) {
return false;
}
return true;
}
而 equals 重寫, 則基本上 hashCode 也要重寫。 以 property 或 column 的 hashCode 作為其 hashCode
@Override
public int hashCode() {
if (property != null) {
return property.hashCode();
} else if (column != null) {
return column.hashCode();
} else {
return 0;
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ResultMapping{");
//sb.append("configuration=").append(configuration); // configuration doesn't have a useful .toString()
sb.append("property='").append(property).append('\'');
sb.append(", column='").append(column).append('\'');
sb.append(", javaType=").append(javaType);
sb.append(", jdbcType=").append(jdbcType);
//sb.append(", typeHandler=").append(typeHandler); // typeHandler also doesn't have a useful .toString()
sb.append(", nestedResultMapId='").append(nestedResultMapId).append('\'');
sb.append(", nestedQueryId='").append(nestedQueryId).append('\'');
sb.append(", notNullColumns=").append(notNullColumns);
sb.append(", columnPrefix='").append(columnPrefix).append('\'');
sb.append(", flags=").append(flags);
sb.append(", composites=").append(composites);
sb.append(", resultSet='").append(resultSet).append('\'');
sb.append(", foreignColumn='").append(foreignColumn).append('\'');
sb.append(", lazy=").append(lazy);
sb.append('}');
return sb.toString();
}
恨我們平常寫的基本差不多。
ResultMapping 是使用建造者模式來進行建立的。
private ResultMapping resultMapping = new ResultMapping();
就是給部分屬性指派。
public Builder(Configuration configuration, String property, String column, TypeHandler<?> typeHandler) {
this(configuration, property);
resultMapping.column = column;
resultMapping.typeHandler = typeHandler;
}
public Builder(Configuration configuration, String property, String column, Class<?> javaType) {
this(configuration, property);
resultMapping.column = column;
resultMapping.javaType = javaType;
}
public Builder(Configuration configuration, String property) {
resultMapping.configuration = configuration;
resultMapping.property = property;
resultMapping.flags = new ArrayList<ResultFlag>();
resultMapping.composites = new ArrayList<ResultMapping>();
resultMapping.lazy = configuration.isLazyLoadingEnabled();
}
除了 configuration, property, column, 其他成員變量都有類似如下的函數:
指派後傳回 Builder 對象本身。
public Builder javaType(Class<?> javaType) {
resultMapping.javaType = javaType;
return this;
}
建造對象的函數
public ResultMapping build() {
// 傳回不可更改的 List
resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);
// 傳回不可更改的 List
resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);
resolveTypeHandler();
// 校驗
validate();
return resultMapping;
}
校驗
// 對我們寫的配置進行校驗
private void validate() {
// 不可同時定義 nestedQueryId 和 nestedResultMapId
if (resultMapping.nestedQueryId != null && resultMapping.nestedResultMapId != null) {
throw new IllegalStateException("Cannot define both nestedQueryId and nestedResultMapId in property " + resultMapping.property);
}
// nestedQueryId 、 nestedResultMapId 和 typeHandler 不能同時為 null
if (resultMapping.nestedQueryId == null && resultMapping.nestedResultMapId == null && resultMapping.typeHandler == null) {
throw new IllegalStateException("No typehandler found for property " + resultMapping.property);
}
// Issue #4 and GH #39: column is optional only in nested resultmaps but not in the rest
if (resultMapping.nestedResultMapId == null && resultMapping.column == null && resultMapping.composites.isEmpty()) {
throw new IllegalStateException("Mapping is missing column attribute for property " + resultMapping.property);
}
if (resultMapping.getResultSet() != null) {
int numColumns = 0;
if (resultMapping.column != null) {
numColumns = resultMapping.column.split(",").length;
}
int numForeignColumns = 0;
if (resultMapping.foreignColumn != null) {
numForeignColumns = resultMapping.foreignColumn.split(",").length;
}
if (numColumns != numForeignColumns) {
throw new IllegalStateException("There should be the same number of columns and foreignColumns in property " + resultMapping.property);
}
}
}
你想不想來學習 mybatis? 學習其使用和源碼呢?那麼, 在部落格園關注我吧!!
我自己打算把這個源碼系列更新完畢, 同時會更新相應的注釋。快去 star 吧!!
mybatis最新源碼和注釋

作者:阿進的寫字台
出處:https://www.cnblogs.com/homejim/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。