Dao层封装泛型实现(spring mvc,springjdbctemplate)
代码片段(6)
[全屏查看所有代码]
1. [代码]BaseDao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
package com.zjhc.commons.db.dao; import java.util.List; import java.util.Map; import com.zjhc.commons.domain.condition.Condition; import com.zjhc.commons.domain.mapper.MapRowMapper; import com.zjhc.commons.domain.model.DataStore; import com.zjhc.commons.domain.model.PagingParameter; import com.zjhc.commons.exception.DaoAccessException; /** * 数据查询DAO接口 * * 创建日期:2012-9-26 * @author wangk */ public interface BaseDao { /** * 查询SQL语句 * * @param sql SQL语句 * @param params SQL参数 * @return List<Map<String, Object>> 查询结果 * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public List<Map<String, Object>> search(String sql, Object... params) throws DaoAccessException; public List<Map<String, Object>> search(String sql, List<Object> params) throws DaoAccessException; public List<Map<String, Object>> search(String sql, Map<String, Object> params) throws DaoAccessException; /** * 查询SQL语句 * * @param <R> 行记录类型 * @param sql SQL语句 * @param mapRowMapper Map行数据映射对象 * @param params SQL参数 * @return List<R> 查询结果 * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, Object... params) throws DaoAccessException; public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, List<Object> params) throws DaoAccessException; public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, Map<String, Object> params) throws DaoAccessException; /** * 分页查询数据 * * @param sql SQL语句 * @param paging 分页参数 * @param params SQL参数 * @return DataStore<Map<String, Object>> 分页数据 * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, Object... params) throws DaoAccessException; public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, List<Object> params) throws DaoAccessException; public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, Map<String, Object> params) throws DaoAccessException; /** * 分页查询数据 * * @param <R> 行记录类型 * @param sql SQL语句 * @param mapRowMapper Map行数据映射对象 * @param paging 分页参数 * @param params SQL参数 * @return DataStore<R> 分页数据 * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, Object... params) throws DaoAccessException; public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, List<Object> params) throws DaoAccessException; public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, Map<String, Object> params) throws DaoAccessException; /** * 连接查询 * * @param condition 查询条件,指定列格式:表名.列名 * @param classLink 连接实体类类型链 * @return List<Map<String, Object>> 查询结果,Map.key: 对象名(Class指定的类名的首字母小写形式).属性名 * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public List<Map<String, Object>> join(Condition condition, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param condition 查询条件 * @param orders 排序对象 * @param classLink 连接实体类类型链 * @return 查询结果 * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public List<Map<String, Object>> join(Condition condition, String orders, Class<?>... classLink) throws DaoAccessException; /** * 连接查询(内连接) * * @param <R> 映射类型参数 * @param condition 查询条件 * @param mapRowMapper 行匹配对象 * @param classLink 连接实体类型链(从子表到父表的顺序) * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public <R> List<R> join(Condition condition, MapRowMapper<R> mapRowMapper, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param <R> 映射类型参数 * @param condition 查询条件 * @param orders 排序对象 * @param mapRowMapper 行匹配对象 * @param classLink 连接实体类型链 * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public <R> List<R> join(Condition condition, String orders, MapRowMapper<R> mapRowMapper, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param condition 查询条件 * @param paging 分页参数 * @param classLink 连接实体类型链 * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public DataStore<Map<String, Object>> join(Condition condition, PagingParameter paging, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param condition 查询条件 * @param orders 排序对象 * @param paging 分页参数 * @param classLink 连接实体类型链 * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public DataStore<Map<String, Object>> join(Condition condition, String orders, PagingParameter paging, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param <R> 映射类型参数 * @param condition 查询条件 * @param mapRowMapper 行匹配对象 * @param paging 分页参数 * @param classLink 连接实体类型链 * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public <R> DataStore<R> join(Condition condition, MapRowMapper<R> mapRowMapper, PagingParameter paging, Class<?>... classLink) throws DaoAccessException; /** * 连接查询 * * @param <R> 映射类型参数 * @param condition 查询条件 * @param orders 排序对象 * @param mapRowMapper 行匹配对象 * @param paging 分页参数 * @param classLink 连接实体类型链 * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ public <R> DataStore<R> join(Condition condition, String orders, MapRowMapper<R> mapRowMapper, PagingParameter paging, Class<?>... classLink) throws DaoAccessException; } |
2. [代码]BaseDaoSupport
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
|
package com.zjhc.commons.db.dao; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.zjhc.commons.db.Entity; import com.zjhc.commons.db.builder.PagingSqlBuilder; import com.zjhc.commons.db.builder.SimpleSqlBuilder; import com.zjhc.commons.domain.condition.Condition; import com.zjhc.commons.domain.mapper.MapRowMapper; import com.zjhc.commons.domain.model.DataStore; import com.zjhc.commons.domain.model.PagingParameter; import com.zjhc.commons.exception.DaoAccessException; /** * 数据查询DAO支持类 * * 创建日期:2012-9-26 * @author wangk */ public abstract class BaseDaoSupport implements BaseDao, InitializingBean { /** 日志对象 */ private static final Logger logger = Logger.getLogger(BaseDaoSupport. class ); /** 实现类日志对象 */ protected final Logger log = Logger.getLogger(getClass()); /** JDBC模版对象 */ @Autowired protected JdbcTemplate jdbcTemplate; /** SQL语句参数带名称的JDBC模版对象 */ protected NamedParameterJdbcTemplate namedParameterJdbcTemplate; /** 分页SQL语句创建对象 */ protected PagingSqlBuilder pagingSqlBuilder; /** * 获得JDBC模版对象 * * @return * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public JdbcTemplate getJdbcTemplate() { return jdbcTemplate; } /** * 获得SQL语句参数带名称的JDBC模版对象 * * @return * 创建日期:2012-12-19 * 修改说明: * @author wangk */ public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() { return namedParameterJdbcTemplate; } /** * 获得分页SQL语句创建对象 * * @return * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public PagingSqlBuilder getPagingSqlBuilder() { return pagingSqlBuilder; } /** * 初始化非注入的属性 * * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() * 创建日期:2012-12-19 * 修改说明: * @author wangk */ @Override public void afterPropertiesSet() throws Exception { //初始化namedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); //初始化pagingSqlBuilder pagingSqlBuilder = new PagingSqlBuilder(((ComboPooledDataSource) jdbcTemplate.getDataSource()).getJdbcUrl().replaceAll( "://.*$" , "" )); } @Override public List<Map<String, Object>> search(String sql, Object... params) throws DaoAccessException { try { logger.debug(sql); return jdbcTemplate.queryForList(sql, params); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public List<Map<String, Object>> search(String sql, List<Object> params) throws DaoAccessException { return search(sql, params.toArray()); } @Override public List<Map<String, Object>> search(String sql, Map<String, Object> params) throws DaoAccessException { try { logger.debug(sql); return namedParameterJdbcTemplate.queryForList(sql, params); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, Object... params) throws DaoAccessException { List<Map<String, Object>> list = search(sql, params); if (list == null ) { return null ; } List<R> ret = new ArrayList<R>(); for ( int i = 0 ; i < list.size(); i++) { ret.add(mapRowMapper.mapRow(list.get(i), i)); } return ret; } @Override public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, List<Object> params) throws DaoAccessException { return search(sql, mapRowMapper, params.toArray()); } @Override public <R> List<R> search(String sql, MapRowMapper<R> mapRowMapper, Map<String, Object> params) throws DaoAccessException { List<Map<String, Object>> list = search(sql, params); if (list == null ) { return null ; } List<R> ret = new ArrayList<R>(); for ( int i = 0 ; i < list.size(); i++) { ret.add(mapRowMapper.mapRow(list.get(i), i)); } return ret; } @Override public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, Object... params) throws DaoAccessException { try { PagingSqlBuilder pagingSqlBuilder = getPagingSqlBuilder(); int records = jdbcTemplate.queryForInt(pagingSqlBuilder.getCountSql(sql), params); if (records < 0 ) { return null ; } if (records == 0 ) { return new DataStore<Map<String, Object>>(records, new ArrayList<Map<String, Object>>()); } return new DataStore<Map<String, Object>>(records, search(pagingSqlBuilder.getPagingSql(sql, paging), params)); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, List<Object> params) throws DaoAccessException { return search(sql, paging, params.toArray()); } @Override public DataStore<Map<String, Object>> search(String sql, PagingParameter paging, Map<String, Object> params) throws DaoAccessException { try { PagingSqlBuilder pagingSqlBuilder = getPagingSqlBuilder(); int records = namedParameterJdbcTemplate.queryForInt(pagingSqlBuilder.getCountSql(sql), params); if (records < 0 ) { return null ; } if (records == 0 ) { return new DataStore<Map<String, Object>>(records, new ArrayList<Map<String, Object>>()); } return new DataStore<Map<String, Object>>(records, search(pagingSqlBuilder.getPagingSql(sql, paging), params)); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, Object... params) throws DaoAccessException { DataStore<Map<String, Object>> dataStore = search(sql, paging, params); if (dataStore == null ) { return null ; } if (dataStore.getDatas() == null ) { return new DataStore<R>(dataStore.getRecords(), null ); } List<R> list = new ArrayList<R>(); for ( int i = 0 ; i < dataStore.getDatas().size(); i++) { list.add(mapRowMapper.mapRow(dataStore.getDatas().get(i), i)); } return new DataStore<R>(dataStore.getRecords(), list); } @Override public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, List<Object> params) throws DaoAccessException { return search(sql, mapRowMapper, paging, params.toArray()); } @Override public <R> DataStore<R> search(String sql, MapRowMapper<R> mapRowMapper, PagingParameter paging, Map<String, Object> params) throws DaoAccessException { DataStore<Map<String, Object>> dataStore = search(sql, paging, params); if (dataStore == null ) { return null ; } if (dataStore.getDatas() == null ) { return new DataStore<R>(dataStore.getRecords(), null ); } List<R> list = new ArrayList<R>(); for ( int i = 0 ; i < dataStore.getDatas().size(); i++) { list.add(mapRowMapper.mapRow(dataStore.getDatas().get(i), i)); } return new DataStore<R>(dataStore.getRecords(), list); } @Override public List<Map<String, Object>> join(Condition condition, Class<?>... classLink) throws DaoAccessException { String orders = null ; return join(condition, orders, classLink); } @Override public List<Map<String, Object>> join(Condition condition, String orders, Class<?>... classLink) throws DaoAccessException { String sql = buildJoinSql(condition, orders, classLink); List<Map<String, Object>> result = null ; if (condition == null ) { result = search(sql); } else { result = search(sql, condition.getParameters()); } convertJoinResult(result, classLink); return result; } @Override public <R> List<R> join(Condition condition, MapRowMapper<R> mapRowMapper, Class<?>... classLink) throws DaoAccessException { return join(condition, null , mapRowMapper, classLink); } @Override public <R> List<R> join(Condition condition, String orders, MapRowMapper<R> mapRowMapper, Class<?>... classLink) throws DaoAccessException { List<Map<String, Object>> list = join(condition, orders, classLink); if (list == null ) { return null ; } List<R> ret = new ArrayList<R>(); for ( int i = 0 ; i < list.size(); i++) { ret.add(mapRowMapper.mapRow(list.get(i), i)); } return ret; } @Override public DataStore<Map<String, Object>> join(Condition condition, PagingParameter paging, Class<?>... classLink) throws DaoAccessException { String orders = null ; return join(condition, orders , paging, classLink); } @Override public DataStore<Map<String, Object>> join(Condition condition, String orders, PagingParameter paging, Class<?>... classLink) throws DaoAccessException { PagingSqlBuilder pagingSqlBuilder = getPagingSqlBuilder(); String sql = buildJoinSql(condition, orders, classLink); Object[] params = new Object[ 0 ]; if (condition != null ) { params = condition.getParameters(); } int records = 0 ; try { records = jdbcTemplate.queryForInt(pagingSqlBuilder.getCountSql(sql), params); } catch (Exception e) { throw new DaoAccessException(e); } if (records < 0 ) { return null ; } if (records == 0 ) { return new DataStore<Map<String, Object>>(records, new ArrayList<Map<String, Object>>()); } List<Map<String, Object>> datas = null ; datas = search(pagingSqlBuilder.getPagingSql(sql, paging), params); convertJoinResult(datas, classLink); return new DataStore<Map<String, Object>>(records, datas); } @Override public <R> DataStore<R> join(Condition condition, MapRowMapper<R> mapRowMapper, PagingParameter paging, Class<?>... classLink) throws DaoAccessException { return join(condition, null , mapRowMapper, paging, classLink); } @Override public <R> DataStore<R> join(Condition condition, String orders, MapRowMapper<R> mapRowMapper, PagingParameter paging, Class<?>... classLink) throws DaoAccessException { DataStore<Map<String, Object>> dataStore = join(condition, orders, paging, classLink); if (dataStore == null ) { return null ; } if (dataStore.getDatas() == null ) { return new DataStore<R>(dataStore.getRecords(), null ); } List<R> list = new ArrayList<R>(); for ( int i = 0 ; i < dataStore.getDatas().size(); i++) { list.add(mapRowMapper.mapRow(dataStore.getDatas().get(i), i)); } return new DataStore<R>(dataStore.getRecords(), list); } /** * 构建(内)连接SQL语句 * * @param condition * @param orders * @param classLink * @return * 创建日期:2012-10-19 * 修改说明: * @author wangk */ @SuppressWarnings ({ "rawtypes" , "unchecked" }) private String buildJoinSql(Condition condition, String orders, Class<?>... classLink) throws DaoAccessException { try { StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); for ( int i = 0 ;i < classLink.length;i++) { Class<? extends Entity> clazz = (Class<? extends Entity>)classLink[i]; SimpleSqlBuilder<? extends Entity> sqlBuilder1 = new SimpleSqlBuilder(clazz); String tableName1 = sqlBuilder1.getTableName(); Map<String, String> fieldColumnMapping1 = sqlBuilder1.getFieldColumnMapping(); for (String field : sqlBuilder1.getFieldColumnMapping().keySet()) { sb1.append(tableName1 + "." + fieldColumnMapping1.get(field) + " AS " + tableName1 + "_" + fieldColumnMapping1.get(field) + ", " ); } if (i == classLink.length - 1 ) { break ; } Class<? extends Entity> rClass = (Class<? extends Entity>)classLink[i+ 1 ]; SimpleSqlBuilder<? extends Entity> sqlBuilder2 = new SimpleSqlBuilder(rClass); String tableName2 = sqlBuilder2.getTableName(); if (i == 0 ) { sb2.append(tableName1); } sb2.append( " JOIN " + tableName2 + " ON " + tableName1 + "." + fieldColumnMapping1.get(sqlBuilder1.getReferenceField(rClass)) + " = " + tableName2 + "." + sqlBuilder1.getReferencedColumn(rClass)); } sb1.delete(sb1.length() - 2 , sb1.length()); String sql = "SELECT " + sb1 + " FROM " + sb2; if (condition != null ) { sql += " WHERE " + condition.toSqlString(); } if (orders != null ) { sql += " ORDER BY " + orders; } logger.debug(sql); return sql; } catch (Exception e) { throw new DaoAccessException(e); } } /** * 转换连接查询结果,Map对象的key值为:对象名.属性名 * * @param result * @param classLink * 创建日期:2012-10-19 * 修改说明: * @author wangk */ private void convertJoinResult(List<Map<String, Object>> result, Class<?>... classLink) throws DaoAccessException { if (CollectionUtils.isEmpty(result)) { return ; } for (Map<String, Object> map : result) { try { for (Class<?> clazz : classLink) { @SuppressWarnings ({ "rawtypes" , "unchecked" }) SimpleSqlBuilder<? extends Entity> sqlBuilder = new SimpleSqlBuilder(clazz); String tableName = sqlBuilder.getTableName(); Map<String, String> fieldColumnMapping = sqlBuilder.getFieldColumnMapping(); String className = clazz.getSimpleName(); String variableName = className.substring( 0 , 1 ).toLowerCase() + className.substring( 1 ); for (String field : fieldColumnMapping.keySet()) { map.put(variableName + "." + field, map.remove(tableName + "_" + fieldColumnMapping.get(field))); } } } catch (Exception e) { throw new DaoAccessException(e); } } } } |
3. [代码]EntityDao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
|
package com.zjhc.commons.db.dao; import java.util.List; import java.util.Map; import com.zjhc.commons.db.Entity; import com.zjhc.commons.domain.condition.Condition; import com.zjhc.commons.domain.model.DataStore; import com.zjhc.commons.domain.model.PagingParameter; import com.zjhc.commons.exception.DaoAccessException; /** * 实体类DAO接口 * * 创建日期:2012-9-24 * @author wangk */ public interface EntityDao<E extends Entity> extends BaseDao { /** * 根据ID值获得实体对象,可选参数associationLink,如果不指定只查询单个实体对象 * 否则使用左连接查询当前实体(左连接查询的主表)和associationLink指定的实体对象 * * @param id ID值 * @param associationLink <p>关联实体链,从当前实体的父表开始依次指定,必须按从子表到父表的顺序且不能间断 * 否则将抛出AnnotationNotFoundException * 如果有多个分支,则各分支可以依次指定,各个分支之间没有顺序 * </p> * @return E 实体对象,记录不存在时返回null * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public <K extends Number> E get(K id, Class<?>... associationLink) throws DaoAccessException; /** * 根据SQL语句获得实体对象, * * @param sql SQL语句 * @param params 查询参数 * @return E 没有记录返回null, 仅有一条记录返回实体对象,否则抛出DuplicatedRecordException * 如果SQL语句指定了查询列,则返回的实体对象只有相应的属性有值,其他为null * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public E get(String sql, Object... params) throws DaoAccessException; public E get(String sql, List<Object> params) throws DaoAccessException; public E get(String sql, Map<String, Object> params) throws DaoAccessException; /** * 根据Condition对象获得实体对象 * * @param condition <p>条件对象,条件出现的列如果没有指定所属表则默认为当前实体对应的表 * associationLink中的实体的列必须带所属表前缀,其格式为:表名.列名 * 如果associationLink中有相同的实体(包括和当前实体相同) * 则相同的实体必须在表名后加上实体序号后缀(第一个实体除外),其格式为:表名_序号.列名 * 当前实体的序号为0,associationLink中的第一个实体的序号为1,依次类推 * 如果associationLink中的实体对应的表名以‘_数字’结尾则指定列的所属表时必须加实体序号后缀 * </p> * @param associationLink 关联实体链,参数说明请参考get(id, associationLink) * @return E * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public E get(Condition condition, Class<?>... associationLink) throws DaoAccessException; /** * 通过ID值删除记录 * * @param id * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public <K extends Number> void delete(K id) throws DaoAccessException; /** * 新增记录(不指定ID值,ID值由数据库生成) * * @param <K> ID属性的类型参数 * @param entity 新增记录的实体对象,其ID属性值必须为空,否则将抛出DuplicateRecordException * @return K 数据库生成的ID值,接收返回值的变量类型必须和ID属性的类型相同,否则将抛出ClassCastException * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public <K extends Number> K save(E entity) throws DaoAccessException; /** * 新增记录(指定ID值) * * @param <K> ID属性的类型参数 * @param entity 新增记录的实体对象,其ID属性值必须为空,否则将抛出DuplicateRecordException * @param id ID值,如果指定的ID值为null,则ID值由数据库生成 * 创建日期:2012-12-7 * 修改说明: * @author wangk */ public <K extends Number> void save(E entity, K id) throws DaoAccessException; /** * 更新记录 * * @param entity * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public void update(E entity) throws DaoAccessException; /** * 新增或更新记录,ID值为空做新增操作,ID值非空做更新操作 * * @param entity * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public void saveOrUpdate(E entity) throws DaoAccessException; /** * 根据SQL语句查询记录 * * @param sql SQL语句,可以只是WHERE子句,为null或空字符串时表时查询全部记录 * @param params SQL参数 * @return List<E> 实体集合,若SQL语句指定了查询列,则实体对象中没有被指定列对应的属性为空值 * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public List<E> query(String sql, Object... params) throws DaoAccessException; public List<E> query(String sql, List<Object> params) throws DaoAccessException; public List<E> query(String sql, Map<String, Object> params) throws DaoAccessException; /** * 根据Condition对象查询记录 * * @param condition 参数说明请参考get(condition, associationLink) * @param associationLink * @return * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public List<E> query(Condition condition, Class<?>... associationLink) throws DaoAccessException; public List<E> query(Condition condition, String orders, Class<?>... associationLink) throws DaoAccessException; /** * 根据SQL语句和分页参数查询记录 * * @param sql 参数说明请参考query(sql, params) * @param paging * @param params * @return DataStore<E> 分页数据 * 创建日期:2012-9-26 * 修改说明: * @author wangk */ public DataStore<E> query(String sql, PagingParameter paging, Object... params) throws DaoAccessException; public DataStore<E> query(String sql, PagingParameter paging, List<Object> params) throws DaoAccessException; public DataStore<E> query(String sql, PagingParameter paging, Map<String, Object> params) throws DaoAccessException; /** * 根据Condition对象和分页参数查询记录 * * @param condition 参数说明请参考get(condition, associationLink) * @param paging * @return * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public DataStore<E> query(Condition condition, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException; public DataStore<E> query(Condition condition, String orders, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException; /** * 查询表里的所有记录 * * @param associationLink 参数说明请参考get(condition, associationLink) * @return * 创建日期:2012-10-20 * 修改说明: * @author wangk */ public List<E> queryAll(Class<?>... associationLink) throws DaoAccessException; public List<E> queryAll(String orders, Class<?>... associationLink) throws DaoAccessException; /** * 分页查询表里的所有记录 * * @param paging * @return * 创建日期:2012-10-20 * 修改说明: * @author wangk */ public DataStore<E> queryAll(PagingParameter paging, Class<?>... associationLink) throws DaoAccessException; public DataStore<E> queryAll(String orders, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException; /** * 计算表里的记录数 * * @return * 创建日期:2012-10-20 * 修改说明: * @author wangk */ public int count() throws DaoAccessException; public int count(Condition condition) throws DaoAccessException; /** * 批量删除 * * @param ids * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public <K extends Number> void deletes(List<K> ids) throws DaoAccessException; /** * 批量新增 * * @param <K> ID属性类型参数 * @param entitys 实体集合,各个对象的ID值必须为空,否则将抛出DuplicateRecordException * @param ids 指定ID集合,entitys的前ids.length个对象通过指定的ID值新增,其他的对象ID值由数据库生成 * @return * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public <K extends Number> void saves(List<E> entitys, K... ids) throws DaoAccessException; /** * 批量更新 * * @param entitys * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public void updates(List<E> entitys) throws DaoAccessException; /** * 批量新增或更新 * * @param entitys * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public void saveOrUpdates(List<E> entitys) throws DaoAccessException; /** * 获得实体对象的被引用对象,被引用对象类型和E的类型相同 * 例:获得某一地区的上一级地区 * * @param entity 实体对象 * @return E 被引用对象 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public E getReferenced(E entity) throws DaoAccessException; public E getReferenced(Object referenceValue) throws DaoAccessException; /** * 获得实体对象的被引用对象 * * @param <R> 被引用对象参数 * @param entity 实体对象 * @param referencedClass 被引用对象类型 * @return R 被引用对象 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public <R extends Entity> R getReferenced(E entity, Class<R> referencedClass) throws DaoAccessException; public <R extends Entity> R getReferenced(Object referenceValue, Class<R> referencedClass) throws DaoAccessException; /** * 查询被引用对象的所有引用对象,引用对象类型为E * (R可以和E相同,例:查询某一地区的所有下一级地区) * * @param <R> 被引用对象参数 * @param referenced 被引用对象 * @return List<E> 引用对象集合 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public <R extends Entity> List<E> queryReferences(R referenced) throws DaoAccessException; public <R extends Entity> List<E> queryReferences(Class<R> referencedClass, Object referencedValue) throws DaoAccessException; /** * 查询被引用对象的所有引用对象,引用对象类型由referenceClass指定 * (应用于关联表的DAO中) * * @param <R> 被引用对象参数 * @param <S> 引用对象参数 * @param referenced 被引用对象 * @param referenceClass 引用对象类型 * @return List<S> 引用对象集合 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public <R extends Entity, S extends Entity> List<S> queryReferences(R referenced, Class<S> referenceClass) throws DaoAccessException; public <R extends Entity, S extends Entity> List<S> queryReferences(Class<R> referencedClass, Object referencedValue, Class<S> referenceClass) throws DaoAccessException; /** * 查询被引用对象的引用对象分页数据,引用对象类型为E * * @param <R> 被引用对象参数 * @param referenced 被引用对象 * @param paging 分页参数 * @return DataStore<E> 引用对象分页数据 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public <R extends Entity> DataStore<E> queryReferences(R referenced, PagingParameter paging) throws DaoAccessException; public <R extends Entity> DataStore<E> queryReferences(Class<R> referencedClass, Object referencedValue, PagingParameter paging) throws DaoAccessException; /** * 查询被引用对象的引用对象分页数据,引用对象类型由referenceClass指定 * (应用于关联表的DAO中) * * @param <R> 被引用对象参数 * @param <S> 引用对象参数 * @param referenced 被引用对象 * @param referenceClass 引用对象类型 * @param paging 分页参数 * @return DataStore<S> 引用对象分页数据 * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public <R extends Entity, S extends Entity> DataStore<S> queryReferences(R referenced, Class<S> referenceClass, PagingParameter paging) throws DaoAccessException; public <R extends Entity, S extends Entity> DataStore<S> queryReferences(Class<R> referencedClass, Object referencedValue, Class<S> referenceClass, PagingParameter paging) throws DaoAccessException; } |
4. [代码]EntityDaoSupport
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
|
package com.zjhc.commons.db.dao; import java.beans.PropertyDescriptor; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import com.zjhc.commons.db.Entity; import com.zjhc.commons.db.annotation.Association; import com.zjhc.commons.db.annotation.Reference; import com.zjhc.commons.db.builder.SimpleSqlBuilder; import com.zjhc.commons.db.exception.AnnotationNotFoundException; import com.zjhc.commons.db.exception.DuplicateRecordException; import com.zjhc.commons.db.exception.ErrorCode; import com.zjhc.commons.db.exception.FieldColumnMappingException; import com.zjhc.commons.db.exception.IllegalRecordException; import com.zjhc.commons.domain.condition.Condition; import com.zjhc.commons.domain.model.DataStore; import com.zjhc.commons.domain.model.PagingParameter; import com.zjhc.commons.exception.DaoAccessException; import com.zjhc.commons.utils.ObjectUtil; /** * 实体Dao支持类 * * 创建日期:2012-9-24 * @author wangk */ public abstract class EntityDaoSupport<E extends Entity> extends BaseDaoSupport implements EntityDao<E> { /** 日志对象 */ private static final Logger logger = Logger.getLogger(BaseDaoSupport. class ); /** 条件关键字集合 */ private static final List<String> CONDITION_KEYWORDS = new ArrayList<String>(); /** 条件运算符(正则表达式形式)集合 */ private static final List<String> CONDITION_OPERATORS = new ArrayList<String>(); static { /** 初始化条件关键字集合 */ CONDITION_KEYWORDS.add( "IS" ); CONDITION_KEYWORDS.add( "NOT" ); CONDITION_KEYWORDS.add( "NULL" ); CONDITION_KEYWORDS.add( "LIKE" ); CONDITION_KEYWORDS.add( "BETWEEN" ); CONDITION_KEYWORDS.add( "AND" ); CONDITION_KEYWORDS.add( "OR" ); CONDITION_KEYWORDS.add( "IN" ); CONDITION_KEYWORDS.add( "ASC" ); CONDITION_KEYWORDS.add( "DESC" ); /** 初始化条件运算符集合(= < > + - * / % ( ) , ?),组合符号(<> <= >=)需要特殊处理 */ CONDITION_OPERATORS.add( "=" ); CONDITION_OPERATORS.add( "<" ); CONDITION_OPERATORS.add( ">" ); CONDITION_OPERATORS.add( "\\+" ); CONDITION_OPERATORS.add( "\\-" ); CONDITION_OPERATORS.add( "\\*" ); CONDITION_OPERATORS.add( "/" ); CONDITION_OPERATORS.add( "%" ); CONDITION_OPERATORS.add( "\\(" ); CONDITION_OPERATORS.add( "\\)" ); CONDITION_OPERATORS.add( "\\," ); CONDITION_OPERATORS.add( "\\?" ); } /** SQL语句构建对象 */ protected SimpleSqlBuilder<E> simpleSqlBuilder; /** 实体类类型 */ private Class<E> entityClass; /** * 构造方法 通过反射初始化entityClass * 创建日期:2012-10-8 * 修改说明: * @author wangk */ public EntityDaoSupport() { //获得EntityDaoSupport包含泛型实参的类型 ParameterizedType parameterizedType = (ParameterizedType)getClass().getGenericSuperclass(); Type[] params = parameterizedType.getActualTypeArguments(); @SuppressWarnings ( "unchecked" ) Class<E> entityClass = (Class<E>)params[ 0 ]; init(entityClass); } /** * 构造方法 * @param entityClass 实体类类型 * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public EntityDaoSupport(Class<E> entityClass) { init(entityClass); } /** * 初始化方法 * * @param entityClass 实体类类型 * 创建日期:2012-10-11 * 修改说明: * @author wangk */ private void init(Class<E> entityClass) { this .entityClass = entityClass; //初始化simpleSqlBuilder simpleSqlBuilder = new SimpleSqlBuilder<E>(entityClass); //检查实体所有的引用属性列是否存在和引用属性类型和被引用属性类型是否相同 simpleSqlBuilder.checkReferenceFields(); //检查关联属性是否存在非自身循环关联并记录debug级别日志 for (Class<?> association : simpleSqlBuilder.getAssociationLink()) { logger.debug(association.getName()); } } /** * 获得SQL语句构建对象 * * @return * 创建日期:2012-9-25 * 修改说明: * @author wangk */ public SimpleSqlBuilder<E> getSimpleSqlBuilder() { return simpleSqlBuilder; } @Override public <K extends Number> E get(K id, Class<?>... associationLink) throws DaoAccessException { if (associationLink != null && associationLink.length == 0 ) { try { return jdbcTemplate.queryForObject(simpleSqlBuilder.getQuerySimpleSql(), simpleSqlBuilder.getRowMapper(), id); } catch (EmptyResultDataAccessException e) { //只处理空结果异常,表示没有对应的记录,返回null logger.warn(e); return null ; } catch (Exception e) { throw new DaoAccessException(e); } } return get(Condition.eq(simpleSqlBuilder.getFieldColumnMapping().get( simpleSqlBuilder.getIdField()), id), associationLink); } @Override public E get(String sql, Object... params) throws DaoAccessException { return getUniqueEntity(query(sql, params)); } @Override public E get(String sql, List<Object> params) throws DaoAccessException { return get(sql, params.toArray()); } @Override public E get(String sql, Map<String, Object> params) throws DaoAccessException { return getUniqueEntity(query(sql, params)); } @Override public E get(Condition condition, Class<?>... associationLink) throws DaoAccessException { return getUniqueEntity(query(condition, associationLink)); } @Override public <K extends Number> K save(E entity) throws DaoAccessException { return saveWithId(entity, null ); } @Override public <K extends Number> void save(E entity, K id) throws DaoAccessException { saveWithId(entity, id); } @Override public void update(E entity) throws DaoAccessException { try { if (entity.isTransient()) { throw new IllegalRecordException(ErrorCode.ILLEGAL_RECORD_AS_UPDATE_TRANSIENT, "The record " + entity + " is transient!" ); } Map<String, Object> params = simpleSqlBuilder.getSqlParameters(entity); namedParameterJdbcTemplate.update(simpleSqlBuilder.getUpdateSql(params.keySet()), params); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public void saveOrUpdate(E entity) throws DaoAccessException { if (entity.isTransient()) { save(entity); } else { update(entity); } } @Override public <K extends Number> void delete(K id) throws DaoAccessException { try { jdbcTemplate.update(simpleSqlBuilder.getDeleteSql(), id); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public List<E> query(String sql, Object... params) throws DaoAccessException { return query(sql, null , params).getDatas(); } @Override public List<E> query(String sql, List<Object> params) throws DaoAccessException { return query(sql, params.toArray()); } @Override public List<E> query(String sql, Map<String, Object> params) throws DaoAccessException { return query(sql, null , params).getDatas(); } @Override public List<E> query(Condition condition, Class<?>... associationLink) throws DaoAccessException { String orders = null ; return query(condition, orders, associationLink); } @Override public List<E> query(Condition condition, String orders, Class<?>... associationLink) throws DaoAccessException { return query(condition, orders, null , associationLink).getDatas(); } @Override public DataStore<E> query(String sql, PagingParameter paging, Object... params) throws DaoAccessException { sql = handleSimpleSql(sql); return queryDataStore(sql, params, getRowMapperBySql(sql), paging); } @Override public DataStore<E> query(String sql, PagingParameter paging, List<Object> params) throws DaoAccessException { return query(sql, paging, params.toArray()); } @Override public DataStore<E> query(String sql, PagingParameter paging, Map<String, Object> params) throws DaoAccessException { sql = handleSimpleSql(sql); return queryDataStore(sql, params, getRowMapperBySql(sql), paging); } @Override public DataStore<E> query(Condition condition, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException { return query(condition, null , paging, associationLink); } @Override public DataStore<E> query(Condition condition, String orders, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException { Object[] params = new Object[ 0 ]; if (condition != null ) { params = condition.getParameters(); } if (associationLink != null && associationLink.length == 0 ) { String sql = condition== null ? "" :condition.toSqlString(); if (orders == null ) { orders = simpleSqlBuilder.getFieldColumnMapping().get(simpleSqlBuilder.getIdField()); } if (!sql.equals( "" )) { sql += " " ; } sql += "ORDER BY " + orders; return query(sql, paging, params); } return queryDataStore(buildAssociationSql(condition, orders, associationLink), params, simpleSqlBuilder.getRowMapper(associationLink), paging); } @Override public List<E> queryAll(Class<?>... associationLink) throws DaoAccessException { String orders = null ; return queryAll(orders, associationLink); } @Override public List<E> queryAll(String orders, Class<?>... associationLink) throws DaoAccessException { return query( null , orders, associationLink); } @Override public DataStore<E> queryAll(PagingParameter paging, Class<?>... associationLink) throws DaoAccessException { return queryAll( null , paging, associationLink); } @Override public DataStore<E> queryAll(String orders, PagingParameter paging, Class<?>... associationLink) throws DaoAccessException { return query( null , orders, paging, associationLink); } @Override public int count() throws DaoAccessException { return count( null ); } @Override public int count(Condition condition) throws DaoAccessException { try { String sql = simpleSqlBuilder.getQueryCountSql(); if (condition == null ) { return jdbcTemplate.queryForInt(sql); } sql += " WHERE " + condition.toSqlString(); logger.debug(sql); return jdbcTemplate.queryForInt(sql, condition.getParameters()); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public <K extends Number> void deletes(List<K> ids) throws DaoAccessException { if (CollectionUtils.isEmpty(ids)) { return ; } try { List<Object[]> batchArgs = new ArrayList<Object[]>(); for (K id : ids) { batchArgs.add( new Object[]{id}); } jdbcTemplate.batchUpdate(simpleSqlBuilder.getDeleteSql(), batchArgs); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public <K extends Number> void saves(List<E> entitys, K... ids) throws DaoAccessException { if (CollectionUtils.isEmpty(entitys)) { return ; } try { int entityCount = entitys.size(); int idCount = ids.length; if (idCount > entityCount) { idCount = entityCount; } List<E> withIdEntitys = entitys.subList( 0 , idCount); List<E> withoutIdEntitys = entitys.subList(idCount, entityCount); if (CollectionUtils.isNotEmpty(withIdEntitys)) { @SuppressWarnings ( "unchecked" ) Map<String, Object>[] batchArgs = new Map[idCount]; for ( int i = 0 ; i < idCount; i++) { E entity = withIdEntitys.get(i); if (!entity.isTransient()) { throw new DuplicateRecordException(ErrorCode.DUPLICATE_RECORDE_AS_SAVE_ENTITY, "The record that whoes id equals " + entity.identityString() + " is already exist!" ); } batchArgs[i] = simpleSqlBuilder.getAllSqlParameter(entity); batchArgs[i].put(simpleSqlBuilder.getIdField(), ids[i]); } namedParameterJdbcTemplate.batchUpdate(simpleSqlBuilder.getIncludeIdFieldInsertSql(), batchArgs); } if (CollectionUtils.isNotEmpty(withoutIdEntitys)) { @SuppressWarnings ( "unchecked" ) Map<String, Object>[] batchArgs = new Map[withoutIdEntitys.size()]; for ( int i = 0 ; i < batchArgs.length; i++) { E entity = withoutIdEntitys.get(i); if (!entity.isTransient()) { throw new DuplicateRecordException(ErrorCode.DUPLICATE_RECORDE_AS_SAVE_ENTITY, "The record that whoes id equals " + entity.identityString() + " is already exist!" ); } batchArgs[i] = simpleSqlBuilder.getAllSqlParameter(entity); } namedParameterJdbcTemplate.batchUpdate(simpleSqlBuilder.getInsertSql(), batchArgs); } } catch (Exception e) { throw new DaoAccessException(e); } } @Override public void updates(List<E> entitys) throws DaoAccessException { if (CollectionUtils.isEmpty(entitys)) { return ; } try { @SuppressWarnings ( "unchecked" ) Map<String, Object>[] batchArgs = new Map[entitys.size()]; for ( int i = 0 ; i < batchArgs.length; i++) { E entity = entitys.get(i); if (entity.isTransient()) { throw new IllegalRecordException(ErrorCode.ILLEGAL_RECORD_AS_UPDATE_TRANSIENT, "The record " + entity + " is transient!" ); } batchArgs[i] = simpleSqlBuilder.getAllSqlParameter(entity); } namedParameterJdbcTemplate.batchUpdate(simpleSqlBuilder.getUpdateSql(), batchArgs); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public void saveOrUpdates(List<E> entitys) throws DaoAccessException { if (CollectionUtils.isEmpty(entitys)) { return ; } List<E> saves = new ArrayList<E>(); List<E> updates = new ArrayList<E>(); for (E entity : entitys) { if (entity.isTransient()) { saves.add(entity); } else { updates.add(entity); } } saves(saves); updates(updates); } @Override public E getReferenced(E entity) throws DaoAccessException { return getReferenced(entity, entityClass); } @Override public E getReferenced(Object referenceValue) throws DaoAccessException { return getReferenced(referenceValue, entityClass); } @Override public <R extends Entity> R getReferenced(E entity, Class<R> referencedClass) throws DaoAccessException { Object value = null ; try { String field = simpleSqlBuilder.getReferenceField(referencedClass); if (field == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referencedClass.getName() + " of " + entityClass.getName()); } value = new PropertyDescriptor(field, entityClass).getReadMethod().invoke(entity); } catch (Exception e) { throw new DaoAccessException(e); } if (value == null ) { return null ; } return getReferenced(value, referencedClass); } @Override public <R extends Entity> R getReferenced(Object referenceValue, Class<R> referencedClass) throws DaoAccessException { try { String referencedColumn = simpleSqlBuilder.getReferencedColumn(referencedClass); if (referencedColumn == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referencedClass.getName() + " of " + entityClass.getName()); } SimpleSqlBuilder<R> referencedSqlBuilder = new SimpleSqlBuilder<R>(referencedClass); String sql = referencedSqlBuilder.getQueryAllSql() + " WHERE " + referencedColumn + " = ?" ; logger.debug(sql); return jdbcTemplate.queryForObject(sql, referencedSqlBuilder.getRowMapper(), referenceValue); } catch (Exception e) { throw new DaoAccessException(e); } } @Override public <R extends Entity> List<E> queryReferences(R referenced) throws DaoAccessException { PagingParameter paging = null ; return queryReferences(referenced, paging).getDatas(); } @Override public <R extends Entity> List<E> queryReferences(Class<R> referencedClass, Object referencedValue) throws DaoAccessException { PagingParameter paging = null ; return queryReferences(referencedClass, referencedValue, paging).getDatas(); } @Override public <R extends Entity, S extends Entity> List<S> queryReferences( R referenced, Class<S> referenceClass) throws DaoAccessException { return queryReferences(referenced, referenceClass, null ).getDatas(); } @Override public <R extends Entity, S extends Entity> List<S> queryReferences( Class<R> referencedClass, Object referencedValue, Class<S> referenceClass) throws DaoAccessException { return queryReferences(referencedClass, referencedValue, referenceClass, null ).getDatas(); } @Override public <R extends Entity> DataStore<E> queryReferences(R referenced, PagingParameter paging) throws DaoAccessException { Object value = getReferencedValue(referenced); if (value == null ) { return null ; } return queryReferences(referenced.getClass(), value, paging); } @Override public <R extends Entity> DataStore<E> queryReferences( Class<R> referencedClass, Object referencedValue, PagingParameter paging) throws DaoAccessException { String sql = null ; try { String field = simpleSqlBuilder.getReferenceField(referencedClass); if (field == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referencedClass.getName() + " of " + entityClass.getName()); } sql = simpleSqlBuilder.getQueryAllSql() + " WHERE " + simpleSqlBuilder.getFieldColumnMapping().get(field) + " = ? ORDER BY " + simpleSqlBuilder.getFieldColumnMapping().get(simpleSqlBuilder.getIdField()); } catch (Exception e) { throw new DaoAccessException(e); } return queryDataStore(sql, new Object[]{referencedValue}, simpleSqlBuilder.getRowMapper(), paging); } @Override public <R extends Entity, S extends Entity> DataStore<S> queryReferences( R referenced, Class<S> referenceClass, PagingParameter paging) throws DaoAccessException { Object value = getReferencedValue(referenced); if (value == null ) { return null ; } return queryReferences(referenced.getClass(), value, referenceClass, paging); } @Override public <R extends Entity, S extends Entity> DataStore<S> queryReferences( Class<R> referencedClass, Object referencedValue, Class<S> referenceClass, PagingParameter paging) throws DaoAccessException { String sql = null ; SimpleSqlBuilder<S> referenceSqlBuilder = null ; try { String referencedColumn = simpleSqlBuilder.getReferencedColumn(referenceClass); if (referencedColumn == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referenceClass.getName() + " of " + entityClass.getName()); } String field = simpleSqlBuilder.getReferenceField(referencedClass); if (field == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referencedClass.getName() + " of " + entityClass.getName()); } referenceSqlBuilder = new SimpleSqlBuilder<S>(referenceClass); sql = referenceSqlBuilder.getQueryAllSql() + " WHERE " + referencedColumn + " IN (SELECT " + simpleSqlBuilder.getFieldColumnMapping().get(simpleSqlBuilder.getReferenceField(referenceClass)) + " FROM " + simpleSqlBuilder.getTableName() + " WHERE " + simpleSqlBuilder.getFieldColumnMapping().get(field) + " = ?) ORDER BY " + referenceSqlBuilder.getFieldColumnMapping().get(referenceSqlBuilder.getIdField()); } catch (Exception e) { throw new DaoAccessException(e); } return queryDataStore(sql, new Object[]{referencedValue}, referenceSqlBuilder.getRowMapper(), paging); } /** * 根据被引用对象获得外键属性值 * * @param <R> * @param referenced * @return * 创建日期:2012-10-8 * 修改说明: * @author wangk */ private <R extends Entity> Object getReferencedValue(R referenced) throws DaoAccessException { try { @SuppressWarnings ( "unchecked" ) Class<R> referencedClass = (Class<R>)referenced.getClass(); String referencedColumn = simpleSqlBuilder.getReferencedColumn(referencedClass); if (referencedColumn == null ) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_REFERENCE, "Annotation " + Reference. class .getName() + " not found for referenced " + referencedClass.getName() + " of " + entityClass.getName()); } SimpleSqlBuilder<R> referencedSqlBuilder = new SimpleSqlBuilder<R>(referencedClass); String columnField = referencedSqlBuilder.getColumnField(referencedColumn); if (columnField == null ) { throw new FieldColumnMappingException(ErrorCode.FIELD_COLUMN_MAPPING_AS_NOT_EXIST_COLUMN, "ColumnName " + referencedColumn + " not exist for " + referencedClass.getName()); } return new PropertyDescriptor(columnField, referencedClass).getReadMethod().invoke(referenced); } catch (Exception e) { throw new DaoAccessException(e); } } /** * 构建关联查询SQL语句 * * @param condition 查询条件 * @param orders 排序对象 * @param associationLink 关联链 * @return String 关联查询SQL语句 * 创建日期:2012-12-5 * 修改说明: * @author wangk */ @SuppressWarnings ({ "rawtypes" , "unchecked" }) private String buildAssociationSql(Condition condition, String orders, Class<?>[] associationLink) throws DaoAccessException { try { if (associationLink == null ) { associationLink = simpleSqlBuilder.getAssociationLink(); } StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); String tableName = simpleSqlBuilder.getTableName() + "_0" ; Map<String, String> fieldColumnMapping = simpleSqlBuilder.getFieldColumnMapping(); for (String field : fieldColumnMapping.keySet()) { sb1.append(tableName + "." + fieldColumnMapping.get(field) + " AS " + tableName + "_" + fieldColumnMapping.get(field) + ", " ); } sb2.append(simpleSqlBuilder.getTableName()).append( " AS " ).append(tableName); //关联类型三标志(被关联类型下标、被关联类型、关联类型)集合 List<List<Object>> associationFlags = new ArrayList<List<Object>>(); for ( int i = 0 ;i < associationLink.length;i++) { Class<?> tempClass = associationLink[i]; if (!ObjectUtil.isExtends(tempClass, Entity. class )) { throw new FieldColumnMappingException(ErrorCode.FIELD_COLUMN_MAPPING_AS_ASSOCIATION_TYPE_ERROR, "Association " + tempClass.getName() + " type error for " + entityClass.getName() + ", the type must extends Entity!" ); } Class<? extends Entity> associationClass = (Class<? extends Entity>)tempClass; SimpleSqlBuilder<? extends Entity> associationSqlBuilder = new SimpleSqlBuilder(associationClass); Class<? extends Entity> clazz = null ; SimpleSqlBuilder<? extends Entity> sqlBuilder = null ; int j = - 1 ; for (; j < i; j++) { if (j >= 0 ) { clazz = (Class<? extends Entity>)associationLink[j]; } else { clazz = entityClass; } sqlBuilder = new SimpleSqlBuilder(clazz); if (sqlBuilder.getAssociationField(associationClass) != null ) { List<Object> associationFlag = new ArrayList<Object>(); associationFlag.add(j + 1 ); associationFlag.add(clazz); associationFlag.add(associationClass); if (!associationFlags.contains(associationFlag)) { //检查指定的关联类型对应的引用属性是否存在 sqlBuilder.checkExistReferenceField(associationClass); associationFlags.add(associationFlag); break ; } } } if (j == i) { throw new AnnotationNotFoundException(ErrorCode.ANNOTATION_NOT_FOUND_AS_ASSOCIATION, "Annotation " + Association. class .getName() + " not found for association " + associationClass.getName() + " of " + entityClass.getName()); } String tableName2 = associationSqlBuilder.getTableName() + "_" + (i + 1 ); Map<String, String> fieldColumnMapping2 = associationSqlBuilder.getFieldColumnMapping(); for (String field : fieldColumnMapping2.keySet()) { sb1.append(tableName2 + "." + fieldColumnMapping2.get(field) + " AS " + tableName2 + "_" + fieldColumnMapping2.get(field) + ", " ); } String tableName1 = sqlBuilder.getTableName() + "_" + (j + 1 ); Map<String, String> fieldColumnMapping1 = sqlBuilder.getFieldColumnMapping(); sb2.append( " LEFT JOIN " + associationSqlBuilder.getTableName() + " AS " + tableName2 + " ON " + tableName1 + "." + fieldColumnMapping1.get(sqlBuilder.getReferenceField(associationClass)) + " = " + tableName2 + "." + sqlBuilder.getReferencedColumn(associationClass)); } sb1.delete(sb1.length() - 2 , sb1.length()); String sql = "SELECT " + sb1 + " FROM " + sb2; if (condition != null ) { sql += " WHERE " + handleSqlColumnPrefix(condition.toSqlString(), associationLink); } if (orders == null ) { orders = simpleSqlBuilder.getFieldColumnMapping().get(simpleSqlBuilder.getIdField()); } sql += " ORDER BY " + handleSqlColumnPrefix(orders, associationLink); logger.debug(sql); return sql; } catch (Exception e) { throw new DaoAccessException(e); } } /** * 处理SQL子句的列名前缀,以区分来自不同的表 * 1. 没有前缀则加上:entityClass#tableName_0. * 2. 有前缀但没有下标则加上下标,如entityClass#tableName.处理成entityClass#tableName_0. * (关联链中有两个相同的类型时如果没有下标则加上第一次出现的下标,要指定后面类型的列必须带下标) * 3. entityClass下标为0,associationLink的第一个元素下标为1,依次类批(即数组下标加一) * 4. 出现的表名不能以'_数字'结尾 * * @param sql 条件SQL语句 * @param associationLink 关联链 * @return * 创建日期:2012-12-5 * 修改说明: * @author wangk */ private String handleSqlColumnPrefix(String sql, Class<?>[] associationLink) { if (sql == null ) { return null ; } StringBuilder sb = new StringBuilder(); int start = 0 ; int end = 0 ; for ( int i = 0 ; i < sql.length(); i++) { char ch = sql.charAt(i); if (ch == '\'' ) { end = i; sb.append(handleSubSqlColumnPrefix(sql.substring(start, end), associationLink)); start = end; for (i++; i < sql.length(); i++) { if (sql.charAt(i) == ch) { end = i + 1 ; sb.append(sql.substring(start, end)); start = end; break ; } } } else if (ch == '(' && sql.substring(i+ 1 ).trim().toUpperCase().startsWith( "SELECT" )) { end = i; sb.append(handleSubSqlColumnPrefix(sql.substring(start, end), associationLink)); start = end; Stack<Character> stack = new Stack<Character>(); stack.push(ch); for (i++; i < sql.length(); i++) { char ch2 = sql.charAt(i); if (ch2 == ch) { stack.push(ch); } else if (ch2 == ')' ) { stack.pop(); } if (stack.isEmpty()) { end = i + 1 ; sb.append(sql.substring(start, end)); start = end; break ; } } } } end = sql.length(); sb.append(handleSubSqlColumnPrefix(sql.substring(start, end), associationLink)); return sb.toString().trim(); } /** * 处理一段SQL子句的列名前缀,不包含子查询和字符串数据 * * @param subSql 一段SQL子句 * @param associationLink 关联链 * @return String 处理结果,结尾带空格 * 创建日期:2012-12-6 * 修改说明: * @author wangk */ private String handleSubSqlColumnPrefix(String subSql, Class<?>[] associationLink) { //处理组合符号(= -> #, < -> @, > -> &) subSql = subSql.replaceAll( "\\s*<>\\s*" , " @& " ).replaceAll( "\\s*<=\\s*" , " @# " ).replaceAll( "\\s*>=\\s*" , " &# " ); for (String operator : CONDITION_OPERATORS) { //处理单个符号 subSql = subSql.replaceAll( "\\s*" + operator + "\\s*" , " " + operator + " " ); } subSql = subSql.replaceAll( "@&" , "<>" ).replaceAll( "@#" , "<=" ).replaceAll( "&#" , ">=" ); String[] strings = subSql.split( "\\s+" ); StringBuilder sb = new StringBuilder(); for (String string : strings) { if (string.matches( "^[A-Za-z_][\\w]*(\\.\\w+)?$" ) && !CONDITION_KEYWORDS.contains(string.toUpperCase())) { sb.append(handleColumnPrefix(string, associationLink)); } else { sb.append(string); } sb.append( " " ); } return sb.toString(); } /** * 处理列名前缀 * * @param column 列名 * @param associationLink 关联链 * @return String 带前缀的列名 * 创建日期:2012-12-5 * 修改说明: * @author wangk */ @SuppressWarnings ({ "rawtypes" , "unchecked" }) private String handleColumnPrefix(String column, Class<?>[] associationLink) { if (column.indexOf( "." ) < 0 ) { return simpleSqlBuilder.getTableName() + "_0." + column; } String[] strings = column.split( "\\." ); String tableName = strings[ 0 ]; if (!tableName.matches( "^.*_\\d+$" )) { int index = 0 ; if (!tableName.equalsIgnoreCase(simpleSqlBuilder.getTableName())) { int i = 0 ; for (; i < associationLink.length; i++) { if (tableName.equalsIgnoreCase( new SimpleSqlBuilder(associationLink[i]).getTableName())) { break ; } } index = i + 1 ; } return tableName + "_" + index + "." + strings[ 1 ]; } return column; } /** * 获得指定entitys的唯一实体对象,没有返回null,两个及以上抛出DuplicateRecordException * * @param entitys 实体集合 * @return * 创建日期:2012-12-6 * 修改说明: * @author wangk */ private E getUniqueEntity(List<E> entitys) { if (CollectionUtils.isEmpty(entitys)) { return null ; } if (entitys.size() == 1 ) { return entitys.get( 0 ); } throw new DuplicateRecordException(ErrorCode.DUPLICATE_RECORDE_AS_GET_ENTITY); } /** * 保存实体对象,ID值由参数指定,如果ID指定为null则由数据库生成 * * @param <K> ID类型参数 * @param entity 实体对象 * @param id ID值 * @return * 创建日期:2012-12-3 * 修改说明: * @author wangk */ private <K extends Number> K saveWithId(E entity, K id) throws DaoAccessException { try { if (!entity.isTransient()) { throw new DuplicateRecordException(ErrorCode.DUPLICATE_RECORDE_AS_SAVE_ENTITY, "The record " + entity + " is exist!" ); } @SuppressWarnings ( "unchecked" ) Class<K> idFieldType = (Class<K>) new PropertyDescriptor(simpleSqlBuilder.getIdField(), entityClass).getPropertyType(); Map<String, Object> params = simpleSqlBuilder.getSqlParameters(entity); if (id == null ) { String sql = simpleSqlBuilder.getInsertSql(params.keySet()); KeyHolder keyHolder = new GeneratedKeyHolder(); namedParameterJdbcTemplate.update(sql, new MapSqlParameterSource(params), keyHolder); id = idFieldType.getConstructor(String. class ).newInstance(keyHolder.getKey().toString()); } else { params.put(simpleSqlBuilder.getIdField(), id); String sql = simpleSqlBuilder.getIncludeIdFieldInsertSql(params.keySet()); namedParameterJdbcTemplate.update(sql, params); } //设置entity的ID值 new PropertyDescriptor(simpleSqlBuilder.getIdField(), entityClass).getWriteMethod().invoke(entity, id); return id; } catch (Exception e) { throw new DaoAccessException(e); } } /** * 处理单表查询的SQL语句,SQL为null或空字符串或只指定WHERE子句时处理成查询全部记录 * * @param sql SQL语句 * @return String 处理后的SQL语句 * 创建日期:2012-12-6 * 修改说明: * @author wangk */ private String handleSimpleSql(String sql) { if (StringUtils.isBlank(sql)) { sql = simpleSqlBuilder.getQueryAllSql(); } else if (!sql.trim().toUpperCase().startsWith( "SELECT" )) { if (!sql.trim().toUpperCase().startsWith( "WHERE" ) && !sql.trim().toUpperCase().startsWith( "ORDER" )) { sql = "WHERE " + sql; } sql = simpleSqlBuilder.getQueryAllSql() + " " + sql; } logger.debug(sql); return sql; } /** * 根据SQL语句获取不同的RowMapper,如果指定了投影列则只映射指定列对应的属性,其他属性为null,否则映射全部属性 * * @param sql SQL语句 * @return RowMapper<E> 记录映射对象 * 创建日期:2012-12-6 * 修改说明: * @author wangk */ private RowMapper<E> getRowMapperBySql(String sql) { sql = sql.trim().toUpperCase(); String projection = sql.substring(sql.indexOf( "SELECT" )+ 6 , sql.indexOf( "FROM" )).trim(); if (projection.indexOf( "*" ) >= 0 ) { return simpleSqlBuilder.getRowMapper(); } Set<String> columns = new HashSet<String>(); for (String column : projection.split( "," )) { columns.add(column.trim().replaceAll( "\\s.*$" , "" )); } return simpleSqlBuilder.getRowMapper(columns); } /** * 查询分页数据,如果指定的paging为null或参数不正确则查询出全部的数据 * * @param <T> SQL参数类型,限制只能使用Object[]或Map<String, Object> * @param sql SQL语句 * @param params SQL参数 * @param rowMapper 记录映射对象 * @param paging 分页参数 * @return DataStore<E> 分页数据 * @throws DaoAccessException DAO访问异常 * 创建日期:2012-12-6 * 修改说明: * @author wangk */ @SuppressWarnings ( "unchecked" ) private <P, S extends Entity> DataStore<S> queryDataStore( String sql, P params, RowMapper<S> rowMapper, PagingParameter paging) throws DaoAccessException { try { if (paging == null || paging.isInvalid()) { if (params instanceof Map) { return new DataStore<S>(paging, namedParameterJdbcTemplate.query(sql, new MapSqlParameterSource((Map<String, Object>)params), rowMapper)); } return new DataStore<S>(paging, jdbcTemplate.query(sql, rowMapper, (Object[])params)); } int records = 0 ; if (params instanceof Map) { records = namedParameterJdbcTemplate.queryForInt(pagingSqlBuilder.getCountSql(sql), (Map<String, Object>)params); } else { records = jdbcTemplate.queryForInt(pagingSqlBuilder.getCountSql(sql), (Object[])params); } if (records < 0 ) { return null ; } if (records == 0 ) { return new DataStore<S>(records, new ArrayList<S>()); } if (params instanceof Map) { return new DataStore<S>(records, namedParameterJdbcTemplate.query( pagingSqlBuilder.getPagingSql(sql, paging), new MapSqlParameterSource((Map<String, Object>)params), rowMapper)); } return new DataStore<S>(records, jdbcTemplate.query(pagingSqlBuilder.getPagingSql(sql, paging), rowMapper, (Object[])params)); } catch (Exception e) { throw new DaoAccessException(e); } } } |
Dao层封装泛型实现(spring mvc,springjdbctemplate)的更多相关文章
- dao层的泛型实现(2种方法)
一: package com.wzs.test2.dao; import java.util.List; public interface CommonDAO { public <T> v ...
- jdbcTemplate的Dao层封装
package com.easyrail.base.dao; import java.io.Serializable; import java.lang.reflect.Field; import j ...
- 封装fastjson为spring mvc的json view
可以将其中的main方法删掉.测试用的.我测试的结果是,jackson比fastjson快. fastjson是1.1.36 jackson是2.2.3 jdk是1.7.40,client cpu是i ...
- Intellij IDEA采用Maven+Spring MVC+Hibernate的架构搭建一个java web项目
原文:Java web 项目搭建 Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring ...
- Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解(三)
前两章我为大家详细介绍了如何搭建Maven环境.Spring MVC的流程结构.Spring MVC与Struts2的区别以及示例中的一些配置文件的分析.在这一章,我就对示例的层次结构进行说明,以及M ...
- springboot 注册dao层 service 层
可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...
- 【深度分析】:阿里,腾讯面试题 SpringBoot整合Spring MVC
Java学习总结 SpringBoot整合Spring MVC 1.SpringMVC概述 MVC(Model–view–controller)是软件工程中的一种软件架构模式,基于此模式把软件系统分为 ...
- Spring mvc Json 的正确返回姿势
我们经常都需要封装统一JSON格式 例如以下形式 { “data”:“输出的数据”, “code”:“响应代码”, “msg”:“响应信息” } /** * Created by linli on 2 ...
- Spring MVC入门
1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...
随机推荐
- VB.NET中文双引号的处理方法
相信朋友们也都碰到了这样的问题了,VS的IDE会不分青红皂白的把中文双引号变成英文的双引号,当然可以通过关闭自动重排功能来回避这个问题,但不是一个好的解决办法,以下这个方式不错: 如果在实际的使用中我 ...
- POJ 3622 multiset
思路: 放一个链接 是我太懒了 http://blog.csdn.net/mars_ch/article/details/52835978 嗯她教的我(姑且算是吧) (一通乱搞就出来了-) //By ...
- DataTable中Compute计算函数
DataTable dt = new DataTable(); //嵌套的三元运算 牛叉到五体投地 object obj = dt.Compute("iif(1000=5,1000,iif( ...
- 【Django】安装及配置
目录 MVC框架与MTV框架 Django的MTV模式 Django框架图示 安装及配置 创建一个Django项目 目录介绍 运行Django项目 启动Django报错 模版文件配置 静态文件配置 A ...
- OpenJDK源码研究笔记(十一):浅析Javac编译过程中的抽象语法树(IfElse,While,Switch等语句的抽象和封装)
浅析OpenJDK源码编译器Javac的语法树包com.sun.source.tree. 抽象语法树,是编译原理中的经典问题,有点难,本文只是随便写写. 0.赋值语句 public interface ...
- React Native入门——IDE及其它相关基础技术
关于React Native的开发,当中一个问题是缺少好用的IDE,有些人说不就是JS么,搞一个记事本也就写了,那样尽管牛逼,但事实上还是非常头大的,有一款好的IDE还是能提升开发效率的,这里对几个还 ...
- 用MediaRecorder实现简单的录像功能
思路:定义一个SurfaceView用来显示预览,在SurfaceHolder的回调中用Camera对象启动预览.然后调用MediaRecorder来录像.仅仅是实现了简单的录像開始和停止功能.顶部能 ...
- java正則表達式总结
近期用到的正則表達式 因为近期在做一个android的新闻client.多次用到了正則表達式.因此总结下. 1.使用正則表達式获取Rss资源内的文章内容的图片url 由于在每条新闻浏览的listVie ...
- Android 学习笔记之Bitmap位图的缩放
位图的缩放也可以借助Matrix或者Canvas来实现. 通过postScale(0.5f, 0.3f)方法设置旋转角度,然后用createBitmap方法创建一个经过缩放处理的Bitmap对象,最后 ...
- html5中的空格符
html5中的空格符 1,Html中空格 不断行的空白(1个字符宽度) 半个空白(1个字符宽度) 一个空白(2个字符宽度) 窄空白(小于1个字符宽度) 2,Css ...