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 SELECT("*");
64 FROM("users");
65 if (criteria.getId() != null) {
66 WHERE("id = #{id}");
67 }
68 if (criteria.getName() != null) {
69 WHERE("name like #{name} || '%'");
70 }
71 }}.toString();
72 }
73
74 public String buildGetUsersByCriteriaMapQuery(final Map<String, Object> criteria) {
75 return new SQL(){{
76 SELECT("*");
77 FROM("users");
78 if (criteria.get("id") != null) {
79 WHERE("id = #{id}");
80 }
81 if (criteria.get("name") != null) {
82 WHERE("name like #{name} || '%'");
83 }
84 }}.toString();
85 }
86
87 public String buildGetUsersByCriteriaMapWithParamQuery(@Param("id") Integer id, @Param("name") String name) {
88 return new SQL() {{
89 SELECT("*");
90 FROM("users");
91 if (id != null) {
92 WHERE("id = #{id}");
93 }
94 if (name != null) {
95 WHERE("name like #{name} || '%'");
96 }
97 }}.toString();
98 }
99
100 public String buildGetUsersByNameQuery(final String name, final String orderByColumn) {
101 return new SQL(){{
102 SELECT("*");
103 FROM("users");
104 if (name != null) {
105 WHERE("name like #{param1} || '%'");
106 }
107 ORDER_BY(orderByColumn);
108 }}.toString();
109 }
110
111 public String buildGetUsersByNameUsingMap(Map<String, Object> params) {
112 final String name = String.class.cast(params.get("param1"));
113 final String orderByColumn = String.class.cast(params.get("param2"));
114 return new SQL(){{
115 SELECT("*");
116 FROM("users");
117 if (name != null) {
118 WHERE("name like #{param1} || '%'");
119 }
120 ORDER_BY(orderByColumn);
121 }}.toString();
122 }
123
124 public String buildGetUsersByNameWithParamNameAndOrderByQuery(@Param("orderByColumn") final String orderByColumn, @Param("name") final String name) {
125 return new SQL(){{
126 SELECT("*");
127 FROM("users");
128 if (name != null) {
129 WHERE("name like #{name} || '%'");
130 }
131 ORDER_BY(orderByColumn);
132 }}.toString();
133 }
134
135 public String buildGetUsersByNameWithParamNameQuery(@Param("name") final String name) {
136 return new SQL(){{
137 SELECT("*");
138 FROM("users");
139 if (name != null) {
140 WHERE("name like #{name} || '%'");
141 }
142 ORDER_BY("id DESC");
143 }}.toString();
144 }
145
146 public String buildGetUsersByNameWithParamNameQueryUsingMap(Map<String, Object> params) {
147 final String name = String.class.cast(params.get("name"));
148 final String orderByColumn = String.class.cast(params.get("orderByColumn"));
149 return new SQL(){{
150 SELECT("*");
151 FROM("users");
152 if (name != null) {
153 WHERE("name like #{param1} || '%'");
154 }
155 ORDER_BY(orderByColumn);
156 }}.toString();
157 }
158
159 public String buildInsert() {
160 return "insert into users (id, name) values (#{id}, #{name})";
161 }
162
163 public String buildUpdate() {
164 return "update users set name = #{name} where id = #{id}";
165 }
166
167 public String buildDelete() {
168 return "delete from users where id = #{id}";
169 }
170
171 public String buildSelectByIdProviderContextOnly(ProviderContext context) {
172 final boolean containsLogicalDelete = context.getMapperMethod().getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
173 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
174 return new SQL(){{
175 SELECT("*");
176 FROM(tableName);
177 WHERE("id = #{id}");
178 if (!containsLogicalDelete){
179 WHERE("logical_delete = ${Constants.LOGICAL_DELETE_OFF}");
180 }
181 }}.toString();
182 }
183
184 public String buildSelectByNameOneParamAndProviderContext(ProviderContext context, final String name) {
185 final boolean containsLogicalDelete = context.getMapperMethod().getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
186 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
187 return new SQL(){{
188 SELECT("*");
189 FROM(tableName);
190 if (name != null) {
191 WHERE("name like #{name} || '%'");
192 }
193 if (!containsLogicalDelete){
194 WHERE("logical_delete = ${LOGICAL_DELETE_OFF:0}");
195 }
196 }}.toString();
197 }
198
199 public String buildSelectByIdAndNameMultipleParamAndProviderContextWithAtParam(@Param("id") final Integer id, ProviderContext context, @Param("name") final String name) {
200 final boolean containsLogicalDelete = context.getMapperMethod().getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
201 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
202 return new SQL(){{
203 SELECT("*");
204 FROM(tableName);
205 if (id != null) {
206 WHERE("id = #{id}");
207 }
208 if (name != null) {
209 WHERE("name like #{name} || '%'");
210 }
211 if (!containsLogicalDelete){
212 WHERE("logical_delete = false");
213 }
214 }}.toString();
215 }
216
217 public String buildSelectByIdAndNameMultipleParamAndProviderContext(final Integer id, final String name, ProviderContext context) {
218 final boolean containsLogicalDelete = context.getMapperMethod().getAnnotation(BaseMapper.ContainsLogicalDelete.class) != null;
219 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
220 return new SQL(){{
221 SELECT("*");
222 FROM(tableName);
223 if (id != null) {
224 WHERE("id = #{param1}");
225 }
226 if (name != null) {
227 WHERE("name like #{param2} || '%'");
228 }
229 if (!containsLogicalDelete){
230 WHERE("logical_delete = false");
231 }
232 }}.toString();
233 }
234
235 private Class<?> getEntityClass(ProviderContext providerContext) {
236 Method mapperMethod = providerContext.getMapperMethod();
237 Class<?> declaringClass = mapperMethod.getDeclaringClass();
238 Class<?> mapperClass = providerContext.getMapperType();
239
240 Type[] types = mapperClass.getGenericInterfaces();
241 for (Type type : types) {
242 if (type instanceof ParameterizedType) {
243 ParameterizedType t = (ParameterizedType) type;
244 if (t.getRawType() == declaringClass || mapperClass.isAssignableFrom((Class<?>) t.getRawType())) {
245 Class<?> returnType = (Class<?>) t.getActualTypeArguments()[0];
246 return returnType;
247 }
248 }
249 }
250 throw new RuntimeException("The interface [" + mapperClass.getCanonicalName() + "] must specify a generic type.");
251 }
252
253 private Map<String, String> getColumnMap(ProviderContext context) {
254 Class<?> entityClass = getEntityClass(context);
255 Field[] fields = entityClass.getDeclaredFields();
256 Map<String, String> columnMap = new LinkedHashMap<String, String>();
257 for (Field field : fields) {
258 BaseMapper.Column column = field.getAnnotation(BaseMapper.Column.class);
259 if (column != null) {
260 String columnName = column.value();
261 if (columnName == null || columnName.length() == 0) {
262 columnName = field.getName();
263 }
264 columnMap.put(columnName, field.getName());
265 }
266 }
267 if (columnMap.size() == 0) {
268 throw new RuntimeException("There is no field in the class [" + entityClass.getCanonicalName()
269 + "] that specifies the @BaseMapper.Column annotation.");
270 }
271 return columnMap;
272 }
273
274 public String buildInsertSelective(ProviderContext context) {
275 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
276 Map<String, String> columnMap = getColumnMap(context);
277 StringBuilder sqlBuffer = new StringBuilder();
278 sqlBuffer.append("<script>");
279 sqlBuffer.append("insert into ");
280 sqlBuffer.append(tableName);
281 sqlBuffer.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
282 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
283 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
284 sqlBuffer.append(entry.getKey()).append(",");
285 sqlBuffer.append("</if>");
286 }
287 sqlBuffer.append("</trim>");
288 sqlBuffer.append("<trim prefix=\"VALUES (\" suffix=\")\" suffixOverrides=\",\">");
289 for (String field : columnMap.values()) {
290 sqlBuffer.append("<if test=\"").append(field).append(" != null\">");
291 sqlBuffer.append("#{").append(field).append("} ,");
292 sqlBuffer.append("</if>");
293 }
294 sqlBuffer.append("</trim>");
295 sqlBuffer.append("</script>");
296 return sqlBuffer.toString();
297 }
298
299 public String buildUpdateSelective(ProviderContext context) {
300 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
301 Map<String, String> columnMap = getColumnMap(context);
302 StringBuilder sqlBuffer = new StringBuilder();
303 sqlBuffer.append("<script>");
304 sqlBuffer.append("update ");
305 sqlBuffer.append(tableName);
306 sqlBuffer.append("<set>");
307 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
308 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
309 sqlBuffer.append(entry.getKey()).append(" = #{").append(entry.getValue()).append("} ,");
310 sqlBuffer.append("</if>");
311 }
312 sqlBuffer.append("</set>");
313
314 sqlBuffer.append("where id = #{id}");
315 sqlBuffer.append("</script>");
316 return sqlBuffer.toString();
317 }
318
319 public String buildGetByEntityQuery(ProviderContext context) {
320 final String tableName = context.getMapperType().getAnnotation(BaseMapper.Meta.class).tableName();
321 Map<String, String> columnMap = getColumnMap(context);
322 StringBuilder sqlBuffer = new StringBuilder();
323 sqlBuffer.append("<script>");
324 sqlBuffer.append("select * from ");
325 sqlBuffer.append(tableName);
326 sqlBuffer.append("<where>");
327 for (Map.Entry<String, String> entry : columnMap.entrySet()) {
328 sqlBuffer.append("<if test=\"").append(entry.getValue()).append(" != null\">");
329 sqlBuffer.append("and ").append(entry.getKey()).append(" = #{").append(entry.getValue()).append("}");
330 sqlBuffer.append("</if>");
331 }
332 sqlBuffer.append("</where>");
333 sqlBuffer.append("</script>");
334 return sqlBuffer.toString();
335 }
336
337 }