1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.mapping;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.apache.ibatis.session.Configuration;
24 import org.apache.ibatis.type.JdbcType;
25 import org.apache.ibatis.type.TypeHandler;
26 import org.apache.ibatis.type.TypeHandlerRegistry;
27
28
29
30
31 public class ResultMapping {
32
33 private Configuration configuration;
34 private String property;
35 private String column;
36 private Class<?> javaType;
37 private JdbcType jdbcType;
38 private TypeHandler<?> typeHandler;
39 private String nestedResultMapId;
40 private String nestedQueryId;
41 private Set<String> notNullColumns;
42 private String columnPrefix;
43 private List<ResultFlag> flags;
44 private List<ResultMapping> composites;
45 private String resultSet;
46 private String foreignColumn;
47 private boolean lazy;
48
49 ResultMapping() {
50 }
51
52 public static class Builder {
53 private final ResultMapping resultMapping = new ResultMapping();
54
55 public Builder(Configuration configuration, String property, String column, TypeHandler<?> typeHandler) {
56 this(configuration, property);
57 resultMapping.column = column;
58 resultMapping.typeHandler = typeHandler;
59 }
60
61 public Builder(Configuration configuration, String property, String column, Class<?> javaType) {
62 this(configuration, property);
63 resultMapping.column = column;
64 resultMapping.javaType = javaType;
65 }
66
67 public Builder(Configuration configuration, String property) {
68 resultMapping.configuration = configuration;
69 resultMapping.property = property;
70 resultMapping.flags = new ArrayList<>();
71 resultMapping.composites = new ArrayList<>();
72 resultMapping.lazy = configuration.isLazyLoadingEnabled();
73 }
74
75 public Builder javaType(Class<?> javaType) {
76 resultMapping.javaType = javaType;
77 return this;
78 }
79
80 public Builder jdbcType(JdbcType jdbcType) {
81 resultMapping.jdbcType = jdbcType;
82 return this;
83 }
84
85 public Builder nestedResultMapId(String nestedResultMapId) {
86 resultMapping.nestedResultMapId = nestedResultMapId;
87 return this;
88 }
89
90 public Builder nestedQueryId(String nestedQueryId) {
91 resultMapping.nestedQueryId = nestedQueryId;
92 return this;
93 }
94
95 public Builder resultSet(String resultSet) {
96 resultMapping.resultSet = resultSet;
97 return this;
98 }
99
100 public Builder foreignColumn(String foreignColumn) {
101 resultMapping.foreignColumn = foreignColumn;
102 return this;
103 }
104
105 public Builder notNullColumns(Set<String> notNullColumns) {
106 resultMapping.notNullColumns = notNullColumns;
107 return this;
108 }
109
110 public Builder columnPrefix(String columnPrefix) {
111 resultMapping.columnPrefix = columnPrefix;
112 return this;
113 }
114
115 public Builder flags(List<ResultFlag> flags) {
116 resultMapping.flags = flags;
117 return this;
118 }
119
120 public Builder typeHandler(TypeHandler<?> typeHandler) {
121 resultMapping.typeHandler = typeHandler;
122 return this;
123 }
124
125 public Builder composites(List<ResultMapping> composites) {
126 resultMapping.composites = composites;
127 return this;
128 }
129
130 public Builder lazy(boolean lazy) {
131 resultMapping.lazy = lazy;
132 return this;
133 }
134
135 public ResultMapping build() {
136
137 resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);
138 resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);
139 resolveTypeHandler();
140 validate();
141 return resultMapping;
142 }
143
144 private void validate() {
145
146 if (resultMapping.nestedQueryId != null && resultMapping.nestedResultMapId != null) {
147 throw new IllegalStateException(
148 "Cannot define both nestedQueryId and nestedResultMapId in property " + resultMapping.property);
149 }
150
151 if (resultMapping.nestedQueryId == null && resultMapping.nestedResultMapId == null
152 && resultMapping.typeHandler == null) {
153 throw new IllegalStateException("No typehandler found for property " + resultMapping.property);
154 }
155
156 if (resultMapping.nestedResultMapId == null && resultMapping.column == null
157 && resultMapping.composites.isEmpty()) {
158 throw new IllegalStateException("Mapping is missing column attribute for property " + resultMapping.property);
159 }
160 if (resultMapping.getResultSet() != null) {
161 int numColumns = 0;
162 if (resultMapping.column != null) {
163 numColumns = resultMapping.column.split(",").length;
164 }
165 int numForeignColumns = 0;
166 if (resultMapping.foreignColumn != null) {
167 numForeignColumns = resultMapping.foreignColumn.split(",").length;
168 }
169 if (numColumns != numForeignColumns) {
170 throw new IllegalStateException(
171 "There should be the same number of columns and foreignColumns in property " + resultMapping.property);
172 }
173 }
174 }
175
176 private void resolveTypeHandler() {
177 if (resultMapping.typeHandler == null && resultMapping.javaType != null) {
178 Configuration configuration = resultMapping.configuration;
179 TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
180 resultMapping.typeHandler = typeHandlerRegistry.getTypeHandler(resultMapping.javaType, resultMapping.jdbcType);
181 }
182 }
183
184 public Builder column(String column) {
185 resultMapping.column = column;
186 return this;
187 }
188 }
189
190 public String getProperty() {
191 return property;
192 }
193
194 public String getColumn() {
195 return column;
196 }
197
198 public Class<?> getJavaType() {
199 return javaType;
200 }
201
202 public JdbcType getJdbcType() {
203 return jdbcType;
204 }
205
206 public TypeHandler<?> getTypeHandler() {
207 return typeHandler;
208 }
209
210 public String getNestedResultMapId() {
211 return nestedResultMapId;
212 }
213
214 public String getNestedQueryId() {
215 return nestedQueryId;
216 }
217
218 public Set<String> getNotNullColumns() {
219 return notNullColumns;
220 }
221
222 public String getColumnPrefix() {
223 return columnPrefix;
224 }
225
226 public List<ResultFlag> getFlags() {
227 return flags;
228 }
229
230 public List<ResultMapping> getComposites() {
231 return composites;
232 }
233
234 public boolean isCompositeResult() {
235 return this.composites != null && !this.composites.isEmpty();
236 }
237
238 public String getResultSet() {
239 return this.resultSet;
240 }
241
242 public String getForeignColumn() {
243 return foreignColumn;
244 }
245
246 public void setForeignColumn(String foreignColumn) {
247 this.foreignColumn = foreignColumn;
248 }
249
250 public boolean isLazy() {
251 return lazy;
252 }
253
254 public void setLazy(boolean lazy) {
255 this.lazy = lazy;
256 }
257
258 public boolean isSimple() {
259 return this.nestedResultMapId == null && this.nestedQueryId == null && this.resultSet == null;
260 }
261
262 @Override
263 public boolean equals(Object o) {
264 if (this == o) {
265 return true;
266 }
267 if (o == null || getClass() != o.getClass()) {
268 return false;
269 }
270
271 ResultMapping that = (ResultMapping) o;
272
273 return property != null && property.equals(that.property);
274 }
275
276 @Override
277 public int hashCode() {
278 if (property != null) {
279 return property.hashCode();
280 }
281 if (column != null) {
282 return column.hashCode();
283 } else {
284 return 0;
285 }
286 }
287
288 @Override
289 public String toString() {
290 final StringBuilder sb = new StringBuilder("ResultMapping{");
291
292 sb.append("property='").append(property).append('\'');
293 sb.append(", column='").append(column).append('\'');
294 sb.append(", javaType=").append(javaType);
295 sb.append(", jdbcType=").append(jdbcType);
296
297 sb.append(", nestedResultMapId='").append(nestedResultMapId).append('\'');
298 sb.append(", nestedQueryId='").append(nestedQueryId).append('\'');
299 sb.append(", notNullColumns=").append(notNullColumns);
300 sb.append(", columnPrefix='").append(columnPrefix).append('\'');
301 sb.append(", flags=").append(flags);
302 sb.append(", composites=").append(composites);
303 sb.append(", resultSet='").append(resultSet).append('\'');
304 sb.append(", foreignColumn='").append(foreignColumn).append('\'');
305 sb.append(", lazy=").append(lazy);
306 sb.append('}');
307 return sb.toString();
308 }
309
310 }