Commit 7de08bb02302ea0169762d508ac55e51eec3356f
1 parent
9fee2037
Exists in
master
and in
2 other branches
增加支持广播SQL
Showing
11 changed files
with
2428 additions
and
26 deletions
Show diff stats
build.gradle
@@ -57,7 +57,7 @@ uploadArchives { | @@ -57,7 +57,7 @@ uploadArchives { | ||
57 | authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD) | 57 | authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD) |
58 | } | 58 | } |
59 | pom.project { | 59 | pom.project { |
60 | - version '2.1.48' | 60 | + version '2.1.52' |
61 | artifactId ARTIFACT_Id | 61 | artifactId ARTIFACT_Id |
62 | groupId GROUP_ID | 62 | groupId GROUP_ID |
63 | packaging TYPE | 63 | packaging TYPE |
src/main/java/com/taover/repository/CustomJdbcTemplateBroadcast.java
0 → 100644
@@ -0,0 +1,546 @@ | @@ -0,0 +1,546 @@ | ||
1 | +package com.taover.repository; | ||
2 | + | ||
3 | +import java.io.Serializable; | ||
4 | +import java.lang.reflect.Field; | ||
5 | +import java.lang.reflect.ParameterizedType; | ||
6 | +import java.math.BigDecimal; | ||
7 | +import java.util.ArrayList; | ||
8 | +import java.util.HashMap; | ||
9 | +import java.util.Iterator; | ||
10 | +import java.util.List; | ||
11 | +import java.util.Map; | ||
12 | + | ||
13 | +import javax.annotation.Resource; | ||
14 | +import javax.persistence.Column; | ||
15 | +import javax.persistence.Id; | ||
16 | +import javax.persistence.Table; | ||
17 | + | ||
18 | +import org.springframework.dao.DataAccessException; | ||
19 | + | ||
20 | +import com.taover.repository.exception.MultiRowException; | ||
21 | +import com.taover.repository.exception.NoContainTenantException; | ||
22 | +import com.taover.repository.exception.NotFoundException; | ||
23 | +import com.taover.repository.exception.ObjectReflectException; | ||
24 | +import com.taover.repository.jdbctemplate.JdbcTemplateBroadcast; | ||
25 | +import com.taover.repository.mapper.CustomJdbcTemplateRowMapper; | ||
26 | +import com.taover.repository.util.UtilsSql; | ||
27 | + | ||
28 | +/** | ||
29 | + * | ||
30 | + * @author root | ||
31 | + * | ||
32 | + * @param <T> | ||
33 | + * @param <ID> | ||
34 | + */ | ||
35 | +public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements CustomJdbcTemplateBroadcastInterface<T, ID>{ | ||
36 | + @Resource | ||
37 | + private JdbcTemplateBroadcast _jdbcTemplateBroadcast; | ||
38 | + | ||
39 | + private Map<String, String> _beanToTableField; | ||
40 | + private Map<String, String> _tableToBeanField; | ||
41 | + private String _tableFieldNameListGapWithComma; | ||
42 | + private String _idTableFieldName; | ||
43 | + private String _dbName; | ||
44 | + private String _tableName; | ||
45 | + private Class<T> _tClassInfo; | ||
46 | + private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; | ||
47 | + | ||
48 | + public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ | ||
49 | + return this._customJdbcTemplateRowMapper; | ||
50 | + } | ||
51 | + | ||
52 | + @SuppressWarnings("unchecked") | ||
53 | + public CustomJdbcTemplateBroadcast() throws Exception{ | ||
54 | + //获取泛型类Class | ||
55 | + this._tClassInfo = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | ||
56 | + | ||
57 | + //检查实体声明 | ||
58 | + Table annoTable = (Table) _tClassInfo.getAnnotation(Table.class); | ||
59 | + if(annoTable == null){ | ||
60 | + throw new Exception("DAO层初始化失败,失败原因:"+_tClassInfo.getName()+"实体类,没有@Table注解指定表名"); | ||
61 | + } | ||
62 | + this._tableName = annoTable.name(); | ||
63 | + String schema = annoTable.schema(); | ||
64 | + String catalog = annoTable.catalog(); | ||
65 | + if(schema != null && !"".equals(schema)){ | ||
66 | + this._dbName = schema; | ||
67 | + }else if(catalog != null && !"".equals(catalog)){ | ||
68 | + this._dbName = catalog; | ||
69 | + } | ||
70 | + | ||
71 | + //初始化数据 | ||
72 | + _beanToTableField = new HashMap<String, String>(); | ||
73 | + _tableToBeanField = new HashMap<String, String>(); | ||
74 | + _tableFieldNameListGapWithComma = ""; | ||
75 | + Field[] declaredFields = _tClassInfo.getDeclaredFields(); | ||
76 | + for(int i=0; i<declaredFields.length; ++i){ | ||
77 | + Field currField = declaredFields[i]; | ||
78 | + String fieldName = currField.getName(); | ||
79 | + Id annoId = (Id)currField.getAnnotation(Id.class); | ||
80 | + Column annoColumn = (Column)currField.getAnnotation(Column.class); | ||
81 | + if(annoId != null){ | ||
82 | + if(annoColumn == null){ | ||
83 | + _idTableFieldName = this.camelToUnderline(fieldName); | ||
84 | + }else{ | ||
85 | + _idTableFieldName = annoColumn.name(); | ||
86 | + } | ||
87 | + _tableFieldNameListGapWithComma += _idTableFieldName+","; | ||
88 | + _beanToTableField.put(fieldName, _idTableFieldName); | ||
89 | + _tableToBeanField.put(_idTableFieldName, fieldName); | ||
90 | + }else{ | ||
91 | + if(annoColumn != null){ | ||
92 | + String tableFieldName = annoColumn.name(); | ||
93 | + _tableFieldNameListGapWithComma += tableFieldName+","; | ||
94 | + _beanToTableField.put(fieldName, tableFieldName); | ||
95 | + _tableToBeanField.put(tableFieldName, fieldName); | ||
96 | + } | ||
97 | + } | ||
98 | + } | ||
99 | + | ||
100 | + //检验是否有属性 | ||
101 | + if(_beanToTableField.isEmpty()){ | ||
102 | + throw new Exception("DAO层初始化失败,失败原因:"+this._tClassInfo.getName()+"实体类,没有在实体中找到属性信息"); | ||
103 | + } | ||
104 | + | ||
105 | + //去除逗号 | ||
106 | + _tableFieldNameListGapWithComma = _tableFieldNameListGapWithComma.substring(0, _tableFieldNameListGapWithComma.length()-1); | ||
107 | + | ||
108 | + //创建rowmapper | ||
109 | + this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); | ||
110 | + } | ||
111 | + | ||
112 | + /** | ||
113 | + * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> | ||
114 | + * 例如:HelloWorld->HELLO_WORLD | ||
115 | + * @param name 转换前的驼峰式命名的字符串 | ||
116 | + * @return 转换后下划线大写方式命名的字符串 | ||
117 | + */ | ||
118 | + private String camelToUnderline(String name) { | ||
119 | + StringBuilder result = new StringBuilder(); | ||
120 | + if (name != null && name.length() > 0) { | ||
121 | + // 将第一个字符处理成大写 | ||
122 | + result.append(name.substring(0, 1).toUpperCase()); | ||
123 | + // 循环处理其余字符 | ||
124 | + for (int i = 1; i < name.length(); i++) { | ||
125 | + String s = name.substring(i, i + 1); | ||
126 | + // 在大写字母前添加下划线 | ||
127 | + if (Character.isUpperCase(s.charAt(0)) && Character.isLetter(s.charAt(0))) { | ||
128 | + result.append("_"); | ||
129 | + } | ||
130 | + // 其他字符直接转成大写 | ||
131 | + result.append(s.toUpperCase()); | ||
132 | + } | ||
133 | + } | ||
134 | + return result.toString(); | ||
135 | + } | ||
136 | + | ||
137 | + private void appendWhereCondition(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> condition) { | ||
138 | + if (condition == null || condition.size() == 0) return; | ||
139 | + Object[] con = condition.get(0); | ||
140 | + int iLen = condition.size(); | ||
141 | + sql.append(" WHERE "); | ||
142 | + pql.append(" WHERE "); | ||
143 | + sql.append(con[0]); | ||
144 | + pql.append(con[0]); | ||
145 | + if (null != con[1] && con[1] != "" && con[1] != "useArg[0]") { | ||
146 | + sql.append(" " + con[1] + " ?"); | ||
147 | + pql.append(" " + con[1] + " " + con[2]); | ||
148 | + list.add(con[2]); | ||
149 | + } | ||
150 | + for (int i = 1; i < iLen; i++) { | ||
151 | + con = condition.get(i); | ||
152 | + sql.append(" AND "); | ||
153 | + pql.append(" AND "); | ||
154 | + sql.append(con[0]); | ||
155 | + pql.append(con[0]); | ||
156 | + if (null == con[1] || "" == con[1] || con[1] == "useArg[0]") continue; | ||
157 | + sql.append(" " + con[1] + " ?"); | ||
158 | + pql.append(" " + con[1] + " " + con[2]); | ||
159 | + list.add(con[2]); | ||
160 | + } | ||
161 | + } | ||
162 | + | ||
163 | + private void appendWhereConditionForCount(StringBuffer sql, List<Object[]> condition) { | ||
164 | + if (condition == null || condition.size() == 0) return; | ||
165 | + Object[] con = condition.get(0); | ||
166 | + int iLen = condition.size(); | ||
167 | + sql.append(" WHERE "); | ||
168 | + sql.append(con[0]); | ||
169 | + if (null != con[1] && con[1] != "" && con[1] != "useArg[0]") { | ||
170 | + sql.append(" " + con[1] + " ?"); | ||
171 | + } | ||
172 | + for (int i = 1; i < iLen; i++) { | ||
173 | + con = condition.get(i); | ||
174 | + sql.append(" AND "); | ||
175 | + sql.append(con[0]); | ||
176 | + if (null == con[1] || "" == con[1] || con[1] == "useArg[0]") continue; | ||
177 | + sql.append(" " + con[1] + " ?"); | ||
178 | + } | ||
179 | + } | ||
180 | + | ||
181 | + private void appendSetSql(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> obj) { | ||
182 | + for (Object[] arg : obj) { | ||
183 | + if (arg.length > 2) { | ||
184 | + sql.append(" " + arg[0] + " = " + arg[0] + arg[2] + " ?,"); | ||
185 | + pql.append(" " + arg[0] + " = " + arg[0] + arg[2] + arg[1] +","); | ||
186 | + list.add(arg[1]); | ||
187 | + }else if(arg.length == 2) { | ||
188 | + sql.append(" " + arg[0] + " = ?,"); | ||
189 | + pql.append(" " + arg[0] + " = " + arg[1] + ","); | ||
190 | + list.add(arg[1]); | ||
191 | + }else if(arg.length == 1) { | ||
192 | + sql.append(" " + arg[0] + ","); | ||
193 | + pql.append(" " + arg[0] + ","); | ||
194 | + } | ||
195 | + } | ||
196 | + } | ||
197 | + | ||
198 | + private String getTableSql(){ | ||
199 | + return (this._dbName == null || "".equals(this._dbName.trim()))? | ||
200 | + ("`"+this._tableName+"`"): | ||
201 | + ("`"+this._dbName+"`.`"+this._tableName+"`"); | ||
202 | + } | ||
203 | + | ||
204 | + private String constructUpdateSql(T entity, List<Field> beanFieldList) { | ||
205 | + StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | ||
206 | + Iterator<String> beanFieldIter = this._beanToTableField.keySet().iterator(); | ||
207 | + while(beanFieldIter.hasNext()){ | ||
208 | + String beanFieldName = beanFieldIter.next(); | ||
209 | + String tableFieldName = this._beanToTableField.get(beanFieldName); | ||
210 | + Field beanField = null; | ||
211 | + try { | ||
212 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); | ||
213 | + beanField.setAccessible(true); | ||
214 | + if(beanField.get(entity) == null) { | ||
215 | + continue; | ||
216 | + } | ||
217 | + } catch (Exception e) { | ||
218 | + continue; | ||
219 | + } | ||
220 | + | ||
221 | + if(tableFieldName == null || beanFieldName == null){ | ||
222 | + continue; | ||
223 | + } | ||
224 | + | ||
225 | + beanFieldList.add(beanField); | ||
226 | + sqlInsertPart.append("`"+tableFieldName+"`,"); | ||
227 | + } | ||
228 | + return sqlInsertPart.substring(0, sqlInsertPart.length()-1)+")"; | ||
229 | + } | ||
230 | + | ||
231 | + private Object getDefaultValueByFieldType(Field itemField) { | ||
232 | + String simpleName = itemField.getType().getSimpleName(); | ||
233 | + if("String".equals(simpleName)) { | ||
234 | + return ""; | ||
235 | + }else if("Date".equals(simpleName) || "Timestamp".equals(simpleName)) { | ||
236 | + return "2000-01-01 00:00:00"; | ||
237 | + }else if("BigDecimal".equals(simpleName)){ | ||
238 | + return BigDecimal.ZERO; | ||
239 | + }else { | ||
240 | + return 0; | ||
241 | + } | ||
242 | + } | ||
243 | + | ||
244 | + @Override | ||
245 | + public T findEntityByID(ID id) throws NotFoundException { | ||
246 | + return findEntityByID(id, false); | ||
247 | + } | ||
248 | + | ||
249 | + @Override | ||
250 | + public T findEntityByID(ID id, boolean isLock) throws NotFoundException { | ||
251 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | ||
252 | + sql.append(" WHERE "+_idTableFieldName+" = ? "); | ||
253 | + if (isLock) { | ||
254 | + sql.append(" FOR UPDATE"); | ||
255 | + } | ||
256 | + try { | ||
257 | + return (T) _jdbcTemplateBroadcast.queryForObject(sql.toString(), this._customJdbcTemplateRowMapper, new String[] {this._tableName}, id); | ||
258 | + }catch (DataAccessException e) { | ||
259 | + throw new NotFoundException(e); | ||
260 | + } | ||
261 | + } | ||
262 | + | ||
263 | + @Override | ||
264 | + public T findEntityByCondition(List<Object[]> condition) throws NotFoundException, MultiRowException, NoContainTenantException { | ||
265 | + List<T> tempList = findListByCondition(condition); | ||
266 | + if(tempList == null || tempList.size() == 0){ | ||
267 | + throw new NotFoundException(); | ||
268 | + } | ||
269 | + if(tempList != null && tempList.size() == 1){ | ||
270 | + return tempList.get(0); | ||
271 | + }else{ | ||
272 | + throw new MultiRowException(); | ||
273 | + } | ||
274 | + } | ||
275 | + | ||
276 | + @Override | ||
277 | + public T findEntityBySql(String sqlCondition) throws NotFoundException, MultiRowException { | ||
278 | + List<T> tempList = findListBySql(sqlCondition); | ||
279 | + if(tempList == null || tempList.size() == 0){ | ||
280 | + throw new NotFoundException(); | ||
281 | + } | ||
282 | + if(tempList != null && tempList.size() == 1){ | ||
283 | + return tempList.get(0); | ||
284 | + }else{ | ||
285 | + throw new MultiRowException(); | ||
286 | + } | ||
287 | + } | ||
288 | + | ||
289 | + @Override | ||
290 | + public List<T> findListByCondition(List<Object[]> condition){ | ||
291 | + return findListByCondition(condition, null); | ||
292 | + } | ||
293 | + | ||
294 | + @Override | ||
295 | + public List<T> findListByCondition(List<Object[]> condition, String sortCondition){ | ||
296 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | ||
297 | + List<Object> list = new ArrayList<Object>(); | ||
298 | + this.appendWhereCondition(sql, new StringBuffer(), list, condition); | ||
299 | + if(sortCondition != null && !sortCondition.equals("")){ | ||
300 | + sql.append(" " + sortCondition + " "); | ||
301 | + } | ||
302 | + return (List<T>)_jdbcTemplateBroadcast.query(sql.toString(), this._customJdbcTemplateRowMapper, new String[] {this._tableName}, list.toArray()); | ||
303 | + } | ||
304 | + | ||
305 | + @Override | ||
306 | + public List<T> findListBySql(String sqlCondition){ | ||
307 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE " + sqlCondition); | ||
308 | + return (List<T>)_jdbcTemplateBroadcast.query(sql.toString(), this._customJdbcTemplateRowMapper, new String[] {this._tableName}); | ||
309 | + } | ||
310 | + | ||
311 | + @Override | ||
312 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize){ | ||
313 | + return findPageByCondition(condition, null , page, pageSize); | ||
314 | + } | ||
315 | + | ||
316 | + @Override | ||
317 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, String sortCondition, int page, int pageSize){ | ||
318 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | ||
319 | + StringBuffer pql = new StringBuffer(sql.toString()); | ||
320 | + StringBuffer sqlCount = new StringBuffer("SELECT COUNT(1) rowCount FROM "+this.getTableSql()); | ||
321 | + List<Object> count_list = new ArrayList<Object>(); | ||
322 | + List<Object> page_list = new ArrayList<Object>(); | ||
323 | + this.appendWhereConditionForCount(sqlCount, condition); | ||
324 | + this.appendWhereCondition(sql, pql, count_list, condition); | ||
325 | + for (int i = 0; i < count_list.size(); i++) | ||
326 | + page_list.add(count_list.get(i)); | ||
327 | + | ||
328 | + page_list.add((page - 1) * pageSize); | ||
329 | + page_list.add(pageSize); | ||
330 | + | ||
331 | + if(sortCondition != null && !sortCondition.equals("")){ | ||
332 | + sql.append(" " + sortCondition + " "); | ||
333 | + pql.append(" " + sortCondition + " "); | ||
334 | + } | ||
335 | + | ||
336 | + String pageSql = sql.toString() + " limit ?, ?"; | ||
337 | + Map<String, Object> totalRowsMap = _jdbcTemplateBroadcast.queryForMap(sqlCount.toString(), new String[] {this._tableName}, count_list.toArray()) ; | ||
338 | + List<T> resultList = _jdbcTemplateBroadcast.query(pageSql.toString(), this._customJdbcTemplateRowMapper, new String[] {this._tableName}, page_list.toArray()); | ||
339 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | ||
340 | + } | ||
341 | + | ||
342 | + @Override | ||
343 | + public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize){ | ||
344 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE " + sqlCondition); | ||
345 | + StringBuffer sqlCount = new StringBuffer("SELECT count(1) rowCount FROM "+this.getTableSql()+" WHERE " + sqlCondition); | ||
346 | + sql.append(" limit ?, ?"); | ||
347 | + List<Object> page_list = new ArrayList<Object>(); | ||
348 | + page_list.add((page - 1) * pageSize); | ||
349 | + page_list.add(page * pageSize); | ||
350 | + | ||
351 | + Map<String, Object> totalRowsMap = _jdbcTemplateBroadcast.queryForMap(sqlCount.toString(), new String[] {this._tableName}); | ||
352 | + List<T> resultList = _jdbcTemplateBroadcast.query(sql.toString(), this._customJdbcTemplateRowMapper, new String[] {this._tableName}, page_list.toArray()); | ||
353 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | ||
354 | + } | ||
355 | + | ||
356 | + @Override | ||
357 | + public void addEntity(T entity) { | ||
358 | + StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | ||
359 | + StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); | ||
360 | + List<Object> paramList = new ArrayList<Object>(); | ||
361 | + | ||
362 | + Iterator<String> beanFieldIter = this._beanToTableField.keySet().iterator(); | ||
363 | + while(beanFieldIter.hasNext()){ | ||
364 | + String beanFieldName = beanFieldIter.next(); | ||
365 | + String tableFieldName = this._beanToTableField.get(beanFieldName); | ||
366 | + Field beanField; | ||
367 | + Object beanFieldValue = null; | ||
368 | + try { | ||
369 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); | ||
370 | + beanField.setAccessible(true); | ||
371 | + beanFieldValue = beanField.get(entity); | ||
372 | + } catch (Exception e) { | ||
373 | + e.printStackTrace(); | ||
374 | + } | ||
375 | + | ||
376 | + if(tableFieldName == null || beanFieldName == null || beanFieldValue == null){ | ||
377 | + continue; | ||
378 | + } | ||
379 | + sqlInsertPart.append("`"+tableFieldName+"`,"); | ||
380 | + sqlColumnPart.append(" ?,"); | ||
381 | + paramList.add(beanFieldValue); | ||
382 | + } | ||
383 | + | ||
384 | + //执行SQL | ||
385 | + String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | ||
386 | + _jdbcTemplateBroadcast.update(exeSql, new String[] {this._tableName}, paramList.toArray()); | ||
387 | + } | ||
388 | + | ||
389 | + @Override | ||
390 | + public void addEntityList(List<T> entityList) { | ||
391 | + if(entityList == null || entityList.isEmpty()) { | ||
392 | + return; | ||
393 | + } | ||
394 | + //构造SQL语句及Entity Field列表 | ||
395 | + List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); | ||
396 | + StringBuffer exeSql = new StringBuffer(this.constructUpdateSql(entityList.get(0), beanFieldList)); | ||
397 | + | ||
398 | + //构造参数信息 | ||
399 | + List<Object> args = new ArrayList<Object>(); | ||
400 | + exeSql.append(" VALUES"); | ||
401 | + for(int itemIndex=0; itemIndex<entityList.size(); ++itemIndex) { | ||
402 | + T item = entityList.get(itemIndex); | ||
403 | + exeSql.append("("); | ||
404 | + for(int i=0; i<beanFieldList.size(); ++i) { | ||
405 | + Field itemField = beanFieldList.get(i); | ||
406 | + Object itemData = null; | ||
407 | + try { | ||
408 | + itemData = itemField.get(item); | ||
409 | + } catch (Exception e) { | ||
410 | + throw new ObjectReflectException(); | ||
411 | + } | ||
412 | + if(itemData == null) { | ||
413 | + args.add(this.getDefaultValueByFieldType(itemField)); | ||
414 | + }else { | ||
415 | + args.add(itemData); | ||
416 | + } | ||
417 | + exeSql.append("?,"); | ||
418 | + } | ||
419 | + exeSql.setCharAt(exeSql.length()-1, ' '); | ||
420 | + exeSql.append("),"); | ||
421 | + } | ||
422 | + exeSql.setCharAt(exeSql.length()-1, ';'); | ||
423 | + | ||
424 | + //执行SQL | ||
425 | + this._jdbcTemplateBroadcast.update(exeSql.toString(), new String[] {this._tableName}, args.toArray()); | ||
426 | + } | ||
427 | + | ||
428 | + @Override | ||
429 | + public int deleteEntityByID(ID id) { | ||
430 | + StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+" WHERE"); | ||
431 | + sql.append(" "+this._idTableFieldName+" = ? "); | ||
432 | + return _jdbcTemplateBroadcast.update(sql.toString(), new String[] {this._tableName}, id); | ||
433 | + } | ||
434 | + | ||
435 | + @Override | ||
436 | + public int deleteEntityByCondition(List<Object[]> condition){ | ||
437 | + if (null == condition || condition.size() == 0) { | ||
438 | + throw new RuntimeException("params[condition] is empty"); | ||
439 | + } | ||
440 | + | ||
441 | + List<Object> list = new ArrayList<Object>(); | ||
442 | + StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+""); | ||
443 | + StringBuffer pql = new StringBuffer(sql.toString()); | ||
444 | + this.appendWhereCondition(sql, pql, list, condition); | ||
445 | + return _jdbcTemplateBroadcast.update( sql.toString(), new String[] {this._tableName}, list.toArray()); | ||
446 | + } | ||
447 | + | ||
448 | + @Override | ||
449 | + public int deleteEntityBySql(String sqlCondition){ | ||
450 | + if("".equals(sqlCondition.trim())) { | ||
451 | + throw new RuntimeException("params[sqlCondition] is empty"); | ||
452 | + } | ||
453 | + return _jdbcTemplateBroadcast.update( "DELETE FROM "+this.getTableSql()+" WHERE " + sqlCondition, new String[] {this._tableName}); | ||
454 | + } | ||
455 | + | ||
456 | + @Override | ||
457 | + public int deleteEntityList(List<ID> idList){ | ||
458 | + StringBuffer idSb = new StringBuffer(); | ||
459 | + for(ID id: idList) { | ||
460 | + idSb.append(id); | ||
461 | + } | ||
462 | + return this.deleteEntityBySql(this._idTableFieldName + " in ("+idSb.toString().substring(0, idSb.length()-1)+") "); | ||
463 | + } | ||
464 | + | ||
465 | + @Override | ||
466 | + public int updateEntityById(List<Object[]> changeList, ID id) { | ||
467 | + if(null == id){ | ||
468 | + throw new RuntimeException("params[id] is null"); | ||
469 | + } | ||
470 | + if (null == changeList || changeList.size() == 0) { | ||
471 | + throw new RuntimeException("params[changeList] is empty"); | ||
472 | + } | ||
473 | + | ||
474 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | ||
475 | + StringBuffer pql = new StringBuffer(sql.toString()); | ||
476 | + List<Object> list = new ArrayList<Object>(); | ||
477 | + this.appendSetSql(sql, pql, list, changeList); | ||
478 | + | ||
479 | + String where = " WHERE "+this._idTableFieldName+"=? "; | ||
480 | + String updateSql = sql.substring(0, sql.length()-1)+where; | ||
481 | + list.add(id); | ||
482 | + return _jdbcTemplateBroadcast.update(updateSql, new String[] {this._tableName}, list.toArray()); | ||
483 | + } | ||
484 | + | ||
485 | + @Override | ||
486 | + public int updateEntityByCondition(List<Object[]> updateObj, List<Object[]> condition){ | ||
487 | + if (null == updateObj || updateObj.size() == 0) { | ||
488 | + throw new RuntimeException("params[updateObj] is empty"); | ||
489 | + } | ||
490 | + if (null == condition || condition.size() == 0) { | ||
491 | + throw new RuntimeException("params[condition] is empty"); | ||
492 | + } | ||
493 | + | ||
494 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | ||
495 | + StringBuffer pql = new StringBuffer(sql.toString()); | ||
496 | + List<Object> list = new ArrayList<Object>(); | ||
497 | + this.appendSetSql(sql, pql, list, updateObj); | ||
498 | + | ||
499 | + StringBuffer where = new StringBuffer(""); | ||
500 | + StringBuffer pwhere = new StringBuffer(""); | ||
501 | + this.appendWhereCondition(where, pwhere, list, condition); | ||
502 | + | ||
503 | + String updateSql = sql.substring(0, sql.length()-1)+where.toString(); | ||
504 | + return _jdbcTemplateBroadcast.update(updateSql, new String[] {this._tableName}, list.toArray()); | ||
505 | + } | ||
506 | + | ||
507 | + @Override | ||
508 | + public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition){ | ||
509 | + if (null == updateObj || updateObj.size() == 0) { | ||
510 | + throw new RuntimeException("params[updateObj] is empty"); | ||
511 | + } | ||
512 | + if ("".equals(sqlCondition)) { | ||
513 | + throw new RuntimeException("params[sqlCondition] is empty"); | ||
514 | + } | ||
515 | + | ||
516 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | ||
517 | + StringBuffer pql = new StringBuffer(sql.toString()); | ||
518 | + List<Object> list = new ArrayList<Object>(); | ||
519 | + this.appendSetSql(sql, pql, list, updateObj); | ||
520 | + | ||
521 | + String updateSql = sql.toString().substring(0, sql.length()-1) + " WHERE "+sqlCondition; | ||
522 | + return _jdbcTemplateBroadcast.update(updateSql, new String[] {this._tableName}, list.toArray()); | ||
523 | + } | ||
524 | + | ||
525 | + @Override | ||
526 | + public Map<String, Object> getPageData(String coreSql, String orderByPartSql, Integer page, Integer pageSize){ | ||
527 | + String[] splitedSql = UtilsSql.splitCoreSql(coreSql); | ||
528 | + return this.getPageData(splitedSql[0], splitedSql[1], orderByPartSql, page, pageSize); | ||
529 | + } | ||
530 | + | ||
531 | + @Override | ||
532 | + public Map<String, Object> getPageData(String selectSql, String fromAndWhereSql, String orderByPartSql, Integer page, Integer pageSize){ | ||
533 | + //构造查询语句 | ||
534 | + String querySql = selectSql+" "+fromAndWhereSql+" "+orderByPartSql+" "+UtilsSql.getLimitCondition(page, pageSize); | ||
535 | + | ||
536 | + //构造统计计数语句 | ||
537 | + String countSql = "select count(*) rowsCount from ( select 1 "+fromAndWhereSql+" ) t "; | ||
538 | + | ||
539 | + //执行查询 | ||
540 | + List<Map<String, Object>> queryData = new ArrayList<Map<String, Object>>(); | ||
541 | + Map<String, Object> countData = new HashMap<String, Object>(); | ||
542 | + queryData = this._jdbcTemplateBroadcast.queryForList(querySql, new String[] {this._tableName}); | ||
543 | + countData = this._jdbcTemplateBroadcast.queryForMap(countSql, new String[] {this._tableName}); | ||
544 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(countData.get("rowsCount").toString()), queryData); | ||
545 | + } | ||
546 | +} |
src/main/java/com/taover/repository/CustomJdbcTemplateBroadcastInterface.java
0 → 100644
@@ -0,0 +1,153 @@ | @@ -0,0 +1,153 @@ | ||
1 | +package com.taover.repository; | ||
2 | + | ||
3 | +import java.io.Serializable; | ||
4 | +import java.util.List; | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import com.taover.repository.exception.MultiRowException; | ||
8 | +import com.taover.repository.exception.NoContainTenantException; | ||
9 | +import com.taover.repository.exception.NotFoundException; | ||
10 | + | ||
11 | +public interface CustomJdbcTemplateBroadcastInterface<T, ID extends Serializable> { | ||
12 | + | ||
13 | + /** | ||
14 | + * 按主键查询 | ||
15 | + */ | ||
16 | + public T findEntityByID(ID id) throws NotFoundException; | ||
17 | + | ||
18 | + /** | ||
19 | + * 按主键查询 | ||
20 | + * isLock 是否锁定, 默认不锁 | ||
21 | + * fromWriteDB 是否从写库读写,默认从读库查询 | ||
22 | + */ | ||
23 | + public T findEntityByID(ID id, boolean isLock) throws NotFoundException; | ||
24 | + | ||
25 | + /** | ||
26 | + * 根据条件List<Object[]>查询 | ||
27 | + * Object[]数组长度是3 | ||
28 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
29 | + */ | ||
30 | + public T findEntityByCondition(List<Object[]> condition) throws NotFoundException,MultiRowException,NoContainTenantException; | ||
31 | + | ||
32 | + /** | ||
33 | + * 根据条件sql查询 | ||
34 | + * sqlCondition 为where 后面的条件。 | ||
35 | + */ | ||
36 | + public T findEntityBySql(String sqlCondition) throws NotFoundException,MultiRowException,NoContainTenantException; | ||
37 | + | ||
38 | + /** | ||
39 | + * 根据条件List<Object[]>查询 | ||
40 | + * Object[]数组长度是3 | ||
41 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
42 | + */ | ||
43 | + public List<T> findListByCondition(List<Object[]> condition); | ||
44 | + | ||
45 | + /** | ||
46 | + * 根据条件List<Object[]>查询 | ||
47 | + * Object[]数组长度是3 | ||
48 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
49 | + */ | ||
50 | + public List<T> findListByCondition(List<Object[]> condition, String sortCondition); | ||
51 | + | ||
52 | + /** | ||
53 | + * 根据条件sql查询 | ||
54 | + * sqlCondition 为where 后面的条件。 | ||
55 | + */ | ||
56 | + public List<T> findListBySql(String sqlCondition); | ||
57 | + | ||
58 | + /** | ||
59 | + * 按条件分页查询 | ||
60 | + * Object[]数组长度是3 | ||
61 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
62 | + */ | ||
63 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize); | ||
64 | + | ||
65 | + /** | ||
66 | + * 按条件分页查询 | ||
67 | + * Object[]数组长度是3 | ||
68 | + * Object[]第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
69 | + * boolean isUseCache, 是否用缓存,默认用。 | ||
70 | + * boolean isAddCache, 是否添加缓存,默认添加。 | ||
71 | + */ | ||
72 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, String sortCondition, int page, int pageSize); | ||
73 | + | ||
74 | + /** | ||
75 | + * 按sql分页查询, sqlCondition为where 后条件sql | ||
76 | + */ | ||
77 | + public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize); | ||
78 | + | ||
79 | + /** | ||
80 | + * 添加 | ||
81 | + */ | ||
82 | + public void addEntity(T entity); | ||
83 | + | ||
84 | + /** | ||
85 | + * 批量添加 | ||
86 | + * @throws Exception | ||
87 | + */ | ||
88 | + public void addEntityList(List<T> entityList); | ||
89 | + | ||
90 | + /** | ||
91 | + * 按ID删除 | ||
92 | + */ | ||
93 | + public int deleteEntityByID(ID id); | ||
94 | + | ||
95 | + /** | ||
96 | + * 删除按List<Object[]>条件 | ||
97 | + * Object[]数组长度是3 | ||
98 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
99 | + */ | ||
100 | + public int deleteEntityByCondition(List<Object[]> condition); | ||
101 | + | ||
102 | + /** | ||
103 | + * 删除按condition条件 | ||
104 | + * 建议使用deleteTByCondition(List<Object[]> condition), 如果removeTByCondition(List<Object[]> condition)满足不了where条件可以使用此方法。 | ||
105 | + * condition为where后面的条件,condition不能为空。 | ||
106 | + */ | ||
107 | + public int deleteEntityBySql(String sqlCondition); | ||
108 | + | ||
109 | + /** | ||
110 | + * 根据list对象逐个删除。 | ||
111 | + * @throws NoContainTenantException | ||
112 | + */ | ||
113 | + public int deleteEntityList(List<ID> idList); | ||
114 | + | ||
115 | + /** | ||
116 | + * 根据ID修改指定的值 | ||
117 | + */ | ||
118 | + public int updateEntityById(List<Object[]> changeList, ID id); | ||
119 | + | ||
120 | + /** | ||
121 | + * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | ||
122 | + * List<Object[]> condition 修改的条件, 数组长度是3, 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | ||
123 | + */ | ||
124 | + public int updateEntityByCondition(List<Object[]> updateObj, List<Object[]> condition); | ||
125 | + | ||
126 | + /** | ||
127 | + * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | ||
128 | + * String sqlCondition 修改的条件。 | ||
129 | + */ | ||
130 | + public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition); | ||
131 | + | ||
132 | + /** | ||
133 | + * 获取分页数据 | ||
134 | + * @param coreSql | ||
135 | + * @param orderByPartSql | ||
136 | + * @param page | ||
137 | + * @param pageSize | ||
138 | + * @return | ||
139 | + */ | ||
140 | + public Map<String, Object> getPageData(String coreSql, String orderByPartSql, Integer page, Integer pageSize); | ||
141 | + | ||
142 | + /** | ||
143 | + * 获取分页数据 | ||
144 | + * @param selectSql | ||
145 | + * @param fromAndWhereSql | ||
146 | + * @param orderByPartSql | ||
147 | + * @param page | ||
148 | + * @param pageSize | ||
149 | + * @return | ||
150 | + */ | ||
151 | + public Map<String, Object> getPageData(String selectSql, String fromAndWhereSql, String orderByPartSql, Integer page, Integer pageSize); | ||
152 | + | ||
153 | +} |
src/main/java/com/taover/repository/autoconfigure/TaoverRepositoryAutoConfiguration.java
@@ -10,7 +10,10 @@ import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration | @@ -10,7 +10,10 @@ import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration | ||
10 | import org.springframework.boot.context.properties.EnableConfigurationProperties; | 10 | import org.springframework.boot.context.properties.EnableConfigurationProperties; |
11 | import org.springframework.context.annotation.Bean; | 11 | import org.springframework.context.annotation.Bean; |
12 | import org.springframework.context.annotation.Configuration; | 12 | import org.springframework.context.annotation.Configuration; |
13 | +import org.springframework.jdbc.core.JdbcTemplate; | ||
13 | 14 | ||
15 | +import com.taover.repository.jdbctemplate.JdbcTemplateBroadcast; | ||
16 | +import com.taover.repository.jdbctemplate.JdbcTemplateBroadcastImpl; | ||
14 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | 17 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; |
15 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenantImpl; | 18 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenantImpl; |
16 | import com.taover.repository.shardingsphere.ShardingInfoRepository; | 19 | import com.taover.repository.shardingsphere.ShardingInfoRepository; |
@@ -23,9 +26,12 @@ import com.taover.repository.shardingsphere.ShardingSphereService; | @@ -23,9 +26,12 @@ import com.taover.repository.shardingsphere.ShardingSphereService; | ||
23 | @ConditionalOnClass({ShardingSphereService.class}) | 26 | @ConditionalOnClass({ShardingSphereService.class}) |
24 | @ConditionalOnMissingBean(ShardingSphereService.class) | 27 | @ConditionalOnMissingBean(ShardingSphereService.class) |
25 | public class TaoverRepositoryAutoConfiguration { | 28 | public class TaoverRepositoryAutoConfiguration { |
26 | - | 29 | + @Resource |
30 | + private JdbcTemplate jdbcTemplate; | ||
27 | @Resource | 31 | @Resource |
28 | private ShardingSphereKeyGeneratorConfiguration config; | 32 | private ShardingSphereKeyGeneratorConfiguration config; |
33 | + @Resource | ||
34 | + private ShardingSphereService shardingSphereService; | ||
29 | 35 | ||
30 | @Bean | 36 | @Bean |
31 | public ShardingSphereService shardingSphereService() { | 37 | public ShardingSphereService shardingSphereService() { |
@@ -39,6 +45,11 @@ public class TaoverRepositoryAutoConfiguration { | @@ -39,6 +45,11 @@ public class TaoverRepositoryAutoConfiguration { | ||
39 | 45 | ||
40 | @Bean | 46 | @Bean |
41 | public JdbcTemplateWrapperTenant jdbcTemplateWrapperTenant() { | 47 | public JdbcTemplateWrapperTenant jdbcTemplateWrapperTenant() { |
42 | - return new JdbcTemplateWrapperTenantImpl(); | 48 | + return new JdbcTemplateWrapperTenantImpl(this.jdbcTemplate, this.shardingSphereService); |
49 | + } | ||
50 | + | ||
51 | + @Bean | ||
52 | + public JdbcTemplateBroadcast jdbcTemplateWrapperBroadcast() { | ||
53 | + return new JdbcTemplateBroadcastImpl(this.jdbcTemplate, this.shardingSphereService); | ||
43 | } | 54 | } |
44 | } | 55 | } |
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateBroadcast.java
0 → 100644
@@ -0,0 +1,976 @@ | @@ -0,0 +1,976 @@ | ||
1 | +package com.taover.repository.jdbctemplate; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | +import java.util.List; | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import org.springframework.dao.DataAccessException; | ||
8 | +import org.springframework.dao.IncorrectResultSizeDataAccessException; | ||
9 | +import org.springframework.jdbc.core.BatchPreparedStatementSetter; | ||
10 | +import org.springframework.jdbc.core.CallableStatementCallback; | ||
11 | +import org.springframework.jdbc.core.CallableStatementCreator; | ||
12 | +import org.springframework.jdbc.core.ColumnMapRowMapper; | ||
13 | +import org.springframework.jdbc.core.ConnectionCallback; | ||
14 | +import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter; | ||
15 | +import org.springframework.jdbc.core.PreparedStatementCallback; | ||
16 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
17 | +import org.springframework.jdbc.core.PreparedStatementCreatorFactory; | ||
18 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
19 | +import org.springframework.jdbc.core.ResultSetExtractor; | ||
20 | +import org.springframework.jdbc.core.RowCallbackHandler; | ||
21 | +import org.springframework.jdbc.core.RowMapper; | ||
22 | +import org.springframework.jdbc.core.SingleColumnRowMapper; | ||
23 | +import org.springframework.jdbc.core.SqlParameter; | ||
24 | +import org.springframework.jdbc.core.SqlParameterValue; | ||
25 | +import org.springframework.jdbc.core.SqlRowSetResultSetExtractor; | ||
26 | +import org.springframework.jdbc.core.StatementCallback; | ||
27 | +import org.springframework.jdbc.support.KeyHolder; | ||
28 | +import org.springframework.jdbc.support.rowset.SqlRowSet; | ||
29 | +import org.springframework.lang.Nullable; | ||
30 | + | ||
31 | +public interface JdbcTemplateBroadcast { | ||
32 | + /** | ||
33 | + * 加载分片信息 | ||
34 | + * @param tenantId | ||
35 | + */ | ||
36 | + public void loadShardingInfo(String[] broadcastTableNames); | ||
37 | + | ||
38 | + /** | ||
39 | + * 清空分片信息 | ||
40 | + */ | ||
41 | + public void clearShardingInfo(); | ||
42 | + | ||
43 | + //------------------------------------------------------------------------- | ||
44 | + // Methods dealing with a plain java.sql.Connection | ||
45 | + //------------------------------------------------------------------------- | ||
46 | + | ||
47 | + /** | ||
48 | + * Execute a JDBC data access operation, implemented as callback action | ||
49 | + * working on a JDBC Connection. This allows for implementing arbitrary | ||
50 | + * data access operations, within Spring's managed JDBC environment: | ||
51 | + * that is, participating in Spring-managed transactions and converting | ||
52 | + * JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
53 | + * <p>The callback action can return a result object, for example a domain | ||
54 | + * object or a collection of domain objects. | ||
55 | + * @param action a callback object that specifies the action | ||
56 | + * @return a result object returned by the action, or {@code null} if none | ||
57 | + * @throws DataAccessException if there is any problem | ||
58 | + */ | ||
59 | + @Nullable | ||
60 | + <T> T execute(ConnectionCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
61 | + | ||
62 | + | ||
63 | + //------------------------------------------------------------------------- | ||
64 | + // Methods dealing with static SQL (java.sql.Statement) | ||
65 | + //------------------------------------------------------------------------- | ||
66 | + | ||
67 | + /** | ||
68 | + * Execute a JDBC data access operation, implemented as callback action | ||
69 | + * working on a JDBC Statement. This allows for implementing arbitrary data | ||
70 | + * access operations on a single Statement, within Spring's managed JDBC | ||
71 | + * environment: that is, participating in Spring-managed transactions and | ||
72 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
73 | + * <p>The callback action can return a result object, for example a domain | ||
74 | + * object or a collection of domain objects. | ||
75 | + * @param action a callback that specifies the action | ||
76 | + * @return a result object returned by the action, or {@code null} if none | ||
77 | + * @throws DataAccessException if there is any problem | ||
78 | + */ | ||
79 | + @Nullable | ||
80 | + <T> T execute(StatementCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
81 | + | ||
82 | + /** | ||
83 | + * Issue a single SQL execute, typically a DDL statement. | ||
84 | + * @param sql static SQL to execute | ||
85 | + * @throws DataAccessException if there is any problem | ||
86 | + */ | ||
87 | + void execute(String sql, String[] broadcastTableNames) throws DataAccessException; | ||
88 | + | ||
89 | + /** | ||
90 | + * Execute a query given static SQL, reading the ResultSet with a | ||
91 | + * ResultSetExtractor. | ||
92 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
93 | + * execute a static query with a PreparedStatement, use the overloaded | ||
94 | + * {@code query} method with {@code null} as argument array. | ||
95 | + * @param sql the SQL query to execute | ||
96 | + * @param rse a callback that will extract all rows of results | ||
97 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
98 | + * @throws DataAccessException if there is any problem executing the query | ||
99 | + * @see #query(String, Object[], ResultSetExtractor) | ||
100 | + */ | ||
101 | + @Nullable | ||
102 | + <T> T query(String sql, ResultSetExtractor<T> rse, String[] broadcastTableNames) throws DataAccessException; | ||
103 | + | ||
104 | + /** | ||
105 | + * Execute a query given static SQL, reading the ResultSet on a per-row | ||
106 | + * basis with a RowCallbackHandler. | ||
107 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
108 | + * execute a static query with a PreparedStatement, use the overloaded | ||
109 | + * {@code query} method with {@code null} as argument array. | ||
110 | + * @param sql the SQL query to execute | ||
111 | + * @param rch a callback that will extract results, one row at a time | ||
112 | + * @throws DataAccessException if there is any problem executing the query | ||
113 | + * @see #query(String, Object[], RowCallbackHandler) | ||
114 | + */ | ||
115 | + void query(String sql, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException; | ||
116 | + | ||
117 | + /** | ||
118 | + * Execute a query given static SQL, mapping each row to a result object | ||
119 | + * via a RowMapper. | ||
120 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
121 | + * execute a static query with a PreparedStatement, use the overloaded | ||
122 | + * {@code query} method with {@code null} as argument array. | ||
123 | + * @param sql the SQL query to execute | ||
124 | + * @param rowMapper a callback that will map one object per row | ||
125 | + * @return the result List, containing mapped objects | ||
126 | + * @throws DataAccessException if there is any problem executing the query | ||
127 | + * @see #query(String, Object[], RowMapper) | ||
128 | + */ | ||
129 | + <T> List<T> query(String sql, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
130 | + | ||
131 | + /** | ||
132 | + * Execute a query given static SQL, mapping a single result row to a | ||
133 | + * result object via a RowMapper. | ||
134 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
135 | + * execute a static query with a PreparedStatement, use the overloaded | ||
136 | + * {@link #queryForObject(String, RowMapper, Object...)} method with | ||
137 | + * {@code null} as argument array. | ||
138 | + * @param sql the SQL query to execute | ||
139 | + * @param rowMapper a callback that will map one object per row | ||
140 | + * @return the single mapped object (may be {@code null} if the given | ||
141 | + * {@link RowMapper} returned {@code} null) | ||
142 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
143 | + * return exactly one row | ||
144 | + * @throws DataAccessException if there is any problem executing the query | ||
145 | + * @see #queryForObject(String, Object[], RowMapper) | ||
146 | + */ | ||
147 | + @Nullable | ||
148 | + <T> T queryForObject(String sql, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
149 | + | ||
150 | + /** | ||
151 | + * Execute a query for a result object, given static SQL. | ||
152 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
153 | + * execute a static query with a PreparedStatement, use the overloaded | ||
154 | + * {@link #queryForObject(String, Class, Object...)} method with | ||
155 | + * {@code null} as argument array. | ||
156 | + * <p>This method is useful for running static SQL with a known outcome. | ||
157 | + * The query is expected to be a single row/single column query; the returned | ||
158 | + * result will be directly mapped to the corresponding object type. | ||
159 | + * @param sql the SQL query to execute | ||
160 | + * @param requiredType the type that the result object is expected to match | ||
161 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | ||
162 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | ||
163 | + * exactly one row, or does not return exactly one column in that row | ||
164 | + * @throws DataAccessException if there is any problem executing the query | ||
165 | + * @see #queryForObject(String, Object[], Class) | ||
166 | + */ | ||
167 | + @Nullable | ||
168 | + <T> T queryForObject(String sql, Class<T> requiredType, String[] broadcastTableNames) throws DataAccessException; | ||
169 | + | ||
170 | + /** | ||
171 | + * Execute a query for a result map, given static SQL. | ||
172 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
173 | + * execute a static query with a PreparedStatement, use the overloaded | ||
174 | + * {@link #queryForMap(String, Object...)} method with {@code null} | ||
175 | + * as argument array. | ||
176 | + * <p>The query is expected to be a single row query; the result row will be | ||
177 | + * mapped to a Map (one entry for each column, using the column name as the key). | ||
178 | + * @param sql the SQL query to execute | ||
179 | + * @return the result Map (one entry per column, with column name as key) | ||
180 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
181 | + * return exactly one row | ||
182 | + * @throws DataAccessException if there is any problem executing the query | ||
183 | + * @see #queryForMap(String, Object[]) | ||
184 | + * @see ColumnMapRowMapper | ||
185 | + */ | ||
186 | + Map<String, Object> queryForMap(String sql, String[] broadcastTableNames) throws DataAccessException; | ||
187 | + | ||
188 | + /** | ||
189 | + * Execute a query for a result list, given static SQL. | ||
190 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
191 | + * execute a static query with a PreparedStatement, use the overloaded | ||
192 | + * {@code queryForList} method with {@code null} as argument array. | ||
193 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
194 | + * result objects, each of them matching the specified element type. | ||
195 | + * @param sql the SQL query to execute | ||
196 | + * @param elementType the required type of element in the result list | ||
197 | + * (for example, {@code Integer.class}) | ||
198 | + * @return a List of objects that match the specified element type | ||
199 | + * @throws DataAccessException if there is any problem executing the query | ||
200 | + * @see #queryForList(String, Object[], Class) | ||
201 | + * @see SingleColumnRowMapper | ||
202 | + */ | ||
203 | + <T> List<T> queryForList(String sql, Class<T> elementType, String[] broadcastTableNames) throws DataAccessException; | ||
204 | + | ||
205 | + /** | ||
206 | + * Execute a query for a result list, given static SQL. | ||
207 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
208 | + * execute a static query with a PreparedStatement, use the overloaded | ||
209 | + * {@code queryForList} method with {@code null} as argument array. | ||
210 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
211 | + * Maps (one entry for each column using the column name as the key). | ||
212 | + * Each element in the list will be of the form returned by this interface's | ||
213 | + * {@code queryForMap} methods. | ||
214 | + * @param sql the SQL query to execute | ||
215 | + * @return an List that contains a Map per row | ||
216 | + * @throws DataAccessException if there is any problem executing the query | ||
217 | + * @see #queryForList(String, Object[]) | ||
218 | + */ | ||
219 | + List<Map<String, Object>> queryForList(String sql, String[] broadcastTableNames) throws DataAccessException; | ||
220 | + | ||
221 | + /** | ||
222 | + * Execute a query for a SqlRowSet, given static SQL. | ||
223 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | ||
224 | + * execute a static query with a PreparedStatement, use the overloaded | ||
225 | + * {@code queryForRowSet} method with {@code null} as argument array. | ||
226 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | ||
227 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | ||
228 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | ||
229 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | ||
230 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | ||
231 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | ||
232 | + * @param sql the SQL query to execute | ||
233 | + * @return a SqlRowSet representation (possibly a wrapper around a | ||
234 | + * {@code javax.sql.rowset.CachedRowSet}) | ||
235 | + * @throws DataAccessException if there is any problem executing the query | ||
236 | + * @see #queryForRowSet(String, Object[]) | ||
237 | + * @see SqlRowSetResultSetExtractor | ||
238 | + * @see javax.sql.rowset.CachedRowSet | ||
239 | + */ | ||
240 | + SqlRowSet queryForRowSet(String sql, String[] broadcastTableNames) throws DataAccessException; | ||
241 | + | ||
242 | + /** | ||
243 | + * Issue a single SQL update operation (such as an insert, update or delete statement). | ||
244 | + * @param sql static SQL to execute | ||
245 | + * @return the number of rows affected | ||
246 | + * @throws DataAccessException if there is any problem. | ||
247 | + */ | ||
248 | + int update(String sql, String[] broadcastTableNames) throws DataAccessException; | ||
249 | + | ||
250 | + /** | ||
251 | + * Issue multiple SQL updates on a single JDBC Statement using batching. | ||
252 | + * <p>Will fall back to separate updates on a single Statement if the JDBC | ||
253 | + * driver does not support batch updates. | ||
254 | + * @param sql defining an array of SQL statements that will be executed. | ||
255 | + * @return an array of the number of rows affected by each statement | ||
256 | + * @throws DataAccessException if there is any problem executing the batch | ||
257 | + */ | ||
258 | + int[] batchUpdate(String[] broadcastTableNames, String... sql) throws DataAccessException; | ||
259 | + | ||
260 | + | ||
261 | + //------------------------------------------------------------------------- | ||
262 | + // Methods dealing with prepared statements | ||
263 | + //------------------------------------------------------------------------- | ||
264 | + | ||
265 | + /** | ||
266 | + * Execute a JDBC data access operation, implemented as callback action | ||
267 | + * working on a JDBC PreparedStatement. This allows for implementing arbitrary | ||
268 | + * data access operations on a single Statement, within Spring's managed JDBC | ||
269 | + * environment: that is, participating in Spring-managed transactions and | ||
270 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
271 | + * <p>The callback action can return a result object, for example a domain | ||
272 | + * object or a collection of domain objects. | ||
273 | + * @param psc a callback that creates a PreparedStatement given a Connection | ||
274 | + * @param action a callback that specifies the action | ||
275 | + * @return a result object returned by the action, or {@code null} if none | ||
276 | + * @throws DataAccessException if there is any problem | ||
277 | + */ | ||
278 | + @Nullable | ||
279 | + <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
280 | + | ||
281 | + /** | ||
282 | + * Execute a JDBC data access operation, implemented as callback action | ||
283 | + * working on a JDBC PreparedStatement. This allows for implementing arbitrary | ||
284 | + * data access operations on a single Statement, within Spring's managed JDBC | ||
285 | + * environment: that is, participating in Spring-managed transactions and | ||
286 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
287 | + * <p>The callback action can return a result object, for example a domain | ||
288 | + * object or a collection of domain objects. | ||
289 | + * @param sql the SQL to execute | ||
290 | + * @param action a callback that specifies the action | ||
291 | + * @return a result object returned by the action, or {@code null} if none | ||
292 | + * @throws DataAccessException if there is any problem | ||
293 | + */ | ||
294 | + @Nullable | ||
295 | + <T> T execute(String sql, PreparedStatementCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
296 | + | ||
297 | + /** | ||
298 | + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. | ||
299 | + * <p>A PreparedStatementCreator can either be implemented directly or | ||
300 | + * configured through a PreparedStatementCreatorFactory. | ||
301 | + * @param psc a callback that creates a PreparedStatement given a Connection | ||
302 | + * @param rse a callback that will extract results | ||
303 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
304 | + * @throws DataAccessException if there is any problem | ||
305 | + * @see PreparedStatementCreatorFactory | ||
306 | + */ | ||
307 | + @Nullable | ||
308 | + <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse, String[] broadcastTableNames) throws DataAccessException; | ||
309 | + | ||
310 | + /** | ||
311 | + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. | ||
312 | + * @param sql the SQL query to execute | ||
313 | + * @param pss a callback that knows how to set values on the prepared statement. | ||
314 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | ||
315 | + * Even if there are no bind parameters, this callback may be used to set the | ||
316 | + * fetch size and other performance options. | ||
317 | + * @param rse a callback that will extract results | ||
318 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
319 | + * @throws DataAccessException if there is any problem | ||
320 | + */ | ||
321 | + @Nullable | ||
322 | + <T> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse, String[] broadcastTableNames) throws DataAccessException; | ||
323 | + | ||
324 | + /** | ||
325 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | ||
326 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | ||
327 | + * @param sql the SQL query to execute | ||
328 | + * @param args arguments to bind to the query | ||
329 | + * @param argTypes the SQL types of the arguments | ||
330 | + * (constants from {@code java.sql.Types}) | ||
331 | + * @param rse a callback that will extract results | ||
332 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
333 | + * @throws DataAccessException if the query fails | ||
334 | + * @see java.sql.Types | ||
335 | + */ | ||
336 | + @Nullable | ||
337 | + <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse, String[] broadcastTableNames) throws DataAccessException; | ||
338 | + | ||
339 | + /** | ||
340 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | ||
341 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | ||
342 | + * @param sql the SQL query to execute | ||
343 | + * @param args arguments to bind to the query | ||
344 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
345 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
346 | + * only the argument value but also the SQL type and optionally the scale | ||
347 | + * @param rse a callback that will extract results | ||
348 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
349 | + * @throws DataAccessException if the query fails | ||
350 | + */ | ||
351 | + @Nullable | ||
352 | + <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse, String[] broadcastTableNames) throws DataAccessException; | ||
353 | + | ||
354 | + /** | ||
355 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | ||
356 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | ||
357 | + * @param sql the SQL query to execute | ||
358 | + * @param rse a callback that will extract results | ||
359 | + * @param args arguments to bind to the query | ||
360 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
361 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
362 | + * only the argument value but also the SQL type and optionally the scale | ||
363 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | ||
364 | + * @throws DataAccessException if the query fails | ||
365 | + * @since 3.0.1 | ||
366 | + */ | ||
367 | + @Nullable | ||
368 | + <T> T query(String sql, ResultSetExtractor<T> rse, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
369 | + | ||
370 | + /** | ||
371 | + * Query using a prepared statement, reading the ResultSet on a per-row basis | ||
372 | + * with a RowCallbackHandler. | ||
373 | + * <p>A PreparedStatementCreator can either be implemented directly or | ||
374 | + * configured through a PreparedStatementCreatorFactory. | ||
375 | + * @param psc a callback that creates a PreparedStatement given a Connection | ||
376 | + * @param rch a callback that will extract results, one row at a time | ||
377 | + * @throws DataAccessException if there is any problem | ||
378 | + * @see PreparedStatementCreatorFactory | ||
379 | + */ | ||
380 | + void query(PreparedStatementCreator psc, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException; | ||
381 | + | ||
382 | + /** | ||
383 | + * Query given SQL to create a prepared statement from SQL and a | ||
384 | + * PreparedStatementSetter implementation that knows how to bind values to the | ||
385 | + * query, reading the ResultSet on a per-row basis with a RowCallbackHandler. | ||
386 | + * @param sql the SQL query to execute | ||
387 | + * @param pss a callback that knows how to set values on the prepared statement. | ||
388 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | ||
389 | + * Even if there are no bind parameters, this callback may be used to set the | ||
390 | + * fetch size and other performance options. | ||
391 | + * @param rch a callback that will extract results, one row at a time | ||
392 | + * @throws DataAccessException if the query fails | ||
393 | + */ | ||
394 | + void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException; | ||
395 | + | ||
396 | + /** | ||
397 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
398 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | ||
399 | + * with a RowCallbackHandler. | ||
400 | + * @param sql the SQL query to execute | ||
401 | + * @param args arguments to bind to the query | ||
402 | + * @param argTypes the SQL types of the arguments | ||
403 | + * (constants from {@code java.sql.Types}) | ||
404 | + * @param rch a callback that will extract results, one row at a time | ||
405 | + * @throws DataAccessException if the query fails | ||
406 | + * @see java.sql.Types | ||
407 | + */ | ||
408 | + void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException; | ||
409 | + | ||
410 | + /** | ||
411 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
412 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | ||
413 | + * with a RowCallbackHandler. | ||
414 | + * @param sql the SQL query to execute | ||
415 | + * @param args arguments to bind to the query | ||
416 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
417 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
418 | + * only the argument value but also the SQL type and optionally the scale | ||
419 | + * @param rch a callback that will extract results, one row at a time | ||
420 | + * @throws DataAccessException if the query fails | ||
421 | + */ | ||
422 | + void query(String sql, Object[] args, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException; | ||
423 | + | ||
424 | + /** | ||
425 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
426 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | ||
427 | + * with a RowCallbackHandler. | ||
428 | + * @param sql the SQL query to execute | ||
429 | + * @param rch a callback that will extract results, one row at a time | ||
430 | + * @param args arguments to bind to the query | ||
431 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
432 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
433 | + * only the argument value but also the SQL type and optionally the scale | ||
434 | + * @throws DataAccessException if the query fails | ||
435 | + * @since 3.0.1 | ||
436 | + */ | ||
437 | + void query(String sql, RowCallbackHandler rch, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
438 | + | ||
439 | + /** | ||
440 | + * Query using a prepared statement, mapping each row to a result object | ||
441 | + * via a RowMapper. | ||
442 | + * <p>A PreparedStatementCreator can either be implemented directly or | ||
443 | + * configured through a PreparedStatementCreatorFactory. | ||
444 | + * @param psc a callback that creates a PreparedStatement given a Connection | ||
445 | + * @param rowMapper a callback that will map one object per row | ||
446 | + * @return the result List, containing mapped objects | ||
447 | + * @throws DataAccessException if there is any problem | ||
448 | + * @see PreparedStatementCreatorFactory | ||
449 | + */ | ||
450 | + <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
451 | + | ||
452 | + /** | ||
453 | + * Query given SQL to create a prepared statement from SQL and a | ||
454 | + * PreparedStatementSetter implementation that knows how to bind values | ||
455 | + * to the query, mapping each row to a result object via a RowMapper. | ||
456 | + * @param sql the SQL query to execute | ||
457 | + * @param pss a callback that knows how to set values on the prepared statement. | ||
458 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | ||
459 | + * Even if there are no bind parameters, this callback may be used to set the | ||
460 | + * fetch size and other performance options. | ||
461 | + * @param rowMapper a callback that will map one object per row | ||
462 | + * @return the result List, containing mapped objects | ||
463 | + * @throws DataAccessException if the query fails | ||
464 | + */ | ||
465 | + <T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
466 | + | ||
467 | + /** | ||
468 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
469 | + * arguments to bind to the query, mapping each row to a result object | ||
470 | + * via a RowMapper. | ||
471 | + * @param sql the SQL query to execute | ||
472 | + * @param args arguments to bind to the query | ||
473 | + * @param argTypes the SQL types of the arguments | ||
474 | + * (constants from {@code java.sql.Types}) | ||
475 | + * @param rowMapper a callback that will map one object per row | ||
476 | + * @return the result List, containing mapped objects | ||
477 | + * @throws DataAccessException if the query fails | ||
478 | + * @see java.sql.Types | ||
479 | + */ | ||
480 | + <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
481 | + | ||
482 | + /** | ||
483 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
484 | + * arguments to bind to the query, mapping each row to a result object | ||
485 | + * via a RowMapper. | ||
486 | + * @param sql the SQL query to execute | ||
487 | + * @param args arguments to bind to the query | ||
488 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
489 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
490 | + * only the argument value but also the SQL type and optionally the scale | ||
491 | + * @param rowMapper a callback that will map one object per row | ||
492 | + * @return the result List, containing mapped objects | ||
493 | + * @throws DataAccessException if the query fails | ||
494 | + */ | ||
495 | + <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
496 | + | ||
497 | + /** | ||
498 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
499 | + * arguments to bind to the query, mapping each row to a result object | ||
500 | + * via a RowMapper. | ||
501 | + * @param sql the SQL query to execute | ||
502 | + * @param rowMapper a callback that will map one object per row | ||
503 | + * @param args arguments to bind to the query | ||
504 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
505 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
506 | + * only the argument value but also the SQL type and optionally the scale | ||
507 | + * @return the result List, containing mapped objects | ||
508 | + * @throws DataAccessException if the query fails | ||
509 | + * @since 3.0.1 | ||
510 | + */ | ||
511 | + <T> List<T> query(String sql, RowMapper<T> rowMapper, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
512 | + | ||
513 | + /** | ||
514 | + * Query given SQL to create a prepared statement from SQL and a list | ||
515 | + * of arguments to bind to the query, mapping a single result row to a | ||
516 | + * result object via a RowMapper. | ||
517 | + * @param sql the SQL query to execute | ||
518 | + * @param args arguments to bind to the query | ||
519 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type) | ||
520 | + * @param argTypes the SQL types of the arguments | ||
521 | + * (constants from {@code java.sql.Types}) | ||
522 | + * @param rowMapper a callback that will map one object per row | ||
523 | + * @return the single mapped object (may be {@code null} if the given | ||
524 | + * {@link RowMapper} returned {@code} null) | ||
525 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
526 | + * return exactly one row | ||
527 | + * @throws DataAccessException if the query fails | ||
528 | + */ | ||
529 | + @Nullable | ||
530 | + <T> T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper, String[] broadcastTableNames) | ||
531 | + throws DataAccessException; | ||
532 | + | ||
533 | + /** | ||
534 | + * Query given SQL to create a prepared statement from SQL and a list | ||
535 | + * of arguments to bind to the query, mapping a single result row to a | ||
536 | + * result object via a RowMapper. | ||
537 | + * @param sql the SQL query to execute | ||
538 | + * @param args arguments to bind to the query | ||
539 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
540 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
541 | + * only the argument value but also the SQL type and optionally the scale | ||
542 | + * @param rowMapper a callback that will map one object per row | ||
543 | + * @return the single mapped object (may be {@code null} if the given | ||
544 | + * {@link RowMapper} returned {@code} null) | ||
545 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
546 | + * return exactly one row | ||
547 | + * @throws DataAccessException if the query fails | ||
548 | + */ | ||
549 | + @Nullable | ||
550 | + <T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper, String[] broadcastTableNames) throws DataAccessException; | ||
551 | + | ||
552 | + /** | ||
553 | + * Query given SQL to create a prepared statement from SQL and a list | ||
554 | + * of arguments to bind to the query, mapping a single result row to a | ||
555 | + * result object via a RowMapper. | ||
556 | + * @param sql the SQL query to execute | ||
557 | + * @param rowMapper a callback that will map one object per row | ||
558 | + * @param args arguments to bind to the query | ||
559 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
560 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
561 | + * only the argument value but also the SQL type and optionally the scale | ||
562 | + * @return the single mapped object (may be {@code null} if the given | ||
563 | + * {@link RowMapper} returned {@code} null) | ||
564 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
565 | + * return exactly one row | ||
566 | + * @throws DataAccessException if the query fails | ||
567 | + * @since 3.0.1 | ||
568 | + */ | ||
569 | + @Nullable | ||
570 | + <T> T queryForObject(String sql, RowMapper<T> rowMapper, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
571 | + | ||
572 | + /** | ||
573 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
574 | + * arguments to bind to the query, expecting a result object. | ||
575 | + * <p>The query is expected to be a single row/single column query; the returned | ||
576 | + * result will be directly mapped to the corresponding object type. | ||
577 | + * @param sql the SQL query to execute | ||
578 | + * @param args arguments to bind to the query | ||
579 | + * @param argTypes the SQL types of the arguments | ||
580 | + * (constants from {@code java.sql.Types}) | ||
581 | + * @param requiredType the type that the result object is expected to match | ||
582 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | ||
583 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | ||
584 | + * exactly one row, or does not return exactly one column in that row | ||
585 | + * @throws DataAccessException if the query fails | ||
586 | + * @see #queryForObject(String, Class) | ||
587 | + * @see java.sql.Types | ||
588 | + */ | ||
589 | + @Nullable | ||
590 | + <T> T queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType, String[] broadcastTableNames) | ||
591 | + throws DataAccessException; | ||
592 | + | ||
593 | + /** | ||
594 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
595 | + * arguments to bind to the query, expecting a result object. | ||
596 | + * <p>The query is expected to be a single row/single column query; the returned | ||
597 | + * result will be directly mapped to the corresponding object type. | ||
598 | + * @param sql the SQL query to execute | ||
599 | + * @param args arguments to bind to the query | ||
600 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
601 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
602 | + * only the argument value but also the SQL type and optionally the scale | ||
603 | + * @param requiredType the type that the result object is expected to match | ||
604 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | ||
605 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | ||
606 | + * exactly one row, or does not return exactly one column in that row | ||
607 | + * @throws DataAccessException if the query fails | ||
608 | + * @see #queryForObject(String, Class) | ||
609 | + */ | ||
610 | + @Nullable | ||
611 | + <T> T queryForObject(String sql, Object[] args, Class<T> requiredType, String[] broadcastTableNames) throws DataAccessException; | ||
612 | + | ||
613 | + /** | ||
614 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
615 | + * arguments to bind to the query, expecting a result object. | ||
616 | + * <p>The query is expected to be a single row/single column query; the returned | ||
617 | + * result will be directly mapped to the corresponding object type. | ||
618 | + * @param sql the SQL query to execute | ||
619 | + * @param requiredType the type that the result object is expected to match | ||
620 | + * @param args arguments to bind to the query | ||
621 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
622 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
623 | + * only the argument value but also the SQL type and optionally the scale | ||
624 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | ||
625 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | ||
626 | + * exactly one row, or does not return exactly one column in that row | ||
627 | + * @throws DataAccessException if the query fails | ||
628 | + * @since 3.0.1 | ||
629 | + * @see #queryForObject(String, Class) | ||
630 | + */ | ||
631 | + @Nullable | ||
632 | + <T> T queryForObject(String sql, Class<T> requiredType, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
633 | + | ||
634 | + /** | ||
635 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
636 | + * arguments to bind to the query, expecting a result map. | ||
637 | + * <p>The query is expected to be a single row query; the result row will be | ||
638 | + * mapped to a Map (one entry for each column, using the column name as the key). | ||
639 | + * @param sql the SQL query to execute | ||
640 | + * @param args arguments to bind to the query | ||
641 | + * @param argTypes the SQL types of the arguments | ||
642 | + * (constants from {@code java.sql.Types}) | ||
643 | + * @return the result Map (one entry per column, with column name as key) | ||
644 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
645 | + * return exactly one row | ||
646 | + * @throws DataAccessException if the query fails | ||
647 | + * @see #queryForMap(String) | ||
648 | + * @see ColumnMapRowMapper | ||
649 | + * @see java.sql.Types | ||
650 | + */ | ||
651 | + Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) throws DataAccessException; | ||
652 | + | ||
653 | + /** | ||
654 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
655 | + * arguments to bind to the query, expecting a result map. | ||
656 | + * <p>The {@code queryForMap} methods defined by this interface are appropriate | ||
657 | + * when you don't have a domain model. Otherwise, consider using one of the | ||
658 | + * {@code queryForObject} methods. | ||
659 | + * <p>The query is expected to be a single row query; the result row will be | ||
660 | + * mapped to a Map (one entry for each column, using the column name as the key). | ||
661 | + * @param sql the SQL query to execute | ||
662 | + * @param args arguments to bind to the query | ||
663 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
664 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
665 | + * only the argument value but also the SQL type and optionally the scale | ||
666 | + * @return the result Map (one entry for each column, using the | ||
667 | + * column name as the key) | ||
668 | + * @throws IncorrectResultSizeDataAccessException if the query does not | ||
669 | + * return exactly one row | ||
670 | + * @throws DataAccessException if the query fails | ||
671 | + * @see #queryForMap(String) | ||
672 | + * @see ColumnMapRowMapper | ||
673 | + */ | ||
674 | + Map<String, Object> queryForMap(String sql, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
675 | + | ||
676 | + /** | ||
677 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
678 | + * arguments to bind to the query, expecting a result list. | ||
679 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
680 | + * result objects, each of them matching the specified element type. | ||
681 | + * @param sql the SQL query to execute | ||
682 | + * @param args arguments to bind to the query | ||
683 | + * @param argTypes the SQL types of the arguments | ||
684 | + * (constants from {@code java.sql.Types}) | ||
685 | + * @param elementType the required type of element in the result list | ||
686 | + * (for example, {@code Integer.class}) | ||
687 | + * @return a List of objects that match the specified element type | ||
688 | + * @throws DataAccessException if the query fails | ||
689 | + * @see #queryForList(String, Class) | ||
690 | + * @see SingleColumnRowMapper | ||
691 | + */ | ||
692 | + <T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType, String[] broadcastTableNames) | ||
693 | + throws DataAccessException; | ||
694 | + | ||
695 | + /** | ||
696 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
697 | + * arguments to bind to the query, expecting a result list. | ||
698 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
699 | + * result objects, each of them matching the specified element type. | ||
700 | + * @param sql the SQL query to execute | ||
701 | + * @param args arguments to bind to the query | ||
702 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
703 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
704 | + * only the argument value but also the SQL type and optionally the scale | ||
705 | + * @param elementType the required type of element in the result list | ||
706 | + * (for example, {@code Integer.class}) | ||
707 | + * @return a List of objects that match the specified element type | ||
708 | + * @throws DataAccessException if the query fails | ||
709 | + * @see #queryForList(String, Class) | ||
710 | + * @see SingleColumnRowMapper | ||
711 | + */ | ||
712 | + <T> List<T> queryForList(String sql, Object[] args, Class<T> elementType, String[] broadcastTableNames) throws DataAccessException; | ||
713 | + | ||
714 | + /** | ||
715 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
716 | + * arguments to bind to the query, expecting a result list. | ||
717 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
718 | + * result objects, each of them matching the specified element type. | ||
719 | + * @param sql the SQL query to execute | ||
720 | + * @param elementType the required type of element in the result list | ||
721 | + * (for example, {@code Integer.class}) | ||
722 | + * @param args arguments to bind to the query | ||
723 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
724 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
725 | + * only the argument value but also the SQL type and optionally the scale | ||
726 | + * @return a List of objects that match the specified element type | ||
727 | + * @throws DataAccessException if the query fails | ||
728 | + * @since 3.0.1 | ||
729 | + * @see #queryForList(String, Class) | ||
730 | + * @see SingleColumnRowMapper | ||
731 | + */ | ||
732 | + <T> List<T> queryForList(String sql, Class<T> elementType, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
733 | + | ||
734 | + /** | ||
735 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
736 | + * arguments to bind to the query, expecting a result list. | ||
737 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
738 | + * Maps (one entry for each column, using the column name as the key). | ||
739 | + * Each element in the list will be of the form returned by this interface's | ||
740 | + * {@code queryForMap} methods. | ||
741 | + * @param sql the SQL query to execute | ||
742 | + * @param args arguments to bind to the query | ||
743 | + * @param argTypes the SQL types of the arguments | ||
744 | + * (constants from {@code java.sql.Types}) | ||
745 | + * @return a List that contains a Map per row | ||
746 | + * @throws DataAccessException if the query fails | ||
747 | + * @see #queryForList(String) | ||
748 | + * @see java.sql.Types | ||
749 | + */ | ||
750 | + List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) throws DataAccessException; | ||
751 | + | ||
752 | + /** | ||
753 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
754 | + * arguments to bind to the query, expecting a result list. | ||
755 | + * <p>The results will be mapped to a List (one entry for each row) of | ||
756 | + * Maps (one entry for each column, using the column name as the key). | ||
757 | + * Each element in the list will be of the form returned by this interface's | ||
758 | + * {@code queryForMap} methods. | ||
759 | + * @param sql the SQL query to execute | ||
760 | + * @param args arguments to bind to the query | ||
761 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
762 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
763 | + * only the argument value but also the SQL type and optionally the scale | ||
764 | + * @return a List that contains a Map per row | ||
765 | + * @throws DataAccessException if the query fails | ||
766 | + * @see #queryForList(String) | ||
767 | + */ | ||
768 | + List<Map<String, Object>> queryForList(String sql, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
769 | + | ||
770 | + /** | ||
771 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
772 | + * arguments to bind to the query, expecting a SqlRowSet. | ||
773 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | ||
774 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | ||
775 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | ||
776 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | ||
777 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | ||
778 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | ||
779 | + * @param sql the SQL query to execute | ||
780 | + * @param args arguments to bind to the query | ||
781 | + * @param argTypes the SQL types of the arguments | ||
782 | + * (constants from {@code java.sql.Types}) | ||
783 | + * @return a SqlRowSet representation (possibly a wrapper around a | ||
784 | + * {@code javax.sql.rowset.CachedRowSet}) | ||
785 | + * @throws DataAccessException if there is any problem executing the query | ||
786 | + * @see #queryForRowSet(String) | ||
787 | + * @see SqlRowSetResultSetExtractor | ||
788 | + * @see javax.sql.rowset.CachedRowSet | ||
789 | + * @see java.sql.Types | ||
790 | + */ | ||
791 | + SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) throws DataAccessException; | ||
792 | + | ||
793 | + /** | ||
794 | + * Query given SQL to create a prepared statement from SQL and a list of | ||
795 | + * arguments to bind to the query, expecting a SqlRowSet. | ||
796 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | ||
797 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | ||
798 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | ||
799 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | ||
800 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | ||
801 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | ||
802 | + * @param sql the SQL query to execute | ||
803 | + * @param args arguments to bind to the query | ||
804 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
805 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
806 | + * only the argument value but also the SQL type and optionally the scale | ||
807 | + * @return a SqlRowSet representation (possibly a wrapper around a | ||
808 | + * {@code javax.sql.rowset.CachedRowSet}) | ||
809 | + * @throws DataAccessException if there is any problem executing the query | ||
810 | + * @see #queryForRowSet(String) | ||
811 | + * @see SqlRowSetResultSetExtractor | ||
812 | + * @see javax.sql.rowset.CachedRowSet | ||
813 | + */ | ||
814 | + SqlRowSet queryForRowSet(String sql, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
815 | + | ||
816 | + /** | ||
817 | + * Issue a single SQL update operation (such as an insert, update or delete | ||
818 | + * statement) using a PreparedStatementCreator to provide SQL and any | ||
819 | + * required parameters. | ||
820 | + * <p>A PreparedStatementCreator can either be implemented directly or | ||
821 | + * configured through a PreparedStatementCreatorFactory. | ||
822 | + * @param psc a callback that provides SQL and any necessary parameters | ||
823 | + * @return the number of rows affected | ||
824 | + * @throws DataAccessException if there is any problem issuing the update | ||
825 | + * @see PreparedStatementCreatorFactory | ||
826 | + */ | ||
827 | + int update(PreparedStatementCreator psc, String[] broadcastTableNames) throws DataAccessException; | ||
828 | + | ||
829 | + /** | ||
830 | + * Issue an update statement using a PreparedStatementCreator to provide SQL and | ||
831 | + * any required parameters. Generated keys will be put into the given KeyHolder. | ||
832 | + * <p>Note that the given PreparedStatementCreator has to create a statement | ||
833 | + * with activated extraction of generated keys (a JDBC 3.0 feature). This can | ||
834 | + * either be done directly or through using a PreparedStatementCreatorFactory. | ||
835 | + * @param psc a callback that provides SQL and any necessary parameters | ||
836 | + * @param generatedKeyHolder a KeyHolder that will hold the generated keys | ||
837 | + * @return the number of rows affected | ||
838 | + * @throws DataAccessException if there is any problem issuing the update | ||
839 | + * @see PreparedStatementCreatorFactory | ||
840 | + * @see org.springframework.jdbc.support.GeneratedKeyHolder | ||
841 | + */ | ||
842 | + int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder, String[] broadcastTableNames) throws DataAccessException; | ||
843 | + | ||
844 | + /** | ||
845 | + * Issue an update statement using a PreparedStatementSetter to set bind parameters, | ||
846 | + * with given SQL. Simpler than using a PreparedStatementCreator as this method | ||
847 | + * will create the PreparedStatement: The PreparedStatementSetter just needs to | ||
848 | + * set parameters. | ||
849 | + * @param sql the SQL containing bind parameters | ||
850 | + * @param pss helper that sets bind parameters. If this is {@code null} | ||
851 | + * we run an update with static SQL. | ||
852 | + * @return the number of rows affected | ||
853 | + * @throws DataAccessException if there is any problem issuing the update | ||
854 | + */ | ||
855 | + int update(String sql, @Nullable PreparedStatementSetter pss, String[] broadcastTableNames) throws DataAccessException; | ||
856 | + | ||
857 | + /** | ||
858 | + * Issue a single SQL update operation (such as an insert, update or delete statement) | ||
859 | + * via a prepared statement, binding the given arguments. | ||
860 | + * @param sql the SQL containing bind parameters | ||
861 | + * @param args arguments to bind to the query | ||
862 | + * @param argTypes the SQL types of the arguments | ||
863 | + * (constants from {@code java.sql.Types}) | ||
864 | + * @return the number of rows affected | ||
865 | + * @throws DataAccessException if there is any problem issuing the update | ||
866 | + * @see java.sql.Types | ||
867 | + */ | ||
868 | + int update(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) throws DataAccessException; | ||
869 | + | ||
870 | + /** | ||
871 | + * Issue a single SQL update operation (such as an insert, update or delete statement) | ||
872 | + * via a prepared statement, binding the given arguments. | ||
873 | + * @param sql the SQL containing bind parameters | ||
874 | + * @param args arguments to bind to the query | ||
875 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | ||
876 | + * may also contain {@link SqlParameterValue} objects which indicate not | ||
877 | + * only the argument value but also the SQL type and optionally the scale | ||
878 | + * @return the number of rows affected | ||
879 | + * @throws DataAccessException if there is any problem issuing the update | ||
880 | + */ | ||
881 | + int update(String sql, String[] broadcastTableNames, @Nullable Object... args) throws DataAccessException; | ||
882 | + | ||
883 | + /** | ||
884 | + * Issue multiple update statements on a single PreparedStatement, | ||
885 | + * using batch updates and a BatchPreparedStatementSetter to set values. | ||
886 | + * <p>Will fall back to separate updates on a single PreparedStatement | ||
887 | + * if the JDBC driver does not support batch updates. | ||
888 | + * @param sql defining PreparedStatement that will be reused. | ||
889 | + * All statements in the batch will use the same SQL. | ||
890 | + * @param pss object to set parameters on the PreparedStatement | ||
891 | + * created by this method | ||
892 | + * @return an array of the number of rows affected by each statement | ||
893 | + * @throws DataAccessException if there is any problem issuing the update | ||
894 | + */ | ||
895 | + int[] batchUpdate(String sql, BatchPreparedStatementSetter pss, String[] broadcastTableNames) throws DataAccessException; | ||
896 | + | ||
897 | + /** | ||
898 | + * Execute a batch using the supplied SQL statement with the batch of supplied arguments. | ||
899 | + * @param sql the SQL statement to execute | ||
900 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | ||
901 | + * @return an array containing the numbers of rows affected by each update in the batch | ||
902 | + */ | ||
903 | + int[] batchUpdate(String sql, List<Object[]> batchArgs, String[] broadcastTableNames) throws DataAccessException; | ||
904 | + | ||
905 | + /** | ||
906 | + * Execute a batch using the supplied SQL statement with the batch of supplied arguments. | ||
907 | + * @param sql the SQL statement to execute. | ||
908 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | ||
909 | + * @param argTypes the SQL types of the arguments | ||
910 | + * (constants from {@code java.sql.Types}) | ||
911 | + * @return an array containing the numbers of rows affected by each update in the batch | ||
912 | + */ | ||
913 | + int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes, String[] broadcastTableNames) throws DataAccessException; | ||
914 | + | ||
915 | + /** | ||
916 | + * Execute multiple batches using the supplied SQL statement with the collect of supplied arguments. | ||
917 | + * The arguments' values will be set using the ParameterizedPreparedStatementSetter. | ||
918 | + * Each batch should be of size indicated in 'batchSize'. | ||
919 | + * @param sql the SQL statement to execute. | ||
920 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | ||
921 | + * @param batchSize batch size | ||
922 | + * @param pss the ParameterizedPreparedStatementSetter to use | ||
923 | + * @return an array containing for each batch another array containing the numbers of rows affected | ||
924 | + * by each update in the batch | ||
925 | + * @since 3.1 | ||
926 | + */ | ||
927 | + <T> int[][] batchUpdate(String sql, Collection<T> batchArgs, int batchSize, | ||
928 | + ParameterizedPreparedStatementSetter<T> pss, String[] broadcastTableNames) throws DataAccessException; | ||
929 | + | ||
930 | + | ||
931 | + //------------------------------------------------------------------------- | ||
932 | + // Methods dealing with callable statements | ||
933 | + //------------------------------------------------------------------------- | ||
934 | + | ||
935 | + /** | ||
936 | + * Execute a JDBC data access operation, implemented as callback action | ||
937 | + * working on a JDBC CallableStatement. This allows for implementing arbitrary | ||
938 | + * data access operations on a single Statement, within Spring's managed JDBC | ||
939 | + * environment: that is, participating in Spring-managed transactions and | ||
940 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
941 | + * <p>The callback action can return a result object, for example a domain | ||
942 | + * object or a collection of domain objects. | ||
943 | + * @param csc a callback that creates a CallableStatement given a Connection | ||
944 | + * @param action a callback that specifies the action | ||
945 | + * @return a result object returned by the action, or {@code null} if none | ||
946 | + * @throws DataAccessException if there is any problem | ||
947 | + */ | ||
948 | + @Nullable | ||
949 | + <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
950 | + | ||
951 | + /** | ||
952 | + * Execute a JDBC data access operation, implemented as callback action | ||
953 | + * working on a JDBC CallableStatement. This allows for implementing arbitrary | ||
954 | + * data access operations on a single Statement, within Spring's managed JDBC | ||
955 | + * environment: that is, participating in Spring-managed transactions and | ||
956 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | ||
957 | + * <p>The callback action can return a result object, for example a domain | ||
958 | + * object or a collection of domain objects. | ||
959 | + * @param callString the SQL call string to execute | ||
960 | + * @param action a callback that specifies the action | ||
961 | + * @return a result object returned by the action, or {@code null} if none | ||
962 | + * @throws DataAccessException if there is any problem | ||
963 | + */ | ||
964 | + @Nullable | ||
965 | + <T> T execute(String callString, CallableStatementCallback<T> action, String[] broadcastTableNames) throws DataAccessException; | ||
966 | + | ||
967 | + /** | ||
968 | + * Execute a SQL call using a CallableStatementCreator to provide SQL and | ||
969 | + * any required parameters. | ||
970 | + * @param csc a callback that provides SQL and any necessary parameters | ||
971 | + * @param declaredParameters list of declared SqlParameter objects | ||
972 | + * @return a Map of extracted out parameters | ||
973 | + * @throws DataAccessException if there is any problem issuing the update | ||
974 | + */ | ||
975 | + Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters, String[] broadcastTableNames) throws DataAccessException; | ||
976 | +} |
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateBroadcastImpl.java
0 → 100644
@@ -0,0 +1,667 @@ | @@ -0,0 +1,667 @@ | ||
1 | +package com.taover.repository.jdbctemplate; | ||
2 | + | ||
3 | +import java.util.Collection; | ||
4 | +import java.util.List; | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import org.apache.shardingsphere.api.hint.HintManager; | ||
8 | +import org.springframework.dao.DataAccessException; | ||
9 | +import org.springframework.jdbc.core.BatchPreparedStatementSetter; | ||
10 | +import org.springframework.jdbc.core.CallableStatementCallback; | ||
11 | +import org.springframework.jdbc.core.CallableStatementCreator; | ||
12 | +import org.springframework.jdbc.core.ConnectionCallback; | ||
13 | +import org.springframework.jdbc.core.JdbcTemplate; | ||
14 | +import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter; | ||
15 | +import org.springframework.jdbc.core.PreparedStatementCallback; | ||
16 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
17 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
18 | +import org.springframework.jdbc.core.ResultSetExtractor; | ||
19 | +import org.springframework.jdbc.core.RowCallbackHandler; | ||
20 | +import org.springframework.jdbc.core.RowMapper; | ||
21 | +import org.springframework.jdbc.core.SqlParameter; | ||
22 | +import org.springframework.jdbc.core.StatementCallback; | ||
23 | +import org.springframework.jdbc.support.KeyHolder; | ||
24 | +import org.springframework.jdbc.support.rowset.SqlRowSet; | ||
25 | + | ||
26 | +import com.taover.repository.shardingsphere.ShardingInfoEntity; | ||
27 | +import com.taover.repository.shardingsphere.ShardingSphereService; | ||
28 | + | ||
29 | +public class JdbcTemplateBroadcastImpl implements JdbcTemplateBroadcast { | ||
30 | + private JdbcTemplate jdbcTemplate; | ||
31 | + private ShardingSphereService shardingSphereService; | ||
32 | + | ||
33 | + public JdbcTemplateBroadcastImpl(JdbcTemplate jdbcTemplate, ShardingSphereService shardingSphereService) { | ||
34 | + this.jdbcTemplate = jdbcTemplate; | ||
35 | + this.shardingSphereService = shardingSphereService; | ||
36 | + } | ||
37 | + | ||
38 | + @Override | ||
39 | + public void loadShardingInfo(String[] broadcastTableNames) { | ||
40 | + List<ShardingInfoEntity> shardingInfo = this.shardingSphereService.getShardingInfoByTableNames(broadcastTableNames); | ||
41 | + if(shardingInfo == null || shardingInfo.isEmpty()) { | ||
42 | + return; | ||
43 | + } | ||
44 | + HintManager.clear(); | ||
45 | + HintManager instance = HintManager.getInstance(); | ||
46 | + for(ShardingInfoEntity item: shardingInfo) { | ||
47 | + instance.addTableShardingValue(item.getTableName(), item.getTableSuffix()); | ||
48 | + instance.addDatabaseShardingValue(item.getTableName(), item.getDsName()); | ||
49 | + } | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public void clearShardingInfo() { | ||
54 | + HintManager.clear(); | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public <E> E execute(ConnectionCallback<E> action, String[] broadcastTableNames) throws DataAccessException { | ||
59 | + try { | ||
60 | + this.loadShardingInfo(broadcastTableNames); | ||
61 | + return this.jdbcTemplate.execute(action); | ||
62 | + }finally { | ||
63 | + this.clearShardingInfo(); | ||
64 | + } | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public <E> E execute(StatementCallback<E> action, String[] broadcastTableNames) throws DataAccessException { | ||
69 | + try { | ||
70 | + this.loadShardingInfo(broadcastTableNames); | ||
71 | + return this.jdbcTemplate.execute(action); | ||
72 | + }finally { | ||
73 | + this.clearShardingInfo(); | ||
74 | + } | ||
75 | + } | ||
76 | + | ||
77 | + @Override | ||
78 | + public void execute(String sql, String[] broadcastTableNames) throws DataAccessException { | ||
79 | + try { | ||
80 | + this.loadShardingInfo(broadcastTableNames); | ||
81 | + this.jdbcTemplate.execute(sql); | ||
82 | + }finally { | ||
83 | + this.clearShardingInfo(); | ||
84 | + } | ||
85 | + } | ||
86 | + | ||
87 | + @Override | ||
88 | + public <E> E query(String sql, ResultSetExtractor<E> rse, String[] broadcastTableNames) throws DataAccessException { | ||
89 | + try { | ||
90 | + this.loadShardingInfo(broadcastTableNames); | ||
91 | + return this.jdbcTemplate.query(sql, rse); | ||
92 | + }finally { | ||
93 | + this.clearShardingInfo(); | ||
94 | + } | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public void query(String sql, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException { | ||
99 | + try { | ||
100 | + this.loadShardingInfo(broadcastTableNames); | ||
101 | + this.jdbcTemplate.query(sql, rch); | ||
102 | + }finally { | ||
103 | + this.clearShardingInfo(); | ||
104 | + } | ||
105 | + } | ||
106 | + | ||
107 | + @Override | ||
108 | + public <E> List<E> query(String sql, RowMapper<E> rowMapper, String[] broadcastTableNames) throws DataAccessException { | ||
109 | + try { | ||
110 | + this.loadShardingInfo(broadcastTableNames); | ||
111 | + return this.jdbcTemplate.query(sql, rowMapper); | ||
112 | + }finally { | ||
113 | + this.clearShardingInfo(); | ||
114 | + } | ||
115 | + } | ||
116 | + | ||
117 | + @Override | ||
118 | + public <E> E queryForObject(String sql, RowMapper<E> rowMapper, String[] broadcastTableNames) throws DataAccessException { | ||
119 | + try { | ||
120 | + this.loadShardingInfo(broadcastTableNames); | ||
121 | + return this.jdbcTemplate.queryForObject(sql, rowMapper); | ||
122 | + }finally { | ||
123 | + this.clearShardingInfo(); | ||
124 | + } | ||
125 | + } | ||
126 | + | ||
127 | + @Override | ||
128 | + public <E> E queryForObject(String sql, Class<E> requiredType, String[] broadcastTableNames) throws DataAccessException { | ||
129 | + try { | ||
130 | + this.loadShardingInfo(broadcastTableNames); | ||
131 | + return this.jdbcTemplate.queryForObject(sql, requiredType); | ||
132 | + }finally { | ||
133 | + this.clearShardingInfo(); | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
137 | + @Override | ||
138 | + public Map<String, Object> queryForMap(String sql, String[] broadcastTableNames) throws DataAccessException { | ||
139 | + try { | ||
140 | + this.loadShardingInfo(broadcastTableNames); | ||
141 | + return this.jdbcTemplate.queryForMap(sql); | ||
142 | + }finally { | ||
143 | + this.clearShardingInfo(); | ||
144 | + } | ||
145 | + } | ||
146 | + | ||
147 | + @Override | ||
148 | + public <E> List<E> queryForList(String sql, Class<E> elementType, String[] broadcastTableNames) throws DataAccessException { | ||
149 | + try { | ||
150 | + this.loadShardingInfo(broadcastTableNames); | ||
151 | + return this.jdbcTemplate.queryForList(sql, elementType); | ||
152 | + }finally { | ||
153 | + this.clearShardingInfo(); | ||
154 | + } | ||
155 | + } | ||
156 | + | ||
157 | + @Override | ||
158 | + public List<Map<String, Object>> queryForList(String sql, String[] broadcastTableNames) throws DataAccessException { | ||
159 | + try { | ||
160 | + this.loadShardingInfo(broadcastTableNames); | ||
161 | + return this.jdbcTemplate.queryForList(sql); | ||
162 | + }finally { | ||
163 | + this.clearShardingInfo(); | ||
164 | + } | ||
165 | + } | ||
166 | + | ||
167 | + @Override | ||
168 | + public SqlRowSet queryForRowSet(String sql, String[] broadcastTableNames) throws DataAccessException { | ||
169 | + try { | ||
170 | + this.loadShardingInfo(broadcastTableNames); | ||
171 | + return this.jdbcTemplate.queryForRowSet(sql); | ||
172 | + }finally { | ||
173 | + this.clearShardingInfo(); | ||
174 | + } | ||
175 | + } | ||
176 | + | ||
177 | + @Override | ||
178 | + public int update(String sql, String[] broadcastTableNames) throws DataAccessException { | ||
179 | + try { | ||
180 | + this.loadShardingInfo(broadcastTableNames); | ||
181 | + return this.jdbcTemplate.update(sql); | ||
182 | + }finally { | ||
183 | + this.clearShardingInfo(); | ||
184 | + } | ||
185 | + } | ||
186 | + | ||
187 | + @Override | ||
188 | + public int[] batchUpdate(String[] broadcastTableNames, String... sql) throws DataAccessException { | ||
189 | + try { | ||
190 | + this.loadShardingInfo(broadcastTableNames); | ||
191 | + return this.jdbcTemplate.batchUpdate(sql); | ||
192 | + }finally { | ||
193 | + this.clearShardingInfo(); | ||
194 | + } | ||
195 | + } | ||
196 | + | ||
197 | + @Override | ||
198 | + public <E> E execute(PreparedStatementCreator psc, PreparedStatementCallback<E> action, String[] broadcastTableNames) | ||
199 | + throws DataAccessException { | ||
200 | + try { | ||
201 | + this.loadShardingInfo(broadcastTableNames); | ||
202 | + return this.jdbcTemplate.execute(psc, action); | ||
203 | + }finally { | ||
204 | + this.clearShardingInfo(); | ||
205 | + } | ||
206 | + } | ||
207 | + | ||
208 | + @Override | ||
209 | + public <E> E execute(String sql, PreparedStatementCallback<E> action, String[] broadcastTableNames) throws DataAccessException { | ||
210 | + try { | ||
211 | + this.loadShardingInfo(broadcastTableNames); | ||
212 | + return this.jdbcTemplate.execute(sql, action); | ||
213 | + }finally { | ||
214 | + this.clearShardingInfo(); | ||
215 | + } | ||
216 | + } | ||
217 | + | ||
218 | + @Override | ||
219 | + public <E> E query(PreparedStatementCreator psc, ResultSetExtractor<E> rse, String[] broadcastTableNames) | ||
220 | + throws DataAccessException { | ||
221 | + try { | ||
222 | + this.loadShardingInfo(broadcastTableNames); | ||
223 | + return this.jdbcTemplate.query(psc, rse); | ||
224 | + }finally { | ||
225 | + this.clearShardingInfo(); | ||
226 | + } | ||
227 | + } | ||
228 | + | ||
229 | + @Override | ||
230 | + public <E> E query(String sql, PreparedStatementSetter pss, ResultSetExtractor<E> rse, String[] broadcastTableNames) | ||
231 | + throws DataAccessException { | ||
232 | + try { | ||
233 | + this.loadShardingInfo(broadcastTableNames); | ||
234 | + return this.jdbcTemplate.query(sql, pss, rse); | ||
235 | + }finally { | ||
236 | + this.clearShardingInfo(); | ||
237 | + } | ||
238 | + } | ||
239 | + | ||
240 | + @Override | ||
241 | + public <E> E query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<E> rse, String[] broadcastTableNames) | ||
242 | + throws DataAccessException { | ||
243 | + try { | ||
244 | + this.loadShardingInfo(broadcastTableNames); | ||
245 | + return this.jdbcTemplate.query(sql, args, argTypes, rse); | ||
246 | + }finally { | ||
247 | + this.clearShardingInfo(); | ||
248 | + } | ||
249 | + } | ||
250 | + | ||
251 | + @Override | ||
252 | + public <E> E query(String sql, Object[] args, ResultSetExtractor<E> rse, String[] broadcastTableNames) throws DataAccessException { | ||
253 | + try { | ||
254 | + this.loadShardingInfo(broadcastTableNames); | ||
255 | + return this.jdbcTemplate.query(sql, args, rse); | ||
256 | + }finally { | ||
257 | + this.clearShardingInfo(); | ||
258 | + } | ||
259 | + } | ||
260 | + | ||
261 | + @Override | ||
262 | + public <E> E query(String sql, ResultSetExtractor<E> rse, String[] broadcastTableNames, Object... args) | ||
263 | + throws DataAccessException { | ||
264 | + try { | ||
265 | + this.loadShardingInfo(broadcastTableNames); | ||
266 | + return this.jdbcTemplate.query(sql, rse, args); | ||
267 | + }finally { | ||
268 | + this.clearShardingInfo(); | ||
269 | + } | ||
270 | + } | ||
271 | + | ||
272 | + @Override | ||
273 | + public void query(PreparedStatementCreator psc, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException { | ||
274 | + try { | ||
275 | + this.loadShardingInfo(broadcastTableNames); | ||
276 | + this.jdbcTemplate.query(psc, rch); | ||
277 | + }finally { | ||
278 | + this.clearShardingInfo(); | ||
279 | + } | ||
280 | + } | ||
281 | + | ||
282 | + @Override | ||
283 | + public void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch, String[] broadcastTableNames) | ||
284 | + throws DataAccessException { | ||
285 | + try { | ||
286 | + this.loadShardingInfo(broadcastTableNames); | ||
287 | + this.jdbcTemplate.query(sql, pss, rch); | ||
288 | + }finally { | ||
289 | + this.clearShardingInfo(); | ||
290 | + } | ||
291 | + } | ||
292 | + | ||
293 | + @Override | ||
294 | + public void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch, String[] broadcastTableNames) | ||
295 | + throws DataAccessException { | ||
296 | + try { | ||
297 | + this.loadShardingInfo(broadcastTableNames); | ||
298 | + this.jdbcTemplate.query(sql, args, argTypes, rch); | ||
299 | + }finally { | ||
300 | + this.clearShardingInfo(); | ||
301 | + } | ||
302 | + } | ||
303 | + | ||
304 | + @Override | ||
305 | + public void query(String sql, Object[] args, RowCallbackHandler rch, String[] broadcastTableNames) throws DataAccessException { | ||
306 | + try { | ||
307 | + this.loadShardingInfo(broadcastTableNames); | ||
308 | + this.jdbcTemplate.query(sql, args, rch); | ||
309 | + }finally { | ||
310 | + this.clearShardingInfo(); | ||
311 | + } | ||
312 | + } | ||
313 | + | ||
314 | + @Override | ||
315 | + public void query(String sql, RowCallbackHandler rch, String[] broadcastTableNames, Object... args) throws DataAccessException { | ||
316 | + try { | ||
317 | + this.loadShardingInfo(broadcastTableNames); | ||
318 | + this.jdbcTemplate.query(sql, rch, args); | ||
319 | + }finally { | ||
320 | + this.clearShardingInfo(); | ||
321 | + } | ||
322 | + } | ||
323 | + | ||
324 | + @Override | ||
325 | + public <E> List<E> query(PreparedStatementCreator psc, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
326 | + throws DataAccessException { | ||
327 | + try { | ||
328 | + this.loadShardingInfo(broadcastTableNames); | ||
329 | + return this.jdbcTemplate.query(psc, rowMapper); | ||
330 | + }finally { | ||
331 | + this.clearShardingInfo(); | ||
332 | + } | ||
333 | + } | ||
334 | + | ||
335 | + @Override | ||
336 | + public <E> List<E> query(String sql, PreparedStatementSetter pss, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
337 | + throws DataAccessException { | ||
338 | + try { | ||
339 | + this.loadShardingInfo(broadcastTableNames); | ||
340 | + return this.jdbcTemplate.query(sql, pss, rowMapper); | ||
341 | + }finally { | ||
342 | + this.clearShardingInfo(); | ||
343 | + } | ||
344 | + } | ||
345 | + | ||
346 | + @Override | ||
347 | + public <E> List<E> query(String sql, Object[] args, int[] argTypes, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
348 | + throws DataAccessException { | ||
349 | + try { | ||
350 | + this.loadShardingInfo(broadcastTableNames); | ||
351 | + return this.jdbcTemplate.query(sql, args, argTypes, rowMapper); | ||
352 | + }finally { | ||
353 | + this.clearShardingInfo(); | ||
354 | + } | ||
355 | + } | ||
356 | + | ||
357 | + @Override | ||
358 | + public <E> List<E> query(String sql, Object[] args, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
359 | + throws DataAccessException { | ||
360 | + try { | ||
361 | + this.loadShardingInfo(broadcastTableNames); | ||
362 | + return this.jdbcTemplate.query(sql, args, rowMapper); | ||
363 | + }finally { | ||
364 | + this.clearShardingInfo(); | ||
365 | + } | ||
366 | + } | ||
367 | + | ||
368 | + @Override | ||
369 | + public <E> List<E> query(String sql, RowMapper<E> rowMapper, String[] broadcastTableNames, Object... args) | ||
370 | + throws DataAccessException { | ||
371 | + try { | ||
372 | + this.loadShardingInfo(broadcastTableNames); | ||
373 | + return this.jdbcTemplate.query(sql, rowMapper, args); | ||
374 | + }finally { | ||
375 | + this.clearShardingInfo(); | ||
376 | + } | ||
377 | + } | ||
378 | + | ||
379 | + @Override | ||
380 | + public <E> E queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
381 | + throws DataAccessException { | ||
382 | + try { | ||
383 | + this.loadShardingInfo(broadcastTableNames); | ||
384 | + return this.jdbcTemplate.queryForObject(sql, args, argTypes, rowMapper); | ||
385 | + }finally { | ||
386 | + this.clearShardingInfo(); | ||
387 | + } | ||
388 | + } | ||
389 | + | ||
390 | + @Override | ||
391 | + public <E> E queryForObject(String sql, Object[] args, RowMapper<E> rowMapper, String[] broadcastTableNames) | ||
392 | + throws DataAccessException { | ||
393 | + try { | ||
394 | + this.loadShardingInfo(broadcastTableNames); | ||
395 | + return this.jdbcTemplate.queryForObject(sql, args, rowMapper); | ||
396 | + }finally { | ||
397 | + this.clearShardingInfo(); | ||
398 | + } | ||
399 | + } | ||
400 | + | ||
401 | + @Override | ||
402 | + public <E> E queryForObject(String sql, RowMapper<E> rowMapper, String[] broadcastTableNames, Object... args) | ||
403 | + throws DataAccessException { | ||
404 | + try { | ||
405 | + this.loadShardingInfo(broadcastTableNames); | ||
406 | + return this.jdbcTemplate.queryForObject(sql, rowMapper, args); | ||
407 | + }finally { | ||
408 | + this.clearShardingInfo(); | ||
409 | + } | ||
410 | + } | ||
411 | + | ||
412 | + @Override | ||
413 | + public <E> E queryForObject(String sql, Object[] args, int[] argTypes, Class<E> requiredType, String[] broadcastTableNames) | ||
414 | + throws DataAccessException { | ||
415 | + try { | ||
416 | + this.loadShardingInfo(broadcastTableNames); | ||
417 | + return this.jdbcTemplate.queryForObject(sql, args, argTypes, requiredType); | ||
418 | + }finally { | ||
419 | + this.clearShardingInfo(); | ||
420 | + } | ||
421 | + } | ||
422 | + | ||
423 | + @Override | ||
424 | + public <E> E queryForObject(String sql, Object[] args, Class<E> requiredType, String[] broadcastTableNames) | ||
425 | + throws DataAccessException { | ||
426 | + try { | ||
427 | + this.loadShardingInfo(broadcastTableNames); | ||
428 | + return this.jdbcTemplate.queryForObject(sql, args, requiredType); | ||
429 | + }finally { | ||
430 | + this.clearShardingInfo(); | ||
431 | + } | ||
432 | + } | ||
433 | + | ||
434 | + @Override | ||
435 | + public <E> E queryForObject(String sql, Class<E> requiredType, String[] broadcastTableNames, Object... args) | ||
436 | + throws DataAccessException { | ||
437 | + try { | ||
438 | + this.loadShardingInfo(broadcastTableNames); | ||
439 | + return this.jdbcTemplate.queryForObject(sql, requiredType, args); | ||
440 | + }finally { | ||
441 | + this.clearShardingInfo(); | ||
442 | + } | ||
443 | + } | ||
444 | + | ||
445 | + @Override | ||
446 | + public Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) | ||
447 | + throws DataAccessException { | ||
448 | + try { | ||
449 | + this.loadShardingInfo(broadcastTableNames); | ||
450 | + return this.jdbcTemplate.queryForMap(sql, args, argTypes); | ||
451 | + }finally { | ||
452 | + this.clearShardingInfo(); | ||
453 | + } | ||
454 | + } | ||
455 | + | ||
456 | + @Override | ||
457 | + public Map<String, Object> queryForMap(String sql, String[] broadcastTableNames, Object... args) throws DataAccessException { | ||
458 | + try { | ||
459 | + this.loadShardingInfo(broadcastTableNames); | ||
460 | + return this.jdbcTemplate.queryForMap(sql, args); | ||
461 | + }finally { | ||
462 | + this.clearShardingInfo(); | ||
463 | + } | ||
464 | + } | ||
465 | + | ||
466 | + @Override | ||
467 | + public <E> List<E> queryForList(String sql, Object[] args, int[] argTypes, Class<E> elementType, String[] broadcastTableNames) | ||
468 | + throws DataAccessException { | ||
469 | + try { | ||
470 | + this.loadShardingInfo(broadcastTableNames); | ||
471 | + return this.jdbcTemplate.queryForList(sql, args, argTypes, elementType); | ||
472 | + }finally { | ||
473 | + this.clearShardingInfo(); | ||
474 | + } | ||
475 | + } | ||
476 | + | ||
477 | + @Override | ||
478 | + public <E> List<E> queryForList(String sql, Object[] args, Class<E> elementType, String[] broadcastTableNames) | ||
479 | + throws DataAccessException { | ||
480 | + try { | ||
481 | + this.loadShardingInfo(broadcastTableNames); | ||
482 | + return this.jdbcTemplate.queryForList(sql, args, elementType); | ||
483 | + }finally { | ||
484 | + this.clearShardingInfo(); | ||
485 | + } | ||
486 | + } | ||
487 | + | ||
488 | + @Override | ||
489 | + public <E> List<E> queryForList(String sql, Class<E> elementType, String[] broadcastTableNames, Object... args) | ||
490 | + throws DataAccessException { | ||
491 | + try { | ||
492 | + this.loadShardingInfo(broadcastTableNames); | ||
493 | + return this.jdbcTemplate.queryForList(sql, elementType, args); | ||
494 | + }finally { | ||
495 | + this.clearShardingInfo(); | ||
496 | + } | ||
497 | + } | ||
498 | + | ||
499 | + @Override | ||
500 | + public List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) | ||
501 | + throws DataAccessException { | ||
502 | + try { | ||
503 | + this.loadShardingInfo(broadcastTableNames); | ||
504 | + return this.jdbcTemplate.queryForList(sql, args, argTypes); | ||
505 | + }finally { | ||
506 | + this.clearShardingInfo(); | ||
507 | + } | ||
508 | + } | ||
509 | + | ||
510 | + @Override | ||
511 | + public List<Map<String, Object>> queryForList(String sql, String[] broadcastTableNames, Object... args) | ||
512 | + throws DataAccessException { | ||
513 | + try { | ||
514 | + this.loadShardingInfo(broadcastTableNames); | ||
515 | + return this.jdbcTemplate.queryForList(sql, args); | ||
516 | + }finally { | ||
517 | + this.clearShardingInfo(); | ||
518 | + } | ||
519 | + } | ||
520 | + | ||
521 | + @Override | ||
522 | + public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) | ||
523 | + throws DataAccessException { | ||
524 | + try { | ||
525 | + this.loadShardingInfo(broadcastTableNames); | ||
526 | + return this.jdbcTemplate.queryForRowSet(sql, args, argTypes); | ||
527 | + }finally { | ||
528 | + this.clearShardingInfo(); | ||
529 | + } | ||
530 | + } | ||
531 | + | ||
532 | + @Override | ||
533 | + public SqlRowSet queryForRowSet(String sql, String[] broadcastTableNames, Object... args) throws DataAccessException { | ||
534 | + try { | ||
535 | + this.loadShardingInfo(broadcastTableNames); | ||
536 | + return this.jdbcTemplate.queryForRowSet(sql, args); | ||
537 | + }finally { | ||
538 | + this.clearShardingInfo(); | ||
539 | + } | ||
540 | + } | ||
541 | + | ||
542 | + @Override | ||
543 | + public int update(PreparedStatementCreator psc, String[] broadcastTableNames) throws DataAccessException { | ||
544 | + try { | ||
545 | + this.loadShardingInfo(broadcastTableNames); | ||
546 | + return this.jdbcTemplate.update(psc); | ||
547 | + }finally { | ||
548 | + this.clearShardingInfo(); | ||
549 | + } | ||
550 | + } | ||
551 | + | ||
552 | + @Override | ||
553 | + public int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder, String[] broadcastTableNames) | ||
554 | + throws DataAccessException { | ||
555 | + try { | ||
556 | + this.loadShardingInfo(broadcastTableNames); | ||
557 | + return this.jdbcTemplate.update(psc, generatedKeyHolder); | ||
558 | + }finally { | ||
559 | + this.clearShardingInfo(); | ||
560 | + } | ||
561 | + } | ||
562 | + | ||
563 | + @Override | ||
564 | + public int update(String sql, PreparedStatementSetter pss, String[] broadcastTableNames) throws DataAccessException { | ||
565 | + try { | ||
566 | + this.loadShardingInfo(broadcastTableNames); | ||
567 | + return this.jdbcTemplate.update(sql, pss); | ||
568 | + }finally { | ||
569 | + this.clearShardingInfo(); | ||
570 | + } | ||
571 | + } | ||
572 | + | ||
573 | + @Override | ||
574 | + public int update(String sql, Object[] args, int[] argTypes, String[] broadcastTableNames) throws DataAccessException { | ||
575 | + try { | ||
576 | + this.loadShardingInfo(broadcastTableNames); | ||
577 | + return this.jdbcTemplate.update(sql, args, argTypes); | ||
578 | + }finally { | ||
579 | + this.clearShardingInfo(); | ||
580 | + } | ||
581 | + } | ||
582 | + | ||
583 | + @Override | ||
584 | + public int update(String sql, String[] broadcastTableNames, Object... args) throws DataAccessException { | ||
585 | + try { | ||
586 | + this.loadShardingInfo(broadcastTableNames); | ||
587 | + return this.jdbcTemplate.update(sql, args); | ||
588 | + }finally { | ||
589 | + this.clearShardingInfo(); | ||
590 | + } | ||
591 | + } | ||
592 | + | ||
593 | + @Override | ||
594 | + public int[] batchUpdate(String sql, BatchPreparedStatementSetter pss, String[] broadcastTableNames) throws DataAccessException { | ||
595 | + try { | ||
596 | + this.loadShardingInfo(broadcastTableNames); | ||
597 | + return this.jdbcTemplate.batchUpdate(sql, pss); | ||
598 | + }finally { | ||
599 | + this.clearShardingInfo(); | ||
600 | + } | ||
601 | + } | ||
602 | + | ||
603 | + @Override | ||
604 | + public int[] batchUpdate(String sql, List<Object[]> batchArgs, String[] broadcastTableNames) throws DataAccessException { | ||
605 | + try { | ||
606 | + this.loadShardingInfo(broadcastTableNames); | ||
607 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs); | ||
608 | + }finally { | ||
609 | + this.clearShardingInfo(); | ||
610 | + } | ||
611 | + } | ||
612 | + | ||
613 | + @Override | ||
614 | + public int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes, String[] broadcastTableNames) | ||
615 | + throws DataAccessException { | ||
616 | + try { | ||
617 | + this.loadShardingInfo(broadcastTableNames); | ||
618 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs); | ||
619 | + }finally { | ||
620 | + this.clearShardingInfo(); | ||
621 | + } | ||
622 | + } | ||
623 | + | ||
624 | + @Override | ||
625 | + public <E> int[][] batchUpdate(String sql, Collection<E> batchArgs, int batchSize, | ||
626 | + ParameterizedPreparedStatementSetter<E> pss, String[] broadcastTableNames) throws DataAccessException { | ||
627 | + try { | ||
628 | + this.loadShardingInfo(broadcastTableNames); | ||
629 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs, batchSize, pss); | ||
630 | + }finally { | ||
631 | + this.clearShardingInfo(); | ||
632 | + } | ||
633 | + } | ||
634 | + | ||
635 | + @Override | ||
636 | + public <E> E execute(CallableStatementCreator csc, CallableStatementCallback<E> action, String[] broadcastTableNames) | ||
637 | + throws DataAccessException { | ||
638 | + try { | ||
639 | + this.loadShardingInfo(broadcastTableNames); | ||
640 | + return this.jdbcTemplate.execute(csc, action); | ||
641 | + }finally { | ||
642 | + this.clearShardingInfo(); | ||
643 | + } | ||
644 | + } | ||
645 | + | ||
646 | + @Override | ||
647 | + public <E> E execute(String callString, CallableStatementCallback<E> action, String[] broadcastTableNames) | ||
648 | + throws DataAccessException { | ||
649 | + try { | ||
650 | + this.loadShardingInfo(broadcastTableNames); | ||
651 | + return this.jdbcTemplate.execute(callString, action); | ||
652 | + }finally { | ||
653 | + this.clearShardingInfo(); | ||
654 | + } | ||
655 | + } | ||
656 | + | ||
657 | + @Override | ||
658 | + public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters, String[] broadcastTableNames) | ||
659 | + throws DataAccessException { | ||
660 | + try { | ||
661 | + this.loadShardingInfo(broadcastTableNames); | ||
662 | + return this.jdbcTemplate.call(csc, declaredParameters); | ||
663 | + }finally { | ||
664 | + this.clearShardingInfo(); | ||
665 | + } | ||
666 | + } | ||
667 | +} |
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateWrapperTenant.java
@@ -29,7 +29,17 @@ import org.springframework.jdbc.support.rowset.SqlRowSet; | @@ -29,7 +29,17 @@ import org.springframework.jdbc.support.rowset.SqlRowSet; | ||
29 | import org.springframework.lang.Nullable; | 29 | import org.springframework.lang.Nullable; |
30 | 30 | ||
31 | public interface JdbcTemplateWrapperTenant { | 31 | public interface JdbcTemplateWrapperTenant { |
32 | - | 32 | + /** |
33 | + * 加载分片信息 | ||
34 | + * @param tenantId | ||
35 | + */ | ||
36 | + public void loadShardingInfo(Long tenantId); | ||
37 | + | ||
38 | + /** | ||
39 | + * 清空分片信息 | ||
40 | + */ | ||
41 | + public void clearShardingInfo(); | ||
42 | + | ||
33 | //------------------------------------------------------------------------- | 43 | //------------------------------------------------------------------------- |
34 | // Methods dealing with a plain java.sql.Connection | 44 | // Methods dealing with a plain java.sql.Connection |
35 | //------------------------------------------------------------------------- | 45 | //------------------------------------------------------------------------- |
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateWrapperTenantImpl.java
@@ -4,8 +4,6 @@ import java.util.Collection; | @@ -4,8 +4,6 @@ import java.util.Collection; | ||
4 | import java.util.List; | 4 | import java.util.List; |
5 | import java.util.Map; | 5 | import java.util.Map; |
6 | 6 | ||
7 | -import javax.annotation.Resource; | ||
8 | - | ||
9 | import org.apache.shardingsphere.api.hint.HintManager; | 7 | import org.apache.shardingsphere.api.hint.HintManager; |
10 | import org.springframework.dao.DataAccessException; | 8 | import org.springframework.dao.DataAccessException; |
11 | import org.springframework.jdbc.core.BatchPreparedStatementSetter; | 9 | import org.springframework.jdbc.core.BatchPreparedStatementSetter; |
@@ -29,13 +27,17 @@ import com.taover.repository.shardingsphere.ShardingInfoEntity; | @@ -29,13 +27,17 @@ import com.taover.repository.shardingsphere.ShardingInfoEntity; | ||
29 | import com.taover.repository.shardingsphere.ShardingSphereService; | 27 | import com.taover.repository.shardingsphere.ShardingSphereService; |
30 | 28 | ||
31 | public class JdbcTemplateWrapperTenantImpl implements JdbcTemplateWrapperTenant { | 29 | public class JdbcTemplateWrapperTenantImpl implements JdbcTemplateWrapperTenant { |
32 | - @Resource | ||
33 | private JdbcTemplate jdbcTemplate; | 30 | private JdbcTemplate jdbcTemplate; |
34 | - @Resource | ||
35 | private ShardingSphereService shardingSphereService; | 31 | private ShardingSphereService shardingSphereService; |
36 | 32 | ||
37 | - private void loadShardingInfo(Long tenantId) { | ||
38 | - List<ShardingInfoEntity> shardingInfo = this.shardingSphereService.getShardingInfoMapByTenantId(tenantId); | 33 | + public JdbcTemplateWrapperTenantImpl(JdbcTemplate jdbcTemplate, ShardingSphereService shardingSphereService) { |
34 | + this.jdbcTemplate = jdbcTemplate; | ||
35 | + this.shardingSphereService = shardingSphereService; | ||
36 | + } | ||
37 | + | ||
38 | + @Override | ||
39 | + public void loadShardingInfo(Long tenantId) { | ||
40 | + List<ShardingInfoEntity> shardingInfo = this.shardingSphereService.getShardingInfoByTenantId(tenantId); | ||
39 | if(shardingInfo == null || shardingInfo.isEmpty()) { | 41 | if(shardingInfo == null || shardingInfo.isEmpty()) { |
40 | return; | 42 | return; |
41 | } | 43 | } |
@@ -47,7 +49,8 @@ public class JdbcTemplateWrapperTenantImpl implements JdbcTemplateWrapperTenant | @@ -47,7 +49,8 @@ public class JdbcTemplateWrapperTenantImpl implements JdbcTemplateWrapperTenant | ||
47 | } | 49 | } |
48 | } | 50 | } |
49 | 51 | ||
50 | - private void clearShardingInfo() { | 52 | + @Override |
53 | + public void clearShardingInfo() { | ||
51 | HintManager.clear(); | 54 | HintManager.clear(); |
52 | } | 55 | } |
53 | 56 |
src/main/java/com/taover/repository/shardingsphere/ShardingSphereService.java
@@ -14,6 +14,7 @@ import com.taover.repository.autoconfigure.ShardingSphereKeyGeneratorConfigurati | @@ -14,6 +14,7 @@ import com.taover.repository.autoconfigure.ShardingSphereKeyGeneratorConfigurati | ||
14 | @Service | 14 | @Service |
15 | public class ShardingSphereService { | 15 | public class ShardingSphereService { |
16 | private Map<Long, List<ShardingInfoEntity>> CACHED_TABLE_SUFFIX_BY_TENANT = null; | 16 | private Map<Long, List<ShardingInfoEntity>> CACHED_TABLE_SUFFIX_BY_TENANT = null; |
17 | + private Map<String, List<ShardingInfoEntity>> CACHED_TABLE_SUFFIX_BY_TABLE_NAME = null; | ||
17 | private Map<String, ShardingKeyGeneratorExt> GENERATOR_HOLDER = new HashMap<String, ShardingKeyGeneratorExt>(); | 18 | private Map<String, ShardingKeyGeneratorExt> GENERATOR_HOLDER = new HashMap<String, ShardingKeyGeneratorExt>(); |
18 | 19 | ||
19 | @Resource | 20 | @Resource |
@@ -31,25 +32,31 @@ public class ShardingSphereService { | @@ -31,25 +32,31 @@ public class ShardingSphereService { | ||
31 | return GENERATOR_HOLDER.get(tableName).generateKeyList(number); | 32 | return GENERATOR_HOLDER.get(tableName).generateKeyList(number); |
32 | } | 33 | } |
33 | 34 | ||
34 | - public List<ShardingInfoEntity> getShardingInfoMapByTenantId(Long tenantId) { | 35 | + public List<ShardingInfoEntity> getShardingInfoByTenantId(Long tenantId) { |
35 | if(CACHED_TABLE_SUFFIX_BY_TENANT == null) { | 36 | if(CACHED_TABLE_SUFFIX_BY_TENANT == null) { |
36 | - loadCacheTableShardingInfoByTenantId(); | 37 | + loadCacheTableShardingInfo(); |
37 | } | 38 | } |
38 | return CACHED_TABLE_SUFFIX_BY_TENANT.get(tenantId); | 39 | return CACHED_TABLE_SUFFIX_BY_TENANT.get(tenantId); |
39 | } | 40 | } |
40 | 41 | ||
41 | - private synchronized void loadCacheTableShardingInfoByTenantId() { | ||
42 | - if(CACHED_TABLE_SUFFIX_BY_TENANT != null) { | 42 | + private synchronized void loadCacheTableShardingInfo() { |
43 | + if(CACHED_TABLE_SUFFIX_BY_TENANT != null && CACHED_TABLE_SUFFIX_BY_TABLE_NAME != null) { | ||
43 | return; | 44 | return; |
44 | - } | 45 | + } |
45 | List<ShardingInfoEntity> dataList = this.shardingInfoRepository.findListBySql("1=1"); | 46 | List<ShardingInfoEntity> dataList = this.shardingInfoRepository.findListBySql("1=1"); |
46 | Map<Long, List<ShardingInfoEntity>> tempData = new HashMap<Long, List<ShardingInfoEntity>>(); | 47 | Map<Long, List<ShardingInfoEntity>> tempData = new HashMap<Long, List<ShardingInfoEntity>>(); |
48 | + Map<String, List<ShardingInfoEntity>> tempDataTableName = new HashMap<String, List<ShardingInfoEntity>>(); | ||
47 | for(ShardingInfoEntity item: dataList) { | 49 | for(ShardingInfoEntity item: dataList) { |
48 | List<ShardingInfoEntity> tempItem = tempData.getOrDefault(item.getTenantId(), new ArrayList<ShardingInfoEntity>()); | 50 | List<ShardingInfoEntity> tempItem = tempData.getOrDefault(item.getTenantId(), new ArrayList<ShardingInfoEntity>()); |
49 | tempItem.add(item); | 51 | tempItem.add(item); |
50 | tempData.put(item.getTenantId(), tempItem); | 52 | tempData.put(item.getTenantId(), tempItem); |
53 | + | ||
54 | + List<ShardingInfoEntity> tempItemTableName = tempDataTableName.getOrDefault(item.getTableName(), new ArrayList<ShardingInfoEntity>()); | ||
55 | + tempItemTableName.add(item); | ||
56 | + tempDataTableName.put(item.getTableName(), tempItemTableName); | ||
51 | } | 57 | } |
52 | CACHED_TABLE_SUFFIX_BY_TENANT = tempData; | 58 | CACHED_TABLE_SUFFIX_BY_TENANT = tempData; |
59 | + CACHED_TABLE_SUFFIX_BY_TABLE_NAME = tempDataTableName; | ||
53 | } | 60 | } |
54 | 61 | ||
55 | private synchronized void loadShardingKeyGenerator(String tableName) { | 62 | private synchronized void loadShardingKeyGenerator(String tableName) { |
@@ -60,4 +67,21 @@ public class ShardingSphereService { | @@ -60,4 +67,21 @@ public class ShardingSphereService { | ||
60 | generator.loalConfig(config); | 67 | generator.loalConfig(config); |
61 | GENERATOR_HOLDER.put(tableName, generator); | 68 | GENERATOR_HOLDER.put(tableName, generator); |
62 | } | 69 | } |
70 | + | ||
71 | + public List<ShardingInfoEntity> getShardingInfoByTableNames(String[] broadcastTableNames) { | ||
72 | + if(broadcastTableNames == null || broadcastTableNames.length == 0) { | ||
73 | + return null; | ||
74 | + } | ||
75 | + if(CACHED_TABLE_SUFFIX_BY_TABLE_NAME == null) { | ||
76 | + loadCacheTableShardingInfo(); | ||
77 | + } | ||
78 | + List<ShardingInfoEntity> dataList = new ArrayList<ShardingInfoEntity>(); | ||
79 | + for(String item: broadcastTableNames) { | ||
80 | + List<ShardingInfoEntity> tempData = CACHED_TABLE_SUFFIX_BY_TABLE_NAME.get(item); | ||
81 | + if(tempData != null && !tempData.isEmpty()) { | ||
82 | + dataList.addAll(tempData); | ||
83 | + } | ||
84 | + } | ||
85 | + return dataList; | ||
86 | + } | ||
63 | } | 87 | } |
src/test/java/com/taover/repository/test/TestAutoconfigure.java
@@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; | @@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
5 | import org.springframework.context.ConfigurableApplicationContext; | 5 | import org.springframework.context.ConfigurableApplicationContext; |
6 | import org.springframework.scheduling.annotation.EnableScheduling; | 6 | import org.springframework.scheduling.annotation.EnableScheduling; |
7 | 7 | ||
8 | +import com.taover.repository.jdbctemplate.JdbcTemplateBroadcast; | ||
8 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | 9 | import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; |
9 | 10 | ||
10 | @SpringBootApplication | 11 | @SpringBootApplication |
@@ -12,10 +13,14 @@ import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | @@ -12,10 +13,14 @@ import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | ||
12 | public class TestAutoconfigure { | 13 | public class TestAutoconfigure { |
13 | public static void main(String args[]) { | 14 | public static void main(String args[]) { |
14 | ConfigurableApplicationContext context = SpringApplication.run(TestAutoconfigure.class, args); | 15 | ConfigurableApplicationContext context = SpringApplication.run(TestAutoconfigure.class, args); |
15 | - JdbcTemplateWrapperTenant jdbcTemplate = context.getBean(JdbcTemplateWrapperTenant.class); | ||
16 | - System.out.println(jdbcTemplate.queryForObject("select id from wxorder_order limit 1", Long.class, 1L)); | ||
17 | - System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 1L)); | ||
18 | - System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 2L)); | ||
19 | - System.out.println(jdbcTemplate.queryForList("select * from wxorder_order_express limit 1", 1L)); | 16 | + |
17 | + JdbcTemplateBroadcast jdbcTemplateB = context.getBean(JdbcTemplateBroadcast.class); | ||
18 | + System.out.println(jdbcTemplateB.queryForObject("select id from wxorder_order order by id desc limit 5 ", String.class, new String[]{"wxorder_order"})); | ||
19 | + | ||
20 | +// JdbcTemplateWrapperTenant jdbcTemplate = context.getBean(JdbcTemplateWrapperTenant.class); | ||
21 | +// System.out.println(jdbcTemplate.queryForObject("select id from wxorder_order limit 1", Long.class, 1L)); | ||
22 | +// System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 1L)); | ||
23 | +// System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 2L)); | ||
24 | +// System.out.println(jdbcTemplate.queryForList("select * from wxorder_order_express limit 1", 1L)); | ||
20 | } | 25 | } |
21 | } | 26 | } |
src/test/resources/application.properties
@@ -13,12 +13,9 @@ spring.gson.serialize-nulls=true | @@ -13,12 +13,9 @@ spring.gson.serialize-nulls=true | ||
13 | spring.mvc.dispatch-options-request=true | 13 | spring.mvc.dispatch-options-request=true |
14 | 14 | ||
15 | # shardingspere | 15 | # shardingspere |
16 | -spring.shardingsphere.datasource.names=ds0 | 16 | +spring.shardingsphere.datasource.names=ds0,ds1 |
17 | spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource | 17 | spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource |
18 | spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver | 18 | spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver |
19 | -#spring.shardingsphere.datasource.ds_0.url=jdbc:mysql://121.42.142.102:3306/bzyun_wxorder?characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL | ||
20 | -#spring.shardingsphere.datasource.ds_0.username=dev | ||
21 | -#spring.shardingsphere.datasource.ds_0.password=taover02 | ||
22 | spring.shardingsphere.datasource.ds0.url=jdbc:mysql://rdsifmezqifmezqo.mysql.rds.aliyuncs.com:3306/bzyun_wxorder?characterEncoding=UTF-8 | 19 | spring.shardingsphere.datasource.ds0.url=jdbc:mysql://rdsifmezqifmezqo.mysql.rds.aliyuncs.com:3306/bzyun_wxorder?characterEncoding=UTF-8 |
23 | spring.shardingsphere.datasource.ds0.username=tylife | 20 | spring.shardingsphere.datasource.ds0.username=tylife |
24 | spring.shardingsphere.datasource.ds0.password=lexi365 | 21 | spring.shardingsphere.datasource.ds0.password=lexi365 |
@@ -27,7 +24,17 @@ spring.shardingsphere.datasource.ds0.max-active=20 | @@ -27,7 +24,17 @@ spring.shardingsphere.datasource.ds0.max-active=20 | ||
27 | spring.shardingsphere.datasource.ds0.min-idle=5 | 24 | spring.shardingsphere.datasource.ds0.min-idle=5 |
28 | spring.shardingsphere.datasource.ds0.max-wait=60000 | 25 | spring.shardingsphere.datasource.ds0.max-wait=60000 |
29 | 26 | ||
30 | -spring.shardingsphere.sharding.tables.wxorder_order.actual-data-nodes=ds0.wxorder_order | 27 | +spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource |
28 | +spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver | ||
29 | +spring.shardingsphere.datasource.ds1.url=jdbc:mysql://121.42.142.102:3306/bzyun_wxorder?characterEncoding=UTF-8 | ||
30 | +spring.shardingsphere.datasource.ds1.username=dev | ||
31 | +spring.shardingsphere.datasource.ds1.password=taover02 | ||
32 | +spring.shardingsphere.datasource.ds1.initial-size=10 | ||
33 | +spring.shardingsphere.datasource.ds1.max-active=20 | ||
34 | +spring.shardingsphere.datasource.ds1.min-idle=5 | ||
35 | +spring.shardingsphere.datasource.ds1.max-wait=60000 | ||
36 | + | ||
37 | +spring.shardingsphere.sharding.tables.wxorder_order.actual-data-nodes=ds0.wxorder_order,ds1.wxorder_order | ||
31 | spring.shardingsphere.sharding.tables.wxorder_order.database-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingDatabaseAlgorithmHint | 38 | spring.shardingsphere.sharding.tables.wxorder_order.database-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingDatabaseAlgorithmHint |
32 | spring.shardingsphere.sharding.tables.wxorder_order.table-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingTableAlgorithmHint | 39 | spring.shardingsphere.sharding.tables.wxorder_order.table-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingTableAlgorithmHint |
33 | spring.shardingsphere.sharding.tables.wxorder_order.key-generator.column=id | 40 | spring.shardingsphere.sharding.tables.wxorder_order.key-generator.column=id |