1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.ibatis.submitted.sqlprovider;
17
18 import java.lang.reflect.Field;
19 import java.lang.reflect.Method;
20 import java.lang.reflect.ParameterizedType;
21 import java.lang.reflect.Type;
22 import java.util.LinkedHashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.apache.ibatis.annotations.Param;
27 import org.apache.ibatis.builder.annotation.ProviderContext;
28 import org.apache.ibatis.jdbc.SQL;
29
30 public class OurSqlBuilder {
31
32 public String buildGetUsersQuery(Map<String, Object> parameter) {
33
34
35 @SuppressWarnings("unchecked")
36 List<Integer> ids = (List<Integer>) parameter.get("list");
37 StringBuilder sb = new StringBuilder();
38 sb.append("select * from users where id in (");
39 for (int i = 0; i < ids.size(); i++) {
40 if (i > 0) {
41 sb.append(",");
42 }
43 sb.append("#{list[");
44 sb.append(i);
45 sb.append("]}");
46 }
47 sb.append(") order by id");
48 return sb.toString();
49 }
50
51 public String buildGetUserQuery(Number parameter) {
52
53
54 return "select * from users where id = #{value}";
55 }
56
57 public String buildGetAllUsersQuery() {
58 return "select * from users order by id";
59 }
60
61 public String buildGetUsersByCriteriaQuery(final User criteria) {
62 return new SQL() {
63 {
64 SELECT("*");
65 FROM("users");
66 if (criteria.getId() != null) {
67 WHERE("id = #{id}");
68 }
69 if (criteria.getName() != null) {
70 WHERE("name like #{name} || '%'");
71 }
72 }
73 }.toString();
74 }
75
76 public String buildGetUsersByCriteriaMapQuery(final Map<String, Object> criteria) {
77 return new SQL() {
78 {
79 SELECT("*");
80 FROM("users");
81 if (criteria.get("id") != null) {
82 WHERE("id = #{id}");
83 }
84 if (criteria.get("name") != null) {
85 WHERE("name like #{name} || '%'");
86 }
87 }
88 }.toString();
89 }
90
91 public String buildGetUsersByCriteriaMapWithParamQuery(@Param("id") Integer id, @Param("name") String name) {
92 return new SQL() {
93 {
94 SELECT("*");
95 FROM("users");
96 if (id != null) {
97 WHERE("id = #{id}");
98 }
99 if (name != null) {
100 WHERE("name like #{name} || '%'");
101 }
102 }
103 }.toString();
104 }
105
106 public String buildGetUsersByNameQuery(final String name, final String orderByColumn) {
107 return new SQL() {
108 {
109 SELECT("*");
110 FROM("users");
111 if (name != null) {
112 WHERE("name like #{param1} || '%'");
113 }
114 ORDER_BY(orderByColumn);
115 }
116 }.toString();
117 }
118
119 public String buildGetUsersByNameUsingMap(Map<String, Object> params) {
120 final String name = String.class.cast(params.get("param1"));
121 final String orderByColumn = String.class.cast(params.get("param2"));
122 return new SQL() {
123 {
124 SELECT("*");
125 FROM("users");
126 if (name != null) {
127 WHERE("name like #{param1} || '%'");
128 }
129 ORDER_BY(orderByColumn);
130 }
131 }.toString();
132 }
133
134 public String buildGetUsersByNameWithParamNameAndOrderByQuery(@Param("orderByColumn") final String orderByColumn,
135 @Param("name") final String name) {
136 return new SQL() {
137 {
138 SELECT("*");
139 FROM("users");
140 if (name != null) {
141 WHERE("name like #{name} || '%'");
142 }
143 ORDER_BY(orderByColumn);
144 }
145 }.toString();
146 }
147
148 public String buildGetUsersByNameWithParamNameQuery(@Param("name") final String name) {
149 return new SQL() {
150 {
151 SELECT("*");
152 FROM("users");
153 if (name != null) {
154 WHERE("name like #{name} || '%'");
155 }
156 ORDER_BY("id DESC");
157 }
158 }.toString();
159 }
160
161 public String buildGetUsersByNameWithParamNameQueryUsingMap(Map<String, Object> params) {
162 final String name = String.class.cast(params.get("name"));
163 final String orderByColumn = String.class.cast(params.get("orderByColumn"));
164 return new SQL() {
165 {
166 SELECT("*");
167 FROM("users");
168 if (name != null) {
169 WHERE("name like #{param1} || '%'");
170 }
171 ORDER_BY(orderByColumn);
172 }
173 }.toString();
174 }
175
176 public String buildInsert() {
177 return "insert into users (id, name) values (#{id}, #{name})";
178 }
179
180 public String buildUpdate() {
181 return "update users set name = #{name} where id = #{id}";
182 }
183
184 public String buildDelete() {
185 return "delete from users where id = #{id}";
186 }
187
188 public String buildSelectByIdProviderContextOnly(ProviderContext context) {
189 final boolean containsLogicalDelete = context.getMapperMethod()
190 .getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
191 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
192 return new SQL() {
193 {
194 SELECT("*");
195 FROM(tableName);
196 WHERE("id = #{id}");
197 if (!containsLogicalDelete) {
198 WHERE("logical_delete = ${Constants.LOGICAL_DELETE_OFF}");
199 }
200 }
201 }.toString();
202 }
203
204 public String buildSelectByNameOneParamAndProviderContext(ProviderContext context, final String name) {
205 final boolean containsLogicalDelete = context.getMapperMethod()
206 .getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
207 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
208 return new SQL() {
209 {
210 SELECT("*");
211 FROM(tableName);
212 if (name != null) {
213 WHERE("name like #{name} || '%'");
214 }
215 if (!containsLogicalDelete) {
216 WHERE("logical_delete = ${LOGICAL_DELETE_OFF:0}");
217 }
218 }
219 }.toString();
220 }
221
222 public String buildSelectByIdAndNameMultipleParamAndProviderContextWithAtParam(@Param("id") final Integer id,
223 ProviderContext context, @Param("name") final String name) {
224 final boolean containsLogicalDelete = context.getMapperMethod()
225 .getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
226 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
227 return new SQL() {
228 {
229 SELECT("*");
230 FROM(tableName);
231 if (id != null) {
232 WHERE("id = #{id}");
233 }
234 if (name != null) {
235 WHERE("name like #{name} || '%'");
236 }
237 if (!containsLogicalDelete) {
238 WHERE("logical_delete = false");
239 }
240 }
241 }.toString();
242 }
243
244 public String buildSelectByIdAndNameMultipleParamAndProviderContext(final Integer id, final String name,
245 ProviderContext context) {
246 final boolean containsLogicalDelete = context.getMapperMethod()
247 .getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
248 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
249 return new SQL() {
250 {
251 SELECT("*");
252 FROM(tableName);
253 if (id != null) {
254 WHERE("id = #{param1}");
255 }
256 if (name != null) {
257 WHERE("name like #{param2} || '%'");
258 }
259 if (!containsLogicalDelete) {
260 WHERE("logical_delete = false");
261 }
262 }
263 }.toString();
264 }
265
266 private Class<?> getEntityClass(ProviderContext providerContext) {
267 Method mapperMethod = providerContext.getMapperMethod();
268 Class<?> declaringClass = mapperMethod.getDeclaringClass();
269 Class<?> mapperClass = providerContext.getMapperType();
270
271 Type[] types = mapperClass.getGenericInterfaces();
272 for (Type type : types) {
273 if (type instanceof ParameterizedType) {
274 ParameterizedType t = (ParameterizedType) type;
275 if (t.getRawType() == declaringClass || mapperClass.isAssignableFrom((Class<?>) t.getRawType())) {
276 return (Class<?>) t.getActualTypeArguments()[0];
277 }
278 }
279 }
280 throw new RuntimeException("The interface [" + mapperClass.getCanonicalName() + "] must specify a generic type.");
281 }
282
283 private Map<String, String> getColumnMap(ProviderContext context) {
284 Class<?> entityClass = getEntityClass(context);
285 Field[] fields = entityClass.getDeclaredFields();
286 Map<String, String> columnMap = new LinkedHashMap<>();
287 for (Field field : fields) {
288 BaseMapper.Column column = field.getAnnotation(BaseMapper.Column.class);
289 if (column != null) {
290 String columnName = column.value();
291 if (columnName == null || columnName.length() == 0) {
292 columnName = field.getName();
293 }
294 columnMap.put(columnName, field.getName());
295 }
296 }
297 if (columnMap.size() == 0) {
298 throw new RuntimeException("There is no field in the class [" + entityClass.getCanonicalName()
299 + "] that specifies the @BaseMapper.Column annotation.");
300 }
301 return columnMap;
302 }
303
304 public String buildInsertSelective(ProviderContext context) {
305 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
306 Map<String, String> columnMap = getColumnMap(context);
307 StringBuilder sqlBuffer = new StringBuilder();
308 sqlBuffer.append("<script>");
309 sqlBuffer.append("insert into ");
310 sqlBuffer.append(tableName);
311 sqlBuffer.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
312 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
313 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
314 sqlBuffer.append(entry.getKey()).append(",");
315 sqlBuffer.append("</if>");
316 }
317 sqlBuffer.append("</trim>");
318 sqlBuffer.append("<trim prefix=\"VALUES (\" suffix=\")\" suffixOverrides=\",\">");
319 for (String field : columnMap.values()) {
320 sqlBuffer.append("<if test=\"").append(field).append(" != null\">");
321 sqlBuffer.append("#{").append(field).append("} ,");
322 sqlBuffer.append("</if>");
323 }
324 sqlBuffer.append("</trim>");
325 sqlBuffer.append("</script>");
326 return sqlBuffer.toString();
327 }
328
329 public String buildUpdateSelective(ProviderContext context) {
330 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
331 Map<String, String> columnMap = getColumnMap(context);
332 StringBuilder sqlBuffer = new StringBuilder();
333 sqlBuffer.append("<script>");
334 sqlBuffer.append("update ");
335 sqlBuffer.append(tableName);
336 sqlBuffer.append("<set>");
337 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
338 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
339 sqlBuffer.append(entry.getKey()).append(" = #{").append(entry.getValue()).append("} ,");
340 sqlBuffer.append("</if>");
341 }
342 sqlBuffer.append("</set>");
343
344 sqlBuffer.append("where id = #{id}");
345 sqlBuffer.append("</script>");
346 return sqlBuffer.toString();
347 }
348
349 public String buildGetByEntityQuery(ProviderContext context) {
350 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
351 Map<String, String> columnMap = getColumnMap(context);
352 StringBuilder sqlBuffer = new StringBuilder();
353 sqlBuffer.append("<script>");
354 sqlBuffer.append("select * from ");
355 sqlBuffer.append(tableName);
356 sqlBuffer.append("<where>");
357 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
358 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
359 sqlBuffer.append("and ").append(entry.getKey()).append(" = #{").append(entry.getValue()).append("}");
360 sqlBuffer.append("</if>");
361 }
362 sqlBuffer.append("</where>");
363 sqlBuffer.append("</script>");
364 return sqlBuffer.toString();
365 }
366
367 }