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 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<ResultFlag>();
71 resultMapping.composites = new ArrayList<ResultMapping>();
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("Cannot define both nestedQueryId and nestedResultMapId in property " + resultMapping.property);
148 }
149
150 if (resultMapping.nestedQueryId == null && resultMapping.nestedResultMapId == null && resultMapping.typeHandler == null) {
151 throw new IllegalStateException("No typehandler found for property " + resultMapping.property);
152 }
153
154 if (resultMapping.nestedResultMapId == null && resultMapping.column == null && resultMapping.composites.isEmpty()) {
155 throw new IllegalStateException("Mapping is missing column attribute for property " + resultMapping.property);
156 }
157 if (resultMapping.getResultSet() != null) {
158 int numColums = 0;
159 if (resultMapping.column != null) {
160 numColums = resultMapping.column.split(",").length;
161 }
162 int numForeignColumns = 0;
163 if (resultMapping.foreignColumn != null) {
164 numForeignColumns = resultMapping.foreignColumn.split(",").length;
165 }
166 if (numColums != numForeignColumns) {
167 throw new IllegalStateException("There should be the same number of columns and foreignColumns in property " + resultMapping.property);
168 }
169 }
170 }
171
172 private void resolveTypeHandler() {
173 if (resultMapping.typeHandler == null && resultMapping.javaType != null) {
174 Configuration configuration = resultMapping.configuration;
175 TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
176 resultMapping.typeHandler = typeHandlerRegistry.getTypeHandler(resultMapping.javaType, resultMapping.jdbcType);
177 }
178 }
179
180 public Builder column(String column) {
181 resultMapping.column = column;
182 return this;
183 }
184 }
185
186 public String getProperty() {
187 return property;
188 }
189
190 public String getColumn() {
191 return column;
192 }
193
194 public Class<?> getJavaType() {
195 return javaType;
196 }
197
198 public JdbcType getJdbcType() {
199 return jdbcType;
200 }
201
202 public TypeHandler<?> getTypeHandler() {
203 return typeHandler;
204 }
205
206 public String getNestedResultMapId() {
207 return nestedResultMapId;
208 }
209
210 public String getNestedQueryId() {
211 return nestedQueryId;
212 }
213
214 public Set<String> getNotNullColumns() {
215 return notNullColumns;
216 }
217
218 public String getColumnPrefix() {
219 return columnPrefix;
220 }
221
222 public List<ResultFlag> getFlags() {
223 return flags;
224 }
225
226 public List<ResultMapping> getComposites() {
227 return composites;
228 }
229
230 public boolean isCompositeResult() {
231 return this.composites != null && !this.composites.isEmpty();
232 }
233
234 public String getResultSet() {
235 return this.resultSet;
236 }
237
238 public String getForeignColumn() {
239 return foreignColumn;
240 }
241
242 public void setForeignColumn(String foreignColumn) {
243 this.foreignColumn = foreignColumn;
244 }
245
246 public boolean isLazy() {
247 return lazy;
248 }
249
250 public void setLazy(boolean lazy) {
251 this.lazy = lazy;
252 }
253
254 @Override
255 public boolean equals(Object o) {
256 if (this == o) {
257 return true;
258 }
259 if (o == null || getClass() != o.getClass()) {
260 return false;
261 }
262
263 ResultMapping that = (ResultMapping) o;
264
265 if (property == null || !property.equals(that.property)) {
266 return false;
267 }
268
269 return true;
270 }
271
272 @Override
273 public int hashCode() {
274 if (property != null) {
275 return property.hashCode();
276 } else if (column != null) {
277 return column.hashCode();
278 } else {
279 return 0;
280 }
281 }
282
283 @Override
284 public String toString() {
285 final StringBuilder sb = new StringBuilder("ResultMapping{");
286
287 sb.append("property='").append(property).append('\'');
288 sb.append(", column='").append(column).append('\'');
289 sb.append(", javaType=").append(javaType);
290 sb.append(", jdbcType=").append(jdbcType);
291
292 sb.append(", nestedResultMapId='").append(nestedResultMapId).append('\'');
293 sb.append(", nestedQueryId='").append(nestedQueryId).append('\'');
294 sb.append(", notNullColumns=").append(notNullColumns);
295 sb.append(", columnPrefix='").append(columnPrefix).append('\'');
296 sb.append(", flags=").append(flags);
297 sb.append(", composites=").append(composites);
298 sb.append(", resultSet='").append(resultSet).append('\'');
299 sb.append(", foreignColumn='").append(foreignColumn).append('\'');
300 sb.append(", lazy=").append(lazy);
301 sb.append('}');
302 return sb.toString();
303 }
304
305 }