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 t) {
274 if (t.getRawType() == declaringClass || mapperClass.isAssignableFrom((Class<?>) t.getRawType())) {
275 return (Class<?>) t.getActualTypeArguments()[0];
276 }
277 }
278 }
279 throw new RuntimeException("The interface [" + mapperClass.getCanonicalName() + "] must specify a generic type.");
280 }
281
282 private Map<String, String> getColumnMap(ProviderContext context) {
283 Class<?> entityClass = getEntityClass(context);
284 Field[] fields = entityClass.getDeclaredFields();
285 Map<String, String> columnMap = new LinkedHashMap<>();
286 for (Field field : fields) {
287 BaseMapper.Column column = field.getAnnotation(BaseMapper.Column.class);
288 if (column != null) {
289 String columnName = column.value();
290 if (columnName == null || columnName.length() == 0) {
291 columnName = field.getName();
292 }
293 columnMap.put(columnName, field.getName());
294 }
295 }
296 if (columnMap.size() == 0) {
297 throw new RuntimeException("There is no field in the class [" + entityClass.getCanonicalName()
298 + "] that specifies the @BaseMapper.Column annotation.");
299 }
300 return columnMap;
301 }
302
303 public String buildInsertSelective(ProviderContext context) {
304 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
305 Map<String, String> columnMap = getColumnMap(context);
306 StringBuilder sqlBuffer = new StringBuilder();
307 sqlBuffer.append("<script>");
308 sqlBuffer.append("insert into ");
309 sqlBuffer.append(tableName);
310 sqlBuffer.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
311 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
312 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
313 sqlBuffer.append(entry.getKey()).append(",");
314 sqlBuffer.append("</if>");
315 }
316 sqlBuffer.append("</trim>");
317 sqlBuffer.append("<trim prefix=\"VALUES (\" suffix=\")\" suffixOverrides=\",\">");
318 for (String field : columnMap.values()) {
319 sqlBuffer.append("<if test=\"").append(field).append(" != null\">");
320 sqlBuffer.append("#{").append(field).append("} ,");
321 sqlBuffer.append("</if>");
322 }
323 sqlBuffer.append("</trim>");
324 sqlBuffer.append("</script>");
325 return sqlBuffer.toString();
326 }
327
328 public String buildUpdateSelective(ProviderContext context) {
329 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
330 Map<String, String> columnMap = getColumnMap(context);
331 StringBuilder sqlBuffer = new StringBuilder();
332 sqlBuffer.append("<script>");
333 sqlBuffer.append("update ");
334 sqlBuffer.append(tableName);
335 sqlBuffer.append("<set>");
336 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
337 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
338 sqlBuffer.append(entry.getKey()).append(" = #{").append(entry.getValue()).append("} ,");
339 sqlBuffer.append("</if>");
340 }
341 sqlBuffer.append("</set>");
342
343 sqlBuffer.append("where id = #{id}");
344 sqlBuffer.append("</script>");
345 return sqlBuffer.toString();
346 }
347
348 public String buildGetByEntityQuery(ProviderContext context) {
349 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
350 Map<String, String> columnMap = getColumnMap(context);
351 StringBuilder sqlBuffer = new StringBuilder();
352 sqlBuffer.append("<script>");
353 sqlBuffer.append("select * from ");
354 sqlBuffer.append(tableName);
355 sqlBuffer.append("<where>");
356 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
357 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
358 sqlBuffer.append("and ").append(entry.getKey()).append(" = #{").append(entry.getValue()).append("}");
359 sqlBuffer.append("</if>");
360 }
361 sqlBuffer.append("</where>");
362 sqlBuffer.append("</script>");
363 return sqlBuffer.toString();
364 }
365
366 }