Commit f0611848f6313a6020b3d6b02ef2929585c1d6fa
1 parent
7a32a07a
Exists in
master
and in
2 other branches
extend to sharding sphere
Showing
30 changed files
with
2924 additions
and
718 deletions
Show diff stats
build.gradle
... | ... | @@ -5,7 +5,6 @@ |
5 | 5 | * For more details take a look at the Java Libraries chapter in the Gradle |
6 | 6 | * user guide available at https://docs.gradle.org/4.5.1/userguide/java_library_plugin.html |
7 | 7 | */ |
8 | - | |
9 | 8 | plugins { |
10 | 9 | // Apply the java-library plugin to add support for Java Library |
11 | 10 | id 'java' |
... | ... | @@ -19,10 +18,12 @@ group = 'com.taover.repository' |
19 | 18 | mainClassName = 'com.taover.repository.UtilsString' |
20 | 19 | |
21 | 20 | dependencies { |
21 | + compile("org.springframework.boot:spring-boot-starter:2.0.5.RELEASE") | |
22 | 22 | compile("org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final") |
23 | 23 | compile('org.springframework:spring-jdbc:5.1.9.RELEASE') |
24 | 24 | compile('mysql:mysql-connector-java:5.1.47') |
25 | 25 | compile('com.alibaba:druid:1.2.4') |
26 | + compile("org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1") | |
26 | 27 | } |
27 | 28 | |
28 | 29 | repositories { |
... | ... | @@ -56,7 +57,7 @@ uploadArchives { |
56 | 57 | authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD) |
57 | 58 | } |
58 | 59 | pom.project { |
59 | - version '2.1.38' | |
60 | + version '2.1.44' | |
60 | 61 | artifactId ARTIFACT_Id |
61 | 62 | groupId GROUP_ID |
62 | 63 | packaging TYPE | ... | ... |
gradle.properties
src/main/java/com/taover/repository/CustomJdbcTemplate.java
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenant.java
... | ... | @@ -16,12 +16,13 @@ import javax.persistence.Id; |
16 | 16 | import javax.persistence.Table; |
17 | 17 | |
18 | 18 | import org.springframework.dao.DataAccessException; |
19 | -import org.springframework.jdbc.core.JdbcTemplate; | |
20 | 19 | |
21 | 20 | import com.taover.repository.exception.MultiRowException; |
22 | 21 | import com.taover.repository.exception.NoContainTenantException; |
23 | 22 | import com.taover.repository.exception.NotFoundException; |
24 | 23 | import com.taover.repository.exception.ObjectReflectException; |
24 | +import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | |
25 | +import com.taover.repository.util.UtilsSql; | |
25 | 26 | |
26 | 27 | /** |
27 | 28 | * |
... | ... | @@ -30,52 +31,47 @@ import com.taover.repository.exception.ObjectReflectException; |
30 | 31 | * @param <T> |
31 | 32 | * @param <ID> |
32 | 33 | */ |
33 | -public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> implements JdbcRepositoryWrapperTenant<T, ID>{ | |
34 | +public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> implements CustomJdbcTemplateWrapperTenantInterface<T, ID>{ | |
34 | 35 | @Resource |
35 | - private JdbcTemplate jdbcTemplateWrite; | |
36 | + private JdbcTemplateWrapperTenant _jdbcTemplateWrapperTenant; | |
36 | 37 | |
37 | - private Map<String, String> beanToTableField; | |
38 | - private Map<String, String> tableToBeanField; | |
39 | - private String tableFieldNameListGapWithComma; | |
40 | - private String idTableFieldName; | |
41 | - private String idBeanFieldName; | |
42 | - private String dbName; | |
43 | - private String tableName; | |
44 | - private Class<T> tClassInfo; | |
45 | - private CustomJdbcTemplateRowMapper customJdbcTemplateRowMapper; | |
38 | + private Map<String, String> _beanToTableField; | |
39 | + private Map<String, String> _tableToBeanField; | |
40 | + private String _tableFieldNameListGapWithComma; | |
41 | + private String _idTableFieldName; | |
42 | + private String _dbName; | |
43 | + private String _tableName; | |
44 | + private Class<T> _tClassInfo; | |
45 | + private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; | |
46 | 46 | |
47 | - public CustomJdbcTemplateRowMapper getCustomJdbcTemplateRowMapper(){ | |
48 | - return this.customJdbcTemplateRowMapper; | |
49 | - } | |
50 | - | |
51 | - public CustomJdbcTemplateWrapperTenant(JdbcTemplate jdbcTemplateWrite) throws Exception{ | |
52 | - this(); | |
53 | - this.jdbcTemplateWrite = jdbcTemplateWrite; | |
54 | - } | |
47 | + public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ | |
48 | + return this._customJdbcTemplateRowMapper; | |
49 | + } | |
55 | 50 | |
51 | + @SuppressWarnings("unchecked") | |
56 | 52 | public CustomJdbcTemplateWrapperTenant() throws Exception{ |
57 | 53 | //获取泛型类Class |
58 | - this.tClassInfo = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | |
54 | + this._tClassInfo = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | |
59 | 55 | |
60 | 56 | //检查实体声明 |
61 | - Table annoTable = (Table) tClassInfo.getAnnotation(Table.class); | |
57 | + Table annoTable = (Table) _tClassInfo.getAnnotation(Table.class); | |
62 | 58 | if(annoTable == null){ |
63 | - throw new Exception("DAO层初始化失败,失败原因:"+tClassInfo.getName()+"实体类,没有@Table注解指定表名"); | |
59 | + throw new Exception("DAO层初始化失败,失败原因:"+_tClassInfo.getName()+"实体类,没有@Table注解指定表名"); | |
64 | 60 | } |
65 | - this.tableName = annoTable.name(); | |
61 | + this._tableName = annoTable.name(); | |
66 | 62 | String schema = annoTable.schema(); |
67 | 63 | String catalog = annoTable.catalog(); |
68 | 64 | if(schema != null && !"".equals(schema)){ |
69 | - this.dbName = schema; | |
65 | + this._dbName = schema; | |
70 | 66 | }else if(catalog != null && !"".equals(catalog)){ |
71 | - this.dbName = catalog; | |
67 | + this._dbName = catalog; | |
72 | 68 | } |
73 | 69 | |
74 | 70 | //初始化数据 |
75 | - beanToTableField = new HashMap<String, String>(); | |
76 | - tableToBeanField = new HashMap<String, String>(); | |
77 | - tableFieldNameListGapWithComma = ""; | |
78 | - Field[] declaredFields = tClassInfo.getDeclaredFields(); | |
71 | + _beanToTableField = new HashMap<String, String>(); | |
72 | + _tableToBeanField = new HashMap<String, String>(); | |
73 | + _tableFieldNameListGapWithComma = ""; | |
74 | + Field[] declaredFields = _tClassInfo.getDeclaredFields(); | |
79 | 75 | for(int i=0; i<declaredFields.length; ++i){ |
80 | 76 | Field currField = declaredFields[i]; |
81 | 77 | String fieldName = currField.getName(); |
... | ... | @@ -83,34 +79,33 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
83 | 79 | Column annoColumn = (Column)currField.getAnnotation(Column.class); |
84 | 80 | if(annoId != null){ |
85 | 81 | if(annoColumn == null){ |
86 | - idTableFieldName = this.camelToUnderline(fieldName); | |
82 | + _idTableFieldName = this.camelToUnderline(fieldName); | |
87 | 83 | }else{ |
88 | - idTableFieldName = annoColumn.name(); | |
84 | + _idTableFieldName = annoColumn.name(); | |
89 | 85 | } |
90 | - idBeanFieldName = fieldName; | |
91 | - tableFieldNameListGapWithComma += idTableFieldName+","; | |
92 | - beanToTableField.put(fieldName, idTableFieldName); | |
93 | - tableToBeanField.put(idTableFieldName, fieldName); | |
86 | + _tableFieldNameListGapWithComma += _idTableFieldName+","; | |
87 | + _beanToTableField.put(fieldName, _idTableFieldName); | |
88 | + _tableToBeanField.put(_idTableFieldName, fieldName); | |
94 | 89 | }else{ |
95 | 90 | if(annoColumn != null){ |
96 | 91 | String tableFieldName = annoColumn.name(); |
97 | - tableFieldNameListGapWithComma += tableFieldName+","; | |
98 | - beanToTableField.put(fieldName, tableFieldName); | |
99 | - tableToBeanField.put(tableFieldName, fieldName); | |
92 | + _tableFieldNameListGapWithComma += tableFieldName+","; | |
93 | + _beanToTableField.put(fieldName, tableFieldName); | |
94 | + _tableToBeanField.put(tableFieldName, fieldName); | |
100 | 95 | } |
101 | 96 | } |
102 | 97 | } |
103 | 98 | |
104 | 99 | //检验是否有属性 |
105 | - if(beanToTableField.isEmpty()){ | |
106 | - throw new Exception("DAO层初始化失败,失败原因:"+this.tClassInfo.getName()+"实体类,没有在实体中找到属性信息"); | |
100 | + if(_beanToTableField.isEmpty()){ | |
101 | + throw new Exception("DAO层初始化失败,失败原因:"+this._tClassInfo.getName()+"实体类,没有在实体中找到属性信息"); | |
107 | 102 | } |
108 | 103 | |
109 | 104 | //去除逗号 |
110 | - tableFieldNameListGapWithComma = tableFieldNameListGapWithComma.substring(0, tableFieldNameListGapWithComma.length()-1); | |
105 | + _tableFieldNameListGapWithComma = _tableFieldNameListGapWithComma.substring(0, _tableFieldNameListGapWithComma.length()-1); | |
111 | 106 | |
112 | 107 | //创建rowmapper |
113 | - this.customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper(this.tClassInfo, this.tableToBeanField); | |
108 | + this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); | |
114 | 109 | } |
115 | 110 | |
116 | 111 | /** |
... | ... | @@ -137,42 +132,6 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
137 | 132 | } |
138 | 133 | return result.toString(); |
139 | 134 | } |
140 | - | |
141 | - /** | |
142 | - * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> | |
143 | - * 例如:HELLO_WORLD->HelloWorld | |
144 | - * @param name 转换前的下划线大写方式命名的字符串 | |
145 | - * @return 转换后的驼峰式命名的字符串 | |
146 | - */ | |
147 | - private String underlineToCamel(String name) { | |
148 | - StringBuilder result = new StringBuilder(); | |
149 | - // 快速检查 | |
150 | - if (name == null || name.isEmpty()) { | |
151 | - // 没必要转换 | |
152 | - return ""; | |
153 | - } else if (!name.contains("_")) { | |
154 | - // 不含下划线,仅将首字母小写 | |
155 | - return name.substring(0, 1).toLowerCase() + name.substring(1); | |
156 | - } | |
157 | - // 用下划线将原始字符串分割 | |
158 | - String camels[] = name.split("_"); | |
159 | - for (String camel : camels) { | |
160 | - // 跳过原始字符串中开头、结尾的下换线或双重下划线 | |
161 | - if (camel.isEmpty()) { | |
162 | - continue; | |
163 | - } | |
164 | - // 处理真正的驼峰片段 | |
165 | - if (result.length() == 0) { | |
166 | - // 第一个驼峰片段,全部字母都小写 | |
167 | - result.append(camel.toLowerCase()); | |
168 | - } else { | |
169 | - // 其他的驼峰片段,首字母大写 | |
170 | - result.append(camel.substring(0, 1).toUpperCase()); | |
171 | - result.append(camel.substring(1).toLowerCase()); | |
172 | - } | |
173 | - } | |
174 | - return result.toString(); | |
175 | - } | |
176 | 135 | |
177 | 136 | private void appendWhereCondition(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> condition) { |
178 | 137 | if (condition == null || condition.size() == 0) return; |
... | ... | @@ -236,20 +195,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
236 | 195 | } |
237 | 196 | |
238 | 197 | private String getTableSql(){ |
239 | - return (this.dbName == null || "".equals(this.dbName.trim()))? | |
240 | - ("`"+this.tableName+"`"): | |
241 | - ("`"+this.dbName+"`.`"+this.tableName+"`"); | |
198 | + return (this._dbName == null || "".equals(this._dbName.trim()))? | |
199 | + ("`"+this._tableName+"`"): | |
200 | + ("`"+this._dbName+"`.`"+this._tableName+"`"); | |
242 | 201 | } |
243 | 202 | |
244 | 203 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { |
245 | 204 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
246 | - Iterator<String> beanFieldIter = this.beanToTableField.keySet().iterator(); | |
205 | + Iterator<String> beanFieldIter = this._beanToTableField.keySet().iterator(); | |
247 | 206 | while(beanFieldIter.hasNext()){ |
248 | 207 | String beanFieldName = beanFieldIter.next(); |
249 | - String tableFieldName = this.beanToTableField.get(beanFieldName); | |
208 | + String tableFieldName = this._beanToTableField.get(beanFieldName); | |
250 | 209 | Field beanField = null; |
251 | 210 | try { |
252 | - beanField = this.tClassInfo.getDeclaredField(beanFieldName); | |
211 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); | |
253 | 212 | beanField.setAccessible(true); |
254 | 213 | if(beanField.get(entity) == null) { |
255 | 214 | continue; |
... | ... | @@ -280,7 +239,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
280 | 239 | return 0; |
281 | 240 | } |
282 | 241 | } |
283 | - | |
242 | + | |
284 | 243 | @Override |
285 | 244 | public T findEntityByID(ID id, Long tenantId) throws NotFoundException { |
286 | 245 | return findEntityByID(id, tenantId, false); |
... | ... | @@ -288,16 +247,16 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
288 | 247 | |
289 | 248 | @Override |
290 | 249 | public T findEntityByID(ID id, Long tenantId, boolean isLock) throws NotFoundException { |
291 | - StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
292 | - sql.append(" WHERE "+idTableFieldName+" = ? and tenant_id="+tenantId); | |
250 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
251 | + sql.append(" WHERE "+_idTableFieldName+" = ? and tenant_id="+tenantId); | |
293 | 252 | if (isLock) { |
294 | 253 | sql.append(" FOR UPDATE"); |
295 | 254 | } |
296 | 255 | try { |
297 | - return (T) jdbcTemplateWrite.queryForObject(sql.toString(), this.customJdbcTemplateRowMapper, id); | |
298 | - }catch (DataAccessException e) { | |
299 | - throw new NotFoundException(); | |
300 | - } | |
256 | + return (T) _jdbcTemplateWrapperTenant.queryForObject(sql.toString(), this._customJdbcTemplateRowMapper, tenantId, id); | |
257 | + }catch (DataAccessException e) { | |
258 | + throw new NotFoundException(e); | |
259 | + } | |
301 | 260 | } |
302 | 261 | |
303 | 262 | @Override |
... | ... | @@ -333,20 +292,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
333 | 292 | |
334 | 293 | @Override |
335 | 294 | public List<T> findListByCondition(List<Object[]> condition, String sortCondition, Long tenantId){ |
336 | - StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
295 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
337 | 296 | List<Object> list = new ArrayList<Object>(); |
338 | 297 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
339 | 298 | this.appendWhereCondition(sql, new StringBuffer(), list, condition); |
340 | 299 | if(sortCondition != null && !sortCondition.equals("")){ |
341 | 300 | sql.append(" " + sortCondition + " "); |
342 | 301 | } |
343 | - return (List<T>)jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper, list.toArray()); | |
302 | + return (List<T>)_jdbcTemplateWrapperTenant.query(sql.toString(), this._customJdbcTemplateRowMapper, tenantId, list.toArray()); | |
344 | 303 | } |
345 | 304 | |
346 | 305 | @Override |
347 | 306 | public List<T> findListBySql(String sqlCondition, Long tenantId){ |
348 | - StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE tenant_id="+tenantId + " and " + sqlCondition); | |
349 | - return (List<T>)jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper); | |
307 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE tenant_id="+tenantId + " and " + sqlCondition); | |
308 | + return (List<T>)_jdbcTemplateWrapperTenant.query(sql.toString(), this._customJdbcTemplateRowMapper, tenantId); | |
350 | 309 | } |
351 | 310 | |
352 | 311 | @Override |
... | ... | @@ -356,7 +315,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
356 | 315 | |
357 | 316 | @Override |
358 | 317 | public Map<String, Object> findPageByCondition(List<Object[]> condition, String sortCondition, int page, int pageSize, Long tenantId){ |
359 | - StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
318 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
360 | 319 | StringBuffer pql = new StringBuffer(sql.toString()); |
361 | 320 | StringBuffer sqlCount = new StringBuffer("SELECT COUNT(1) rowCount FROM "+this.getTableSql()); |
362 | 321 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
... | ... | @@ -376,40 +335,39 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
376 | 335 | } |
377 | 336 | |
378 | 337 | String pageSql = sql.toString() + " limit ?, ?"; |
379 | - | |
380 | - Map<String, Object> totalRowsMap = jdbcTemplateWrite.queryForMap(sqlCount.toString(), count_list.toArray()) ; | |
381 | - List<T> resultList = jdbcTemplateWrite.query(pageSql.toString(), this.customJdbcTemplateRowMapper, page_list.toArray()); | |
338 | + Map<String, Object> totalRowsMap = _jdbcTemplateWrapperTenant.queryForMap(sqlCount.toString(), tenantId, count_list.toArray()) ; | |
339 | + List<T> resultList = _jdbcTemplateWrapperTenant.query(pageSql.toString(), this._customJdbcTemplateRowMapper, tenantId, page_list.toArray()); | |
382 | 340 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); |
383 | 341 | } |
384 | 342 | |
385 | 343 | @Override |
386 | 344 | public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize, Long tenantId){ |
387 | - StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE tenant_id=" + tenantId + " and " + sqlCondition ); | |
345 | + StringBuffer sql = new StringBuffer("SELECT "+this._tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE tenant_id=" + tenantId + " and " + sqlCondition ); | |
388 | 346 | StringBuffer sqlCount = new StringBuffer("SELECT count(1) rowCount FROM "+this.getTableSql()+" WHERE tenant_id=" + tenantId + " and " + sqlCondition); |
389 | 347 | sql.append(" limit ?, ?"); |
390 | 348 | List<Object> page_list = new ArrayList<Object>(); |
391 | 349 | page_list.add((page - 1) * pageSize); |
392 | 350 | page_list.add(page * pageSize); |
393 | 351 | |
394 | - Map<String, Object> totalRowsMap = jdbcTemplateWrite.queryForMap(sqlCount.toString()); | |
395 | - List<T> resultList = jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper, page_list.toArray()); | |
352 | + Map<String, Object> totalRowsMap = _jdbcTemplateWrapperTenant.queryForMap(sqlCount.toString(), tenantId); | |
353 | + List<T> resultList = _jdbcTemplateWrapperTenant.query(sql.toString(), this._customJdbcTemplateRowMapper, tenantId, page_list.toArray()); | |
396 | 354 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); |
397 | 355 | } |
398 | 356 | |
399 | 357 | @Override |
400 | - public void addEntity(T entity) { | |
358 | + public void addEntity(T entity, Long tenantId) { | |
401 | 359 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
402 | 360 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); |
403 | 361 | List<Object> paramList = new ArrayList<Object>(); |
404 | 362 | |
405 | - Iterator<String> beanFieldIter = this.beanToTableField.keySet().iterator(); | |
363 | + Iterator<String> beanFieldIter = this._beanToTableField.keySet().iterator(); | |
406 | 364 | while(beanFieldIter.hasNext()){ |
407 | 365 | String beanFieldName = beanFieldIter.next(); |
408 | - String tableFieldName = this.beanToTableField.get(beanFieldName); | |
366 | + String tableFieldName = this._beanToTableField.get(beanFieldName); | |
409 | 367 | Field beanField; |
410 | 368 | Object beanFieldValue = null; |
411 | 369 | try { |
412 | - beanField = this.tClassInfo.getDeclaredField(beanFieldName); | |
370 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); | |
413 | 371 | beanField.setAccessible(true); |
414 | 372 | beanFieldValue = beanField.get(entity); |
415 | 373 | } catch (Exception e) { |
... | ... | @@ -423,19 +381,19 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
423 | 381 | sqlColumnPart.append(" ?,"); |
424 | 382 | paramList.add(beanFieldValue); |
425 | 383 | } |
426 | - | |
384 | + | |
427 | 385 | //执行SQL |
428 | 386 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; |
429 | - jdbcTemplateWrite.update(exeSql, paramList.toArray()); | |
387 | + _jdbcTemplateWrapperTenant.update(exeSql, tenantId, paramList.toArray()); | |
430 | 388 | } |
431 | 389 | |
432 | 390 | @Override |
433 | - public void addEntityList(List<T> entityList) { | |
391 | + public void addEntityList(List<T> entityList, Long tenantId) { | |
434 | 392 | if(entityList == null || entityList.isEmpty()) { |
435 | 393 | return; |
436 | 394 | } |
437 | 395 | //构造SQL语句及Entity Field列表 |
438 | - List<Field> beanFieldList = new ArrayList<Field>(this.beanToTableField.size()); | |
396 | + List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); | |
439 | 397 | StringBuffer exeSql = new StringBuffer(this.constructUpdateSql(entityList.get(0), beanFieldList)); |
440 | 398 | |
441 | 399 | //构造参数信息 |
... | ... | @@ -464,15 +422,15 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
464 | 422 | } |
465 | 423 | exeSql.setCharAt(exeSql.length()-1, ';'); |
466 | 424 | |
467 | - //执行SQL | |
468 | - this.jdbcTemplateWrite.update(exeSql.toString(), args.toArray()); | |
425 | + //执行SQL | |
426 | + this._jdbcTemplateWrapperTenant.update(exeSql.toString(), tenantId, args.toArray()); | |
469 | 427 | } |
470 | 428 | |
471 | 429 | @Override |
472 | 430 | public int deleteEntityByID(ID id, Long tenantId) { |
473 | 431 | StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+" WHERE"); |
474 | - sql.append(" "+this.idTableFieldName+" = ? and tenant_id="+tenantId); | |
475 | - return jdbcTemplateWrite.update(sql.toString(), id); | |
432 | + sql.append(" "+this._idTableFieldName+" = ? and tenant_id="+tenantId); | |
433 | + return _jdbcTemplateWrapperTenant.update(sql.toString(), tenantId, id); | |
476 | 434 | } |
477 | 435 | |
478 | 436 | @Override |
... | ... | @@ -486,7 +444,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
486 | 444 | StringBuffer pql = new StringBuffer(sql.toString()); |
487 | 445 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
488 | 446 | this.appendWhereCondition(sql, pql, list, condition); |
489 | - return jdbcTemplateWrite.update( sql.toString(), list.toArray()); | |
447 | + return _jdbcTemplateWrapperTenant.update( sql.toString(), tenantId, list.toArray()); | |
490 | 448 | } |
491 | 449 | |
492 | 450 | @Override |
... | ... | @@ -494,7 +452,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
494 | 452 | if("".equals(sqlCondition.trim())) { |
495 | 453 | throw new RuntimeException("params[sqlCondition] is empty"); |
496 | 454 | } |
497 | - return jdbcTemplateWrite.update( "DELETE FROM "+this.getTableSql()+" WHERE tenant_id="+tenantId + " and " + sqlCondition); | |
455 | + return _jdbcTemplateWrapperTenant.update( "DELETE FROM "+this.getTableSql()+" WHERE tenant_id="+tenantId + " and " + sqlCondition, tenantId); | |
498 | 456 | } |
499 | 457 | |
500 | 458 | @Override |
... | ... | @@ -503,7 +461,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
503 | 461 | for(ID id: idList) { |
504 | 462 | idSb.append(id); |
505 | 463 | } |
506 | - return this.deleteEntityBySql(this.idTableFieldName + " in ("+idSb.toString().substring(0, idSb.length()-1)+") and tenant_id="+tenantId, tenantId); | |
464 | + return this.deleteEntityBySql(this._idTableFieldName + " in ("+idSb.toString().substring(0, idSb.length()-1)+") and tenant_id="+tenantId, tenantId); | |
507 | 465 | } |
508 | 466 | |
509 | 467 | @Override |
... | ... | @@ -520,10 +478,10 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
520 | 478 | List<Object> list = new ArrayList<Object>(); |
521 | 479 | this.appendSetSql(sql, pql, list, changeList); |
522 | 480 | |
523 | - String where = " WHERE "+this.idTableFieldName+"=? and tenant_id="+tenantId; | |
481 | + String where = " WHERE "+this._idTableFieldName+"=? and tenant_id="+tenantId; | |
524 | 482 | String updateSql = sql.substring(0, sql.length()-1)+where; |
525 | - list.add(id); | |
526 | - return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
483 | + list.add(id); | |
484 | + return _jdbcTemplateWrapperTenant.update(updateSql, tenantId, list.toArray()); | |
527 | 485 | } |
528 | 486 | |
529 | 487 | @Override |
... | ... | @@ -546,7 +504,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
546 | 504 | this.appendWhereCondition(where, pwhere, list, condition); |
547 | 505 | |
548 | 506 | String updateSql = sql.substring(0, sql.length()-1)+where.toString(); |
549 | - return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
507 | + return _jdbcTemplateWrapperTenant.update(updateSql, tenantId, list.toArray()); | |
550 | 508 | } |
551 | 509 | |
552 | 510 | @Override |
... | ... | @@ -564,17 +522,13 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
564 | 522 | this.appendSetSql(sql, pql, list, updateObj); |
565 | 523 | |
566 | 524 | String updateSql = sql.toString().substring(0, sql.length()-1) + " WHERE tenant_id="+tenantId+" and "+sqlCondition; |
567 | - return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
525 | + return _jdbcTemplateWrapperTenant.update(updateSql, tenantId, list.toArray()); | |
568 | 526 | } |
569 | 527 | |
570 | 528 | @Override |
571 | 529 | public Map<String, Object> getPageData(String coreSql, String orderByPartSql, Integer page, Integer pageSize, Long tenantId){ |
572 | - try { | |
573 | - String[] splitedSql = UtilsSql.splitCoreSql(coreSql); | |
574 | - return this.getPageData(splitedSql[0], splitedSql[1], orderByPartSql, page, pageSize, tenantId); | |
575 | - }catch (Exception e) { | |
576 | - return UtilsSql.createPage(page, pageSize, 0, new ArrayList<Object>()); | |
577 | - } | |
530 | + String[] splitedSql = UtilsSql.splitCoreSql(coreSql); | |
531 | + return this.getPageData(splitedSql[0], splitedSql[1], orderByPartSql, page, pageSize, tenantId); | |
578 | 532 | } |
579 | 533 | |
580 | 534 | @Override |
... | ... | @@ -589,10 +543,9 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme |
589 | 543 | |
590 | 544 | //执行查询 |
591 | 545 | List<Map<String, Object>> queryData = new ArrayList<Map<String, Object>>(); |
592 | - Map<String, Object> countData = new HashMap<String, Object>(); | |
593 | - queryData = this.jdbcTemplateWrite.queryForList(querySql); | |
594 | - countData = this.jdbcTemplateWrite.queryForMap(countSql); | |
546 | + Map<String, Object> countData = new HashMap<String, Object>(); | |
547 | + queryData = this._jdbcTemplateWrapperTenant.queryForList(querySql, tenantId); | |
548 | + countData = this._jdbcTemplateWrapperTenant.queryForMap(countSql, tenantId); | |
595 | 549 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(countData.get("rowsCount").toString()), queryData); |
596 | 550 | } |
597 | - | |
598 | 551 | } | ... | ... |
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenantInterface.java
0 → 100644
... | ... | @@ -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 CustomJdbcTemplateWrapperTenantInterface<T, ID extends Serializable> { | |
12 | + | |
13 | + /** | |
14 | + * 按主键查询 | |
15 | + */ | |
16 | + public T findEntityByID(ID id, Long tenantId) throws NotFoundException; | |
17 | + | |
18 | + /** | |
19 | + * 按主键查询 | |
20 | + * isLock 是否锁定, 默认不锁 | |
21 | + * fromWriteDB 是否从写库读写,默认从读库查询 | |
22 | + */ | |
23 | + public T findEntityByID(ID id, Long tenantId, boolean isLock) throws NotFoundException; | |
24 | + | |
25 | + /** | |
26 | + * 根据条件List<Object[]>查询 | |
27 | + * Object[]数组长度是3 | |
28 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
29 | + */ | |
30 | + public T findEntityByCondition(List<Object[]> condition, Long tenantId) throws NotFoundException,MultiRowException,NoContainTenantException; | |
31 | + | |
32 | + /** | |
33 | + * 根据条件sql查询 | |
34 | + * sqlCondition 为where 后面的条件。 | |
35 | + */ | |
36 | + public T findEntityBySql(String sqlCondition, Long tenantId) throws NotFoundException,MultiRowException,NoContainTenantException; | |
37 | + | |
38 | + /** | |
39 | + * 根据条件List<Object[]>查询 | |
40 | + * Object[]数组长度是3 | |
41 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
42 | + */ | |
43 | + public List<T> findListByCondition(List<Object[]> condition, Long tenantId); | |
44 | + | |
45 | + /** | |
46 | + * 根据条件List<Object[]>查询 | |
47 | + * Object[]数组长度是3 | |
48 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
49 | + */ | |
50 | + public List<T> findListByCondition(List<Object[]> condition, String sortCondition, Long tenantId); | |
51 | + | |
52 | + /** | |
53 | + * 根据条件sql查询 | |
54 | + * sqlCondition 为where 后面的条件。 | |
55 | + */ | |
56 | + public List<T> findListBySql(String sqlCondition, Long tenantId); | |
57 | + | |
58 | + /** | |
59 | + * 按条件分页查询 | |
60 | + * Object[]数组长度是3 | |
61 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
62 | + */ | |
63 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize, Long tenantId); | |
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, Long tenantId); | |
73 | + | |
74 | + /** | |
75 | + * 按sql分页查询, sqlCondition为where 后条件sql | |
76 | + */ | |
77 | + public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize, Long tenantId); | |
78 | + | |
79 | + /** | |
80 | + * 添加 | |
81 | + */ | |
82 | + public void addEntity(T entity, Long tenantId); | |
83 | + | |
84 | + /** | |
85 | + * 批量添加 | |
86 | + * @throws Exception | |
87 | + */ | |
88 | + public void addEntityList(List<T> entityList, Long tenantId); | |
89 | + | |
90 | + /** | |
91 | + * 按ID删除 | |
92 | + */ | |
93 | + public int deleteEntityByID(ID id, Long tenantId); | |
94 | + | |
95 | + /** | |
96 | + * 删除按List<Object[]>条件 | |
97 | + * Object[]数组长度是3 | |
98 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
99 | + */ | |
100 | + public int deleteEntityByCondition(List<Object[]> condition, Long tenantId); | |
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, Long tenantId); | |
108 | + | |
109 | + /** | |
110 | + * 根据list对象逐个删除。 | |
111 | + * @throws NoContainTenantException | |
112 | + */ | |
113 | + public int deleteEntityList(List<ID> idList, Long tenantId); | |
114 | + | |
115 | + /** | |
116 | + * 根据ID修改指定的值 | |
117 | + */ | |
118 | + public int updateEntityById(List<Object[]> changeList, ID id, Long tenantId); | |
119 | + | |
120 | + /** | |
121 | + * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | |
122 | + * List<Object[]> condition 修改的条件, 数组长度是3, 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
123 | + */ | |
124 | + public int updateEntityByCondition(List<Object[]> updateObj, List<Object[]> condition, Long tenantId); | |
125 | + | |
126 | + /** | |
127 | + * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | |
128 | + * String sqlCondition 修改的条件。 | |
129 | + */ | |
130 | + public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition, Long tenantId); | |
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, Long tenantId); | |
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, Long tenantId); | |
152 | + | |
153 | +} | ... | ... |
src/main/java/com/taover/repository/JdbcRepositoryWrapperTenant.java
... | ... | @@ -1,152 +0,0 @@ |
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 JdbcRepositoryWrapperTenant<T, ID extends Serializable> { | |
12 | - | |
13 | - /** | |
14 | - * 按主键查询 | |
15 | - */ | |
16 | - public T findEntityByID(ID id, Long tenantId) throws NotFoundException; | |
17 | - | |
18 | - /** | |
19 | - * 按主键查询 | |
20 | - * isLock 是否锁定, 默认不锁 | |
21 | - * fromWriteDB 是否从写库读写,默认从读库查询 | |
22 | - */ | |
23 | - public T findEntityByID(ID id, Long tenantId, boolean isLock) throws NotFoundException; | |
24 | - | |
25 | - /** | |
26 | - * 根据条件List<Object[]>查询 | |
27 | - * Object[]数组长度是3 | |
28 | - * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
29 | - */ | |
30 | - public T findEntityByCondition(List<Object[]> condition, Long tenantId) throws NotFoundException,MultiRowException,NoContainTenantException; | |
31 | - | |
32 | - /** | |
33 | - * 根据条件sql查询 | |
34 | - * sqlCondition 为where 后面的条件。 | |
35 | - */ | |
36 | - public T findEntityBySql(String sqlCondition, Long tenantId) throws NotFoundException,MultiRowException,NoContainTenantException; | |
37 | - | |
38 | - /** | |
39 | - * 根据条件List<Object[]>查询 | |
40 | - * Object[]数组长度是3 | |
41 | - * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
42 | - */ | |
43 | - public List<T> findListByCondition(List<Object[]> condition, Long tenantId); | |
44 | - | |
45 | - /** | |
46 | - * 根据条件List<Object[]>查询 | |
47 | - * Object[]数组长度是3 | |
48 | - * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
49 | - */ | |
50 | - public List<T> findListByCondition(List<Object[]> condition, String sortCondition, Long tenantId); | |
51 | - | |
52 | - /** | |
53 | - * 根据条件sql查询 | |
54 | - * sqlCondition 为where 后面的条件。 | |
55 | - */ | |
56 | - public List<T> findListBySql(String sqlCondition, Long tenantId); | |
57 | - | |
58 | - /** | |
59 | - * 按条件分页查询 | |
60 | - * Object[]数组长度是3 | |
61 | - * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
62 | - */ | |
63 | - public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize, Long tenantId); | |
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, Long tenantId); | |
73 | - | |
74 | - /** | |
75 | - * 按sql分页查询, sqlCondition为where 后条件sql | |
76 | - */ | |
77 | - public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize, Long tenantId); | |
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, Long tenantId); | |
94 | - | |
95 | - /** | |
96 | - * 删除按List<Object[]>条件 | |
97 | - * Object[]数组长度是3 | |
98 | - * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
99 | - */ | |
100 | - public int deleteEntityByCondition(List<Object[]> condition, Long tenantId); | |
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, Long tenantId); | |
108 | - | |
109 | - /** | |
110 | - * 根据list对象逐个删除。 | |
111 | - * @throws NoContainTenantException | |
112 | - */ | |
113 | - public int deleteEntityList(List<ID> idList, Long tenantId); | |
114 | - | |
115 | - /** | |
116 | - * 根据ID修改指定的值 | |
117 | - */ | |
118 | - public int updateEntityById(List<Object[]> changeList, ID id, Long tenantId); | |
119 | - | |
120 | - /** | |
121 | - * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | |
122 | - * List<Object[]> condition 修改的条件, 数组长度是3, 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
123 | - */ | |
124 | - public int updateEntityByCondition(List<Object[]> updateObj, List<Object[]> condition, Long tenantId); | |
125 | - | |
126 | - /** | |
127 | - * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | |
128 | - * String sqlCondition 修改的条件。 | |
129 | - */ | |
130 | - public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition, Long tenantId); | |
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, Long tenantId); | |
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, Long tenantId); | |
152 | -} |
src/main/java/com/taover/repository/UtilsSql.java
... | ... | @@ -1,192 +0,0 @@ |
1 | -package com.taover.repository; | |
2 | - | |
3 | -import java.util.HashMap; | |
4 | -import java.util.Map; | |
5 | -import java.util.Stack; | |
6 | - | |
7 | -import org.springframework.util.StringUtils; | |
8 | - | |
9 | -public class UtilsSql { | |
10 | - | |
11 | - public static String[] splitCoreSql(String coreSql) throws Exception { | |
12 | - //去除''内的信息 | |
13 | - int fromIndex = calcFromIndex(coreSql); | |
14 | - if(fromIndex > -1) { | |
15 | - return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())}; | |
16 | - }else { | |
17 | - throw new Exception("未找到FROM子句"); | |
18 | - } | |
19 | - } | |
20 | - | |
21 | - private static int calcFromIndex(String coreSql) { | |
22 | - Stack<String> operStack = new Stack<String>(); | |
23 | - String coreSqlUpperCase = coreSql.toUpperCase(); | |
24 | - int sqlLen = coreSqlUpperCase.length(); | |
25 | - int currIndex = 0; | |
26 | - while(currIndex < sqlLen) { | |
27 | - String originContainBlank = subFirstStrEndWithBlank(coreSqlUpperCase, currIndex); | |
28 | - String itemWithoutBlank = originContainBlank.trim(); | |
29 | - if("".equals(itemWithoutBlank)) { | |
30 | - currIndex += originContainBlank.length(); | |
31 | - continue; | |
32 | - } | |
33 | - if(operStack.isEmpty() && "FROM".equals(itemWithoutBlank)) { | |
34 | - return currIndex; | |
35 | - } | |
36 | - dealCoupleMark(itemWithoutBlank, operStack); | |
37 | - currIndex += originContainBlank.length(); | |
38 | - } | |
39 | - return -1; | |
40 | - } | |
41 | - private static void dealCoupleMark(String itemWithoutBlank, Stack<String> operStack) { | |
42 | - char preChar = ' '; | |
43 | - for(int i=0; i<itemWithoutBlank.length(); ++i) { | |
44 | - char currChar = itemWithoutBlank.charAt(i); | |
45 | - if(preChar != '\\' && currChar == '\'') { | |
46 | - if(operStack.isEmpty() || !operStack.peek().equals("'")) { | |
47 | - operStack.push("'"); | |
48 | - }else if(operStack.peek().equals("'")) { | |
49 | - operStack.pop(); | |
50 | - } | |
51 | - }else if(currChar == '('){ | |
52 | - if(operStack.isEmpty() || !operStack.peek().equals("'")) { | |
53 | - operStack.push("("); | |
54 | - } | |
55 | - }else if(currChar == ')') { | |
56 | - if(!operStack.isEmpty() && operStack.peek().equals("(")) { | |
57 | - operStack.pop(); | |
58 | - } | |
59 | - } | |
60 | - preChar = currChar; | |
61 | - } | |
62 | - } | |
63 | - | |
64 | - private static String subFirstStrEndWithBlank(String coreSqlUpperCase, int startIndex) { | |
65 | - boolean startWithBlank = coreSqlUpperCase.charAt(startIndex)==' '; | |
66 | - int endIndex = startIndex; | |
67 | - int sqlLen = coreSqlUpperCase.length(); | |
68 | - char preChar = '0'; | |
69 | - for(int i=startIndex; i<sqlLen; ++i) { | |
70 | - char currChar = coreSqlUpperCase.charAt(i); | |
71 | - if(startWithBlank && currChar!=' ') { | |
72 | - endIndex = i; | |
73 | - break; | |
74 | - } | |
75 | - if(!startWithBlank && currChar!=' ' && preChar==' ') { | |
76 | - endIndex = i; | |
77 | - break; | |
78 | - } | |
79 | - preChar = currChar; | |
80 | - if(i == sqlLen-1) { | |
81 | - endIndex = sqlLen; | |
82 | - } | |
83 | - } | |
84 | - return coreSqlUpperCase.substring(startIndex, endIndex); | |
85 | - } | |
86 | - | |
87 | - /** | |
88 | - * 获取排序字符串 | |
89 | - * @param sort | |
90 | - * @param order | |
91 | - * @param columnPreffix | |
92 | - * @return | |
93 | - */ | |
94 | - public static String getSortCondition(String sort, String order, String columnPreffix){ | |
95 | - String underScoreSort = UtilsString.underscoreName(sort).toLowerCase(); | |
96 | - if(StringUtils.isEmpty(columnPreffix)){ | |
97 | - columnPreffix = ""; | |
98 | - } | |
99 | - String sortCondition = " "; | |
100 | - if(!StringUtils.isEmpty(underScoreSort)){ | |
101 | - sortCondition = " order by "; | |
102 | - String[] sortArr = underScoreSort.split(","); | |
103 | - if(StringUtils.isEmpty(order)){ | |
104 | - sortCondition += columnPreffix+sortArr[0]+" DESC "; | |
105 | - for(int i=1; i<sortArr.length; ++i){ | |
106 | - sortCondition += ","+columnPreffix+sortArr[i]+" DESC "; | |
107 | - } | |
108 | - }else{ | |
109 | - String[] orderArr = order.split(","); | |
110 | - sortCondition += sortArr[0]+" "+orderArr[0]+" "; | |
111 | - for(int i=1; i<sortArr.length; ++i){ | |
112 | - if(i < orderArr.length){ | |
113 | - sortCondition = ","+columnPreffix+sortArr[i]+" "+orderArr[i]+" "; | |
114 | - }else{ | |
115 | - sortCondition = ","+columnPreffix+sortArr[i]+" DESC "; | |
116 | - } | |
117 | - } | |
118 | - } | |
119 | - } | |
120 | - return sortCondition; | |
121 | - } | |
122 | - | |
123 | - /** | |
124 | - * 获取分页 | |
125 | - * @param sort | |
126 | - * @param order | |
127 | - * @param columnPreffix | |
128 | - * @return | |
129 | - */ | |
130 | - public static String getLimitCondition(int page, int pageSize){ | |
131 | - String sql = ""; | |
132 | - if(page < -1){ | |
133 | - page = 0; | |
134 | - if(pageSize < 1){ | |
135 | - pageSize = 0; | |
136 | - } | |
137 | - sql += " limit "+pageSize*(page-1)+","+pageSize; | |
138 | - }else if(page == -1){ | |
139 | - sql = ""; | |
140 | - }else{ | |
141 | - if(pageSize < 1){ | |
142 | - pageSize = 0; | |
143 | - } | |
144 | - sql += " limit "+pageSize*(page-1)+","+pageSize; | |
145 | - } | |
146 | - return sql; | |
147 | - } | |
148 | - | |
149 | - /** | |
150 | - * 创建分页返回 | |
151 | - * @param page | |
152 | - * @param rows | |
153 | - * @param data | |
154 | - * @return | |
155 | - */ | |
156 | - public static Map<String, Object> createPage(int page, int size, int total, Object data){ | |
157 | - Map<String, Object> pageData = new HashMap<String, Object>(); | |
158 | - pageData.put("page", page); | |
159 | - pageData.put("rows", data); | |
160 | - pageData.put("size", size); | |
161 | - pageData.put("total", total); | |
162 | - return pageData; | |
163 | - } | |
164 | - | |
165 | - public static void main(String[] args) { | |
166 | - String[] testSql = new String[] { | |
167 | - "\\", | |
168 | - "select actionFrom as 'seelctsele\\'ctd',(select a as 'fromCActio' from t) from www where 223=1 ", | |
169 | - "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id", | |
170 | - "select wdd, fromType from www where 223", | |
171 | - "SELECT excel_data.already_deal_line alreadyDealLine, excel_data.channel_id channelId, excel_data.channel_name channelName, excel_data.contain_express_status containExpressStatus, excel_data.create_time createTime, excel_data.deal_control dealControl, excel_data.deal_status dealStatus, excel_data.excel_path excelPath, excel_data.excel_title_index excelTitleIndex, excel_data.exists_error existsError, excel_data.file_id fileId, excel_data.file_name fileName, excel_data.group_name groupName, excel_data.id, excel_data.key_mapping keyMapping, excel_data.message_ssid messageSsid, excel_data.order_line orderLine, excel_data.payload payload, excel_data.progress_step progressStep, excel_data.select_sheet_name selectSheetName, excel_data.step_deal_time stepDealTime, excel_data.tenant_id tenantId, excel_data.update_time updateTime, excel_data.xls_batch_no xlsBatchNo FROM wxorder_excel_data excel_data WHERE excel_data.tenant_id=16", | |
172 | - "SELECT excel_data.xls_batch_no as 'xlsBatchNo', (select now()) as 'temp' FROM wxorder_excel_data excel_data WHERE excel_data.tenant_id=16" | |
173 | - }; | |
174 | - | |
175 | - for(int i=0; i<testSql.length; ++i) { | |
176 | - String item = testSql[i]; | |
177 | - System.out.println("================testSql["+i+"]==============="); | |
178 | - try { | |
179 | - String[] data = splitCoreSql(item); | |
180 | - System.out.println(data[0]); | |
181 | - System.out.println(data[1]); | |
182 | - } catch (Exception e) { | |
183 | - System.out.println(e.getMessage()); | |
184 | - } | |
185 | - } | |
186 | - | |
187 | -// String testSub = " asdf asdf asdfaf"; | |
188 | -// System.out.println(subFirstStrEndWithBlank(testSub, 5)); | |
189 | -// System.out.println(subFirstStrEndWithBlank(testSub, 6)); | |
190 | -// System.out.println(subFirstStrEndWithBlank(testSub, 13)); | |
191 | - } | |
192 | -} |
src/main/java/com/taover/repository/UtilsString.java
... | ... | @@ -1,237 +0,0 @@ |
1 | -package com.taover.repository; | |
2 | - | |
3 | -import java.net.URL; | |
4 | -import java.text.SimpleDateFormat; | |
5 | -import java.util.Date; | |
6 | - | |
7 | -public class UtilsString { | |
8 | - /** | |
9 | - * 格式化日期区间字符串 | |
10 | - * @param source | |
11 | - * @param splitStr | |
12 | - * @param dateFormat | |
13 | - * @return | |
14 | - * @throws Exception | |
15 | - */ | |
16 | - public static Date[] getDateFromString(String source, String splitStr, String dateFormat) throws Exception{ | |
17 | - Date[] resultObj = new Date[2]; | |
18 | - Date createdAtStart = null; | |
19 | - Date createdAtEnd = null; | |
20 | - if(source != null && !"".equals(source)){ | |
21 | - String[] createdAtArr = source.split(splitStr); | |
22 | - SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); | |
23 | - if(createdAtArr.length > 0){ | |
24 | - createdAtStart = sdf.parse(createdAtArr[0]); | |
25 | - } | |
26 | - if(createdAtArr.length > 1){ | |
27 | - createdAtEnd = sdf.parse(createdAtArr[1]); | |
28 | - } | |
29 | - } | |
30 | - resultObj[0] = createdAtStart; | |
31 | - resultObj[1] = createdAtEnd; | |
32 | - return resultObj; | |
33 | - } | |
34 | - | |
35 | - /** | |
36 | - * 获取URL path部分 | |
37 | - * @param url | |
38 | - * @return | |
39 | - */ | |
40 | - public static String getUrlPath(String url){ | |
41 | - if(url == null){ | |
42 | - return null; | |
43 | - } | |
44 | - if(url.startsWith("http")){ | |
45 | - try{ | |
46 | - URL dataUrl = new URL(url); | |
47 | - return dataUrl.getPath(); | |
48 | - }catch(Exception e){ | |
49 | - e.printStackTrace(); | |
50 | - } | |
51 | - } | |
52 | - return url; | |
53 | - } | |
54 | - | |
55 | - /** | |
56 | - * 在compares字符数组查找pattern字符串,找到则返回字串在数组中的索引,未找到返回-1 | |
57 | - * @param pattern | |
58 | - * @param compares | |
59 | - * @return | |
60 | - */ | |
61 | - public static int getStringIndex(String pattern, String compares[]){ | |
62 | - //参数检验 | |
63 | - if(pattern==null || compares==null){ | |
64 | - return -1; | |
65 | - } | |
66 | - | |
67 | - //循环遍历compares | |
68 | - for(int i=0; i<compares.length; ++i){ | |
69 | - if(compares[i].equals(pattern)){ | |
70 | - return i; | |
71 | - } | |
72 | - } | |
73 | - return -1; | |
74 | - } | |
75 | - | |
76 | - /** | |
77 | - * 生成发货单的发货单内部序号, 格式:'D'.date('Ymd') +8位数字 | |
78 | - * @return | |
79 | - */ | |
80 | - public static String getDeliverySn(){ | |
81 | - String result = "D"; | |
82 | - String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); | |
83 | - long temp = System.currentTimeMillis()%100000000; | |
84 | - result = result + date + temp; | |
85 | - return result; | |
86 | - } | |
87 | - | |
88 | - /** | |
89 | - * 通过表名获取BEAN类名 | |
90 | - * @param tableName | |
91 | - * @return | |
92 | - */ | |
93 | - public static String getBeanNameFormTableName(String tableName){ | |
94 | - if (tableName == null) return null; | |
95 | - if (tableName.length() == 0) return ""; | |
96 | - byte[] ss = tableName.toLowerCase().getBytes(); | |
97 | - int len = ss.length; | |
98 | - byte[] ss1 = new byte[len]; | |
99 | - ss1[0] = new String(ss, 0).toUpperCase().getBytes()[0]; | |
100 | - int k = 1; | |
101 | - for (int i = 1; i < ss.length; i++) { | |
102 | - if (ss[i] == '_') { | |
103 | - if (i < ss.length - 1) { | |
104 | - ss1[k] = (byte)Character.toUpperCase(ss[(i + 1)]); | |
105 | - i++; | |
106 | - } | |
107 | - len--; | |
108 | - } else { | |
109 | - ss1[k] = ss[i]; | |
110 | - } | |
111 | - k++; | |
112 | - } | |
113 | - return new String(ss1, 0, len); | |
114 | - } | |
115 | - | |
116 | - /** | |
117 | - * 获取前缀 | |
118 | - * @param value | |
119 | - * @param digitNumber | |
120 | - * @param preffixChar | |
121 | - * @return | |
122 | - */ | |
123 | - public static String getCodeWithPreffix(long value, int digitNumber, char preffixChar){ | |
124 | - String result = ""; | |
125 | - if(value>Long.MAX_VALUE || value<Long.MIN_VALUE){ | |
126 | - return null; | |
127 | - } | |
128 | - for(int i=digitNumber; i>0; --i){ | |
129 | - long baseDiv = (long) Math.pow(10, i-1); | |
130 | - long baseRand = (long) Math.pow(10, i); | |
131 | - long currentDigit = value % baseRand / baseDiv; | |
132 | - if(currentDigit == 0){ | |
133 | - result = result + preffixChar; | |
134 | - }else{ | |
135 | - result = result + currentDigit; | |
136 | - } | |
137 | - } | |
138 | - return result; | |
139 | - } | |
140 | - | |
141 | - /** | |
142 | - * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> | |
143 | - * 例如:HelloWorld->HELLO_WORLD | |
144 | - * @param name 转换前的驼峰式命名的字符串 | |
145 | - * @return 转换后下划线大写方式命名的字符串 | |
146 | - */ | |
147 | - public static String underscoreName(String name) { | |
148 | - StringBuilder result = new StringBuilder(); | |
149 | - if (name != null && name.length() > 0) { | |
150 | - // 将第一个字符处理成大写 | |
151 | - result.append(name.substring(0, 1).toUpperCase()); | |
152 | - // 循环处理其余字符 | |
153 | - for (int i = 1; i < name.length(); i++) { | |
154 | - String s = name.substring(i, i + 1); | |
155 | - // 在大写字母前添加下划线 | |
156 | - if (Character.isUpperCase(s.charAt(0)) && Character.isLetter(s.charAt(0))) { | |
157 | - result.append("_"); | |
158 | - } | |
159 | - // 其他字符直接转成大写 | |
160 | - result.append(s.toUpperCase()); | |
161 | - } | |
162 | - } | |
163 | - return result.toString(); | |
164 | - } | |
165 | - | |
166 | - /** | |
167 | - * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> | |
168 | - * 例如:HELLO_WORLD->HelloWorld | |
169 | - * @param name 转换前的下划线大写方式命名的字符串 | |
170 | - * @return 转换后的驼峰式命名的字符串 | |
171 | - */ | |
172 | - public static String camelName(String name) { | |
173 | - StringBuilder result = new StringBuilder(); | |
174 | - // 快速检查 | |
175 | - if (name == null || name.isEmpty()) { | |
176 | - // 没必要转换 | |
177 | - return ""; | |
178 | - } else if (!name.contains("_")) { | |
179 | - // 不含下划线,仅将首字母小写 | |
180 | - return name.substring(0, 1).toLowerCase() + name.substring(1); | |
181 | - } | |
182 | - // 用下划线将原始字符串分割 | |
183 | - String camels[] = name.split("_"); | |
184 | - for (String camel : camels) { | |
185 | - // 跳过原始字符串中开头、结尾的下换线或双重下划线 | |
186 | - if (camel.isEmpty()) { | |
187 | - continue; | |
188 | - } | |
189 | - // 处理真正的驼峰片段 | |
190 | - if (result.length() == 0) { | |
191 | - // 第一个驼峰片段,全部字母都小写 | |
192 | - result.append(camel.toLowerCase()); | |
193 | - } else { | |
194 | - // 其他的驼峰片段,首字母大写 | |
195 | - result.append(camel.substring(0, 1).toUpperCase()); | |
196 | - result.append(camel.substring(1).toLowerCase()); | |
197 | - } | |
198 | - } | |
199 | - return result.toString(); | |
200 | - } | |
201 | - | |
202 | - public static String getRandomStr(int digitNum){ | |
203 | - int numStartZero = 48; | |
204 | - int charStartUpperA = 65; | |
205 | - int charStartLowerA = 97; | |
206 | - int numSelectCount = 10; | |
207 | - int charSelectCount = 26; | |
208 | - int numCount = numSelectCount+2*charSelectCount; | |
209 | - String randomResult = ""; | |
210 | - for(int i=0; i<digitNum; ++i){ | |
211 | - int currIndex = (int)(Math.random()*numCount); | |
212 | - if(currIndex < numSelectCount){ | |
213 | - currIndex = numStartZero+currIndex; | |
214 | - }else if(currIndex < numSelectCount+charSelectCount){ | |
215 | - currIndex = charStartUpperA+(currIndex-numSelectCount); | |
216 | - }else{ | |
217 | - currIndex = charStartLowerA+(currIndex-numSelectCount-charSelectCount); | |
218 | - } | |
219 | - randomResult += (char)(currIndex)+""; | |
220 | - } | |
221 | - return randomResult; | |
222 | - } | |
223 | - | |
224 | - public static void main(String args[]){ | |
225 | -// System.out.println(getBeanNameFormTableName("asdf_asdf")); | |
226 | -// System.out.println(System.currentTimeMillis()); | |
227 | -// System.out.println(getCodeWithPreffix(1231212, 10, '-')); | |
228 | - /*String dd = "\"{\"success\":true,\"code\":1,\"printedorder_id\":\"1654\",\"error_message\":\"\"}\""; | |
229 | - dd = dd.substring(1, dd.length()-1); | |
230 | - System.out.println(dd); | |
231 | - JSONObject temp = JSONObject.fromObject(dd); | |
232 | - System.out.println(temp.getInt("code"));*/ | |
233 | - | |
234 | - //System.out.println(UtilsString.getUrlPath("https://ss0.umsapi.com/files/de/c1/13/dec11397254b06e1fd8750311ec2bb02ccd8d3dc.jpeg")); | |
235 | - System.out.println(getRandomStr(12)); | |
236 | - } | |
237 | -} | |
238 | 0 | \ No newline at end of file |
src/main/java/com/taover/repository/autoconfigure/ShardingSphereKeyGeneratorConfiguration.java
0 → 100644
... | ... | @@ -0,0 +1,31 @@ |
1 | +package com.taover.repository.autoconfigure; | |
2 | + | |
3 | +import org.springframework.boot.context.properties.ConfigurationProperties; | |
4 | +import org.springframework.context.annotation.Configuration; | |
5 | + | |
6 | +@Configuration | |
7 | +@ConfigurationProperties(prefix = "taover.sharding") | |
8 | +public class ShardingSphereKeyGeneratorConfiguration { | |
9 | + private String workerId; | |
10 | + private String maxTolerateTimeDifferenceMilliseconds; | |
11 | + private String maxVibrationOffset; | |
12 | + | |
13 | + public String getWorkerId() { | |
14 | + return workerId; | |
15 | + } | |
16 | + public void setWorkerId(String workerId) { | |
17 | + this.workerId = workerId; | |
18 | + } | |
19 | + public String getMaxTolerateTimeDifferenceMilliseconds() { | |
20 | + return maxTolerateTimeDifferenceMilliseconds; | |
21 | + } | |
22 | + public void setMaxTolerateTimeDifferenceMilliseconds(String maxTolerateTimeDifferenceMilliseconds) { | |
23 | + this.maxTolerateTimeDifferenceMilliseconds = maxTolerateTimeDifferenceMilliseconds; | |
24 | + } | |
25 | + public String getMaxVibrationOffset() { | |
26 | + return maxVibrationOffset; | |
27 | + } | |
28 | + public void setMaxVibrationOffset(String maxVibrationOffset) { | |
29 | + this.maxVibrationOffset = maxVibrationOffset; | |
30 | + } | |
31 | +} | ... | ... |
src/main/java/com/taover/repository/autoconfigure/TaoverRepositoryAutoConfiguration.java
0 → 100644
... | ... | @@ -0,0 +1,44 @@ |
1 | +package com.taover.repository.autoconfigure; | |
2 | + | |
3 | +import javax.annotation.Resource; | |
4 | + | |
5 | +import org.springframework.boot.autoconfigure.AutoConfigureAfter; | |
6 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; | |
7 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |
8 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | |
9 | +import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; | |
10 | +import org.springframework.boot.context.properties.EnableConfigurationProperties; | |
11 | +import org.springframework.context.annotation.Bean; | |
12 | +import org.springframework.context.annotation.Configuration; | |
13 | + | |
14 | +import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | |
15 | +import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenantImpl; | |
16 | +import com.taover.repository.shardingsphere.ShardingInfoRepository; | |
17 | +import com.taover.repository.shardingsphere.ShardingSphereService; | |
18 | + | |
19 | +@Configuration | |
20 | +@EnableConfigurationProperties({ShardingSphereKeyGeneratorConfiguration.class}) | |
21 | +@AutoConfigureAfter(JdbcTemplateAutoConfiguration.class) | |
22 | +@ConditionalOnProperty(prefix = "spring.shardingsphere", name = "enabled", havingValue = "true", matchIfMissing = true) | |
23 | +@ConditionalOnClass({ShardingSphereService.class}) | |
24 | +@ConditionalOnMissingBean(ShardingSphereService.class) | |
25 | +public class TaoverRepositoryAutoConfiguration { | |
26 | + | |
27 | + @Resource | |
28 | + private ShardingSphereKeyGeneratorConfiguration config; | |
29 | + | |
30 | + @Bean | |
31 | + public ShardingSphereService shardingSphereService() { | |
32 | + return new ShardingSphereService(config); | |
33 | + } | |
34 | + | |
35 | + @Bean | |
36 | + public ShardingInfoRepository shardingInfoRepository() throws Exception { | |
37 | + return new ShardingInfoRepository(); | |
38 | + } | |
39 | + | |
40 | + @Bean | |
41 | + public JdbcTemplateWrapperTenant jdbcTemplateWrapperTenant() { | |
42 | + return new JdbcTemplateWrapperTenantImpl(); | |
43 | + } | |
44 | +} | ... | ... |
src/main/java/com/taover/repository/bean/TenantIdentity.java
0 → 100644
src/main/java/com/taover/repository/exception/MultiRowException.java
src/main/java/com/taover/repository/exception/NotFoundException.java
src/main/java/com/taover/repository/exception/SqlParsePagerException.java
0 → 100644
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateWrapperTenant.java
0 → 100644
... | ... | @@ -0,0 +1,966 @@ |
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 JdbcTemplateWrapperTenant { | |
32 | + | |
33 | + //------------------------------------------------------------------------- | |
34 | + // Methods dealing with a plain java.sql.Connection | |
35 | + //------------------------------------------------------------------------- | |
36 | + | |
37 | + /** | |
38 | + * Execute a JDBC data access operation, implemented as callback action | |
39 | + * working on a JDBC Connection. This allows for implementing arbitrary | |
40 | + * data access operations, within Spring's managed JDBC environment: | |
41 | + * that is, participating in Spring-managed transactions and converting | |
42 | + * JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
43 | + * <p>The callback action can return a result object, for example a domain | |
44 | + * object or a collection of domain objects. | |
45 | + * @param action a callback object that specifies the action | |
46 | + * @return a result object returned by the action, or {@code null} if none | |
47 | + * @throws DataAccessException if there is any problem | |
48 | + */ | |
49 | + @Nullable | |
50 | + <T> T execute(ConnectionCallback<T> action, Long tenantId) throws DataAccessException; | |
51 | + | |
52 | + | |
53 | + //------------------------------------------------------------------------- | |
54 | + // Methods dealing with static SQL (java.sql.Statement) | |
55 | + //------------------------------------------------------------------------- | |
56 | + | |
57 | + /** | |
58 | + * Execute a JDBC data access operation, implemented as callback action | |
59 | + * working on a JDBC Statement. This allows for implementing arbitrary data | |
60 | + * access operations on a single Statement, within Spring's managed JDBC | |
61 | + * environment: that is, participating in Spring-managed transactions and | |
62 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
63 | + * <p>The callback action can return a result object, for example a domain | |
64 | + * object or a collection of domain objects. | |
65 | + * @param action a callback that specifies the action | |
66 | + * @return a result object returned by the action, or {@code null} if none | |
67 | + * @throws DataAccessException if there is any problem | |
68 | + */ | |
69 | + @Nullable | |
70 | + <T> T execute(StatementCallback<T> action, Long tenantId) throws DataAccessException; | |
71 | + | |
72 | + /** | |
73 | + * Issue a single SQL execute, typically a DDL statement. | |
74 | + * @param sql static SQL to execute | |
75 | + * @throws DataAccessException if there is any problem | |
76 | + */ | |
77 | + void execute(String sql, Long tenantId) throws DataAccessException; | |
78 | + | |
79 | + /** | |
80 | + * Execute a query given static SQL, reading the ResultSet with a | |
81 | + * ResultSetExtractor. | |
82 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
83 | + * execute a static query with a PreparedStatement, use the overloaded | |
84 | + * {@code query} method with {@code null} as argument array. | |
85 | + * @param sql the SQL query to execute | |
86 | + * @param rse a callback that will extract all rows of results | |
87 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
88 | + * @throws DataAccessException if there is any problem executing the query | |
89 | + * @see #query(String, Object[], ResultSetExtractor) | |
90 | + */ | |
91 | + @Nullable | |
92 | + <T> T query(String sql, ResultSetExtractor<T> rse, Long tenantId) throws DataAccessException; | |
93 | + | |
94 | + /** | |
95 | + * Execute a query given static SQL, reading the ResultSet on a per-row | |
96 | + * basis with a RowCallbackHandler. | |
97 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
98 | + * execute a static query with a PreparedStatement, use the overloaded | |
99 | + * {@code query} method with {@code null} as argument array. | |
100 | + * @param sql the SQL query to execute | |
101 | + * @param rch a callback that will extract results, one row at a time | |
102 | + * @throws DataAccessException if there is any problem executing the query | |
103 | + * @see #query(String, Object[], RowCallbackHandler) | |
104 | + */ | |
105 | + void query(String sql, RowCallbackHandler rch, Long tenantId) throws DataAccessException; | |
106 | + | |
107 | + /** | |
108 | + * Execute a query given static SQL, mapping each row to a result object | |
109 | + * via a RowMapper. | |
110 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
111 | + * execute a static query with a PreparedStatement, use the overloaded | |
112 | + * {@code query} method with {@code null} as argument array. | |
113 | + * @param sql the SQL query to execute | |
114 | + * @param rowMapper a callback that will map one object per row | |
115 | + * @return the result List, containing mapped objects | |
116 | + * @throws DataAccessException if there is any problem executing the query | |
117 | + * @see #query(String, Object[], RowMapper) | |
118 | + */ | |
119 | + <T> List<T> query(String sql, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
120 | + | |
121 | + /** | |
122 | + * Execute a query given static SQL, mapping a single result row to a | |
123 | + * result object via a RowMapper. | |
124 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
125 | + * execute a static query with a PreparedStatement, use the overloaded | |
126 | + * {@link #queryForObject(String, RowMapper, Object...)} method with | |
127 | + * {@code null} as argument array. | |
128 | + * @param sql the SQL query to execute | |
129 | + * @param rowMapper a callback that will map one object per row | |
130 | + * @return the single mapped object (may be {@code null} if the given | |
131 | + * {@link RowMapper} returned {@code} null) | |
132 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
133 | + * return exactly one row | |
134 | + * @throws DataAccessException if there is any problem executing the query | |
135 | + * @see #queryForObject(String, Object[], RowMapper) | |
136 | + */ | |
137 | + @Nullable | |
138 | + <T> T queryForObject(String sql, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
139 | + | |
140 | + /** | |
141 | + * Execute a query for a result object, given static SQL. | |
142 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
143 | + * execute a static query with a PreparedStatement, use the overloaded | |
144 | + * {@link #queryForObject(String, Class, Object...)} method with | |
145 | + * {@code null} as argument array. | |
146 | + * <p>This method is useful for running static SQL with a known outcome. | |
147 | + * The query is expected to be a single row/single column query; the returned | |
148 | + * result will be directly mapped to the corresponding object type. | |
149 | + * @param sql the SQL query to execute | |
150 | + * @param requiredType the type that the result object is expected to match | |
151 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | |
152 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | |
153 | + * exactly one row, or does not return exactly one column in that row | |
154 | + * @throws DataAccessException if there is any problem executing the query | |
155 | + * @see #queryForObject(String, Object[], Class) | |
156 | + */ | |
157 | + @Nullable | |
158 | + <T> T queryForObject(String sql, Class<T> requiredType, Long tenantId) throws DataAccessException; | |
159 | + | |
160 | + /** | |
161 | + * Execute a query for a result map, given static SQL. | |
162 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
163 | + * execute a static query with a PreparedStatement, use the overloaded | |
164 | + * {@link #queryForMap(String, Object...)} method with {@code null} | |
165 | + * as argument array. | |
166 | + * <p>The query is expected to be a single row query; the result row will be | |
167 | + * mapped to a Map (one entry for each column, using the column name as the key). | |
168 | + * @param sql the SQL query to execute | |
169 | + * @return the result Map (one entry per column, with column name as key) | |
170 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
171 | + * return exactly one row | |
172 | + * @throws DataAccessException if there is any problem executing the query | |
173 | + * @see #queryForMap(String, Object[]) | |
174 | + * @see ColumnMapRowMapper | |
175 | + */ | |
176 | + Map<String, Object> queryForMap(String sql, Long tenantId) throws DataAccessException; | |
177 | + | |
178 | + /** | |
179 | + * Execute a query for a result list, given static SQL. | |
180 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
181 | + * execute a static query with a PreparedStatement, use the overloaded | |
182 | + * {@code queryForList} method with {@code null} as argument array. | |
183 | + * <p>The results will be mapped to a List (one entry for each row) of | |
184 | + * result objects, each of them matching the specified element type. | |
185 | + * @param sql the SQL query to execute | |
186 | + * @param elementType the required type of element in the result list | |
187 | + * (for example, {@code Integer.class}) | |
188 | + * @return a List of objects that match the specified element type | |
189 | + * @throws DataAccessException if there is any problem executing the query | |
190 | + * @see #queryForList(String, Object[], Class) | |
191 | + * @see SingleColumnRowMapper | |
192 | + */ | |
193 | + <T> List<T> queryForList(String sql, Class<T> elementType, Long tenantId) throws DataAccessException; | |
194 | + | |
195 | + /** | |
196 | + * Execute a query for a result list, given static SQL. | |
197 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
198 | + * execute a static query with a PreparedStatement, use the overloaded | |
199 | + * {@code queryForList} method with {@code null} as argument array. | |
200 | + * <p>The results will be mapped to a List (one entry for each row) of | |
201 | + * Maps (one entry for each column using the column name as the key). | |
202 | + * Each element in the list will be of the form returned by this interface's | |
203 | + * {@code queryForMap} methods. | |
204 | + * @param sql the SQL query to execute | |
205 | + * @return an List that contains a Map per row | |
206 | + * @throws DataAccessException if there is any problem executing the query | |
207 | + * @see #queryForList(String, Object[]) | |
208 | + */ | |
209 | + List<Map<String, Object>> queryForList(String sql, Long tenantId) throws DataAccessException; | |
210 | + | |
211 | + /** | |
212 | + * Execute a query for a SqlRowSet, given static SQL. | |
213 | + * <p>Uses a JDBC Statement, not a PreparedStatement. If you want to | |
214 | + * execute a static query with a PreparedStatement, use the overloaded | |
215 | + * {@code queryForRowSet} method with {@code null} as argument array. | |
216 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | |
217 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | |
218 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | |
219 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | |
220 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | |
221 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | |
222 | + * @param sql the SQL query to execute | |
223 | + * @return a SqlRowSet representation (possibly a wrapper around a | |
224 | + * {@code javax.sql.rowset.CachedRowSet}) | |
225 | + * @throws DataAccessException if there is any problem executing the query | |
226 | + * @see #queryForRowSet(String, Object[]) | |
227 | + * @see SqlRowSetResultSetExtractor | |
228 | + * @see javax.sql.rowset.CachedRowSet | |
229 | + */ | |
230 | + SqlRowSet queryForRowSet(String sql, Long tenantId) throws DataAccessException; | |
231 | + | |
232 | + /** | |
233 | + * Issue a single SQL update operation (such as an insert, update or delete statement). | |
234 | + * @param sql static SQL to execute | |
235 | + * @return the number of rows affected | |
236 | + * @throws DataAccessException if there is any problem. | |
237 | + */ | |
238 | + int update(String sql, Long tenantId) throws DataAccessException; | |
239 | + | |
240 | + /** | |
241 | + * Issue multiple SQL updates on a single JDBC Statement using batching. | |
242 | + * <p>Will fall back to separate updates on a single Statement if the JDBC | |
243 | + * driver does not support batch updates. | |
244 | + * @param sql defining an array of SQL statements that will be executed. | |
245 | + * @return an array of the number of rows affected by each statement | |
246 | + * @throws DataAccessException if there is any problem executing the batch | |
247 | + */ | |
248 | + int[] batchUpdate(Long tenantId, String... sql) throws DataAccessException; | |
249 | + | |
250 | + | |
251 | + //------------------------------------------------------------------------- | |
252 | + // Methods dealing with prepared statements | |
253 | + //------------------------------------------------------------------------- | |
254 | + | |
255 | + /** | |
256 | + * Execute a JDBC data access operation, implemented as callback action | |
257 | + * working on a JDBC PreparedStatement. This allows for implementing arbitrary | |
258 | + * data access operations on a single Statement, within Spring's managed JDBC | |
259 | + * environment: that is, participating in Spring-managed transactions and | |
260 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
261 | + * <p>The callback action can return a result object, for example a domain | |
262 | + * object or a collection of domain objects. | |
263 | + * @param psc a callback that creates a PreparedStatement given a Connection | |
264 | + * @param action a callback that specifies the action | |
265 | + * @return a result object returned by the action, or {@code null} if none | |
266 | + * @throws DataAccessException if there is any problem | |
267 | + */ | |
268 | + @Nullable | |
269 | + <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, Long tenantId) throws DataAccessException; | |
270 | + | |
271 | + /** | |
272 | + * Execute a JDBC data access operation, implemented as callback action | |
273 | + * working on a JDBC PreparedStatement. This allows for implementing arbitrary | |
274 | + * data access operations on a single Statement, within Spring's managed JDBC | |
275 | + * environment: that is, participating in Spring-managed transactions and | |
276 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
277 | + * <p>The callback action can return a result object, for example a domain | |
278 | + * object or a collection of domain objects. | |
279 | + * @param sql the SQL to execute | |
280 | + * @param action a callback that specifies the action | |
281 | + * @return a result object returned by the action, or {@code null} if none | |
282 | + * @throws DataAccessException if there is any problem | |
283 | + */ | |
284 | + @Nullable | |
285 | + <T> T execute(String sql, PreparedStatementCallback<T> action, Long tenantId) throws DataAccessException; | |
286 | + | |
287 | + /** | |
288 | + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. | |
289 | + * <p>A PreparedStatementCreator can either be implemented directly or | |
290 | + * configured through a PreparedStatementCreatorFactory. | |
291 | + * @param psc a callback that creates a PreparedStatement given a Connection | |
292 | + * @param rse a callback that will extract results | |
293 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
294 | + * @throws DataAccessException if there is any problem | |
295 | + * @see PreparedStatementCreatorFactory | |
296 | + */ | |
297 | + @Nullable | |
298 | + <T> T query(PreparedStatementCreator psc, ResultSetExtractor<T> rse, Long tenantId) throws DataAccessException; | |
299 | + | |
300 | + /** | |
301 | + * Query using a prepared statement, reading the ResultSet with a ResultSetExtractor. | |
302 | + * @param sql the SQL query to execute | |
303 | + * @param pss a callback that knows how to set values on the prepared statement. | |
304 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | |
305 | + * Even if there are no bind parameters, this callback may be used to set the | |
306 | + * fetch size and other performance options. | |
307 | + * @param rse a callback that will extract results | |
308 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
309 | + * @throws DataAccessException if there is any problem | |
310 | + */ | |
311 | + @Nullable | |
312 | + <T> T query(String sql, @Nullable PreparedStatementSetter pss, ResultSetExtractor<T> rse, Long tenantId) throws DataAccessException; | |
313 | + | |
314 | + /** | |
315 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | |
316 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | |
317 | + * @param sql the SQL query to execute | |
318 | + * @param args arguments to bind to the query | |
319 | + * @param argTypes the SQL types of the arguments | |
320 | + * (constants from {@code java.sql.Types}) | |
321 | + * @param rse a callback that will extract results | |
322 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
323 | + * @throws DataAccessException if the query fails | |
324 | + * @see java.sql.Types | |
325 | + */ | |
326 | + @Nullable | |
327 | + <T> T query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<T> rse, Long tenantId) throws DataAccessException; | |
328 | + | |
329 | + /** | |
330 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | |
331 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | |
332 | + * @param sql the SQL query to execute | |
333 | + * @param args arguments to bind to the query | |
334 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
335 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
336 | + * only the argument value but also the SQL type and optionally the scale | |
337 | + * @param rse a callback that will extract results | |
338 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
339 | + * @throws DataAccessException if the query fails | |
340 | + */ | |
341 | + @Nullable | |
342 | + <T> T query(String sql, Object[] args, ResultSetExtractor<T> rse, Long tenantId) throws DataAccessException; | |
343 | + | |
344 | + /** | |
345 | + * Query given SQL to create a prepared statement from SQL and a list of arguments | |
346 | + * to bind to the query, reading the ResultSet with a ResultSetExtractor. | |
347 | + * @param sql the SQL query to execute | |
348 | + * @param rse a callback that will extract results | |
349 | + * @param args arguments to bind to the query | |
350 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
351 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
352 | + * only the argument value but also the SQL type and optionally the scale | |
353 | + * @return an arbitrary result object, as returned by the ResultSetExtractor | |
354 | + * @throws DataAccessException if the query fails | |
355 | + * @since 3.0.1 | |
356 | + */ | |
357 | + @Nullable | |
358 | + <T> T query(String sql, ResultSetExtractor<T> rse, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
359 | + | |
360 | + /** | |
361 | + * Query using a prepared statement, reading the ResultSet on a per-row basis | |
362 | + * with a RowCallbackHandler. | |
363 | + * <p>A PreparedStatementCreator can either be implemented directly or | |
364 | + * configured through a PreparedStatementCreatorFactory. | |
365 | + * @param psc a callback that creates a PreparedStatement given a Connection | |
366 | + * @param rch a callback that will extract results, one row at a time | |
367 | + * @throws DataAccessException if there is any problem | |
368 | + * @see PreparedStatementCreatorFactory | |
369 | + */ | |
370 | + void query(PreparedStatementCreator psc, RowCallbackHandler rch, Long tenantId) throws DataAccessException; | |
371 | + | |
372 | + /** | |
373 | + * Query given SQL to create a prepared statement from SQL and a | |
374 | + * PreparedStatementSetter implementation that knows how to bind values to the | |
375 | + * query, reading the ResultSet on a per-row basis with a RowCallbackHandler. | |
376 | + * @param sql the SQL query to execute | |
377 | + * @param pss a callback that knows how to set values on the prepared statement. | |
378 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | |
379 | + * Even if there are no bind parameters, this callback may be used to set the | |
380 | + * fetch size and other performance options. | |
381 | + * @param rch a callback that will extract results, one row at a time | |
382 | + * @throws DataAccessException if the query fails | |
383 | + */ | |
384 | + void query(String sql, @Nullable PreparedStatementSetter pss, RowCallbackHandler rch, Long tenantId) throws DataAccessException; | |
385 | + | |
386 | + /** | |
387 | + * Query given SQL to create a prepared statement from SQL and a list of | |
388 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | |
389 | + * with a RowCallbackHandler. | |
390 | + * @param sql the SQL query to execute | |
391 | + * @param args arguments to bind to the query | |
392 | + * @param argTypes the SQL types of the arguments | |
393 | + * (constants from {@code java.sql.Types}) | |
394 | + * @param rch a callback that will extract results, one row at a time | |
395 | + * @throws DataAccessException if the query fails | |
396 | + * @see java.sql.Types | |
397 | + */ | |
398 | + void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch, Long tenantId) throws DataAccessException; | |
399 | + | |
400 | + /** | |
401 | + * Query given SQL to create a prepared statement from SQL and a list of | |
402 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | |
403 | + * with a RowCallbackHandler. | |
404 | + * @param sql the SQL query to execute | |
405 | + * @param args arguments to bind to the query | |
406 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
407 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
408 | + * only the argument value but also the SQL type and optionally the scale | |
409 | + * @param rch a callback that will extract results, one row at a time | |
410 | + * @throws DataAccessException if the query fails | |
411 | + */ | |
412 | + void query(String sql, Object[] args, RowCallbackHandler rch, Long tenantId) throws DataAccessException; | |
413 | + | |
414 | + /** | |
415 | + * Query given SQL to create a prepared statement from SQL and a list of | |
416 | + * arguments to bind to the query, reading the ResultSet on a per-row basis | |
417 | + * with a RowCallbackHandler. | |
418 | + * @param sql the SQL query to execute | |
419 | + * @param rch a callback that will extract results, one row at a time | |
420 | + * @param args arguments to bind to the query | |
421 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
422 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
423 | + * only the argument value but also the SQL type and optionally the scale | |
424 | + * @throws DataAccessException if the query fails | |
425 | + * @since 3.0.1 | |
426 | + */ | |
427 | + void query(String sql, RowCallbackHandler rch, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
428 | + | |
429 | + /** | |
430 | + * Query using a prepared statement, mapping each row to a result object | |
431 | + * via a RowMapper. | |
432 | + * <p>A PreparedStatementCreator can either be implemented directly or | |
433 | + * configured through a PreparedStatementCreatorFactory. | |
434 | + * @param psc a callback that creates a PreparedStatement given a Connection | |
435 | + * @param rowMapper a callback that will map one object per row | |
436 | + * @return the result List, containing mapped objects | |
437 | + * @throws DataAccessException if there is any problem | |
438 | + * @see PreparedStatementCreatorFactory | |
439 | + */ | |
440 | + <T> List<T> query(PreparedStatementCreator psc, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
441 | + | |
442 | + /** | |
443 | + * Query given SQL to create a prepared statement from SQL and a | |
444 | + * PreparedStatementSetter implementation that knows how to bind values | |
445 | + * to the query, mapping each row to a result object via a RowMapper. | |
446 | + * @param sql the SQL query to execute | |
447 | + * @param pss a callback that knows how to set values on the prepared statement. | |
448 | + * If this is {@code null}, the SQL will be assumed to contain no bind parameters. | |
449 | + * Even if there are no bind parameters, this callback may be used to set the | |
450 | + * fetch size and other performance options. | |
451 | + * @param rowMapper a callback that will map one object per row | |
452 | + * @return the result List, containing mapped objects | |
453 | + * @throws DataAccessException if the query fails | |
454 | + */ | |
455 | + <T> List<T> query(String sql, @Nullable PreparedStatementSetter pss, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
456 | + | |
457 | + /** | |
458 | + * Query given SQL to create a prepared statement from SQL and a list of | |
459 | + * arguments to bind to the query, mapping each row to a result object | |
460 | + * via a RowMapper. | |
461 | + * @param sql the SQL query to execute | |
462 | + * @param args arguments to bind to the query | |
463 | + * @param argTypes the SQL types of the arguments | |
464 | + * (constants from {@code java.sql.Types}) | |
465 | + * @param rowMapper a callback that will map one object per row | |
466 | + * @return the result List, containing mapped objects | |
467 | + * @throws DataAccessException if the query fails | |
468 | + * @see java.sql.Types | |
469 | + */ | |
470 | + <T> List<T> query(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
471 | + | |
472 | + /** | |
473 | + * Query given SQL to create a prepared statement from SQL and a list of | |
474 | + * arguments to bind to the query, mapping each row to a result object | |
475 | + * via a RowMapper. | |
476 | + * @param sql the SQL query to execute | |
477 | + * @param args arguments to bind to the query | |
478 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
479 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
480 | + * only the argument value but also the SQL type and optionally the scale | |
481 | + * @param rowMapper a callback that will map one object per row | |
482 | + * @return the result List, containing mapped objects | |
483 | + * @throws DataAccessException if the query fails | |
484 | + */ | |
485 | + <T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
486 | + | |
487 | + /** | |
488 | + * Query given SQL to create a prepared statement from SQL and a list of | |
489 | + * arguments to bind to the query, mapping each row to a result object | |
490 | + * via a RowMapper. | |
491 | + * @param sql the SQL query to execute | |
492 | + * @param rowMapper a callback that will map one object per row | |
493 | + * @param args arguments to bind to the query | |
494 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
495 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
496 | + * only the argument value but also the SQL type and optionally the scale | |
497 | + * @return the result List, containing mapped objects | |
498 | + * @throws DataAccessException if the query fails | |
499 | + * @since 3.0.1 | |
500 | + */ | |
501 | + <T> List<T> query(String sql, RowMapper<T> rowMapper, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
502 | + | |
503 | + /** | |
504 | + * Query given SQL to create a prepared statement from SQL and a list | |
505 | + * of arguments to bind to the query, mapping a single result row to a | |
506 | + * result object via a RowMapper. | |
507 | + * @param sql the SQL query to execute | |
508 | + * @param args arguments to bind to the query | |
509 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type) | |
510 | + * @param argTypes the SQL types of the arguments | |
511 | + * (constants from {@code java.sql.Types}) | |
512 | + * @param rowMapper a callback that will map one object per row | |
513 | + * @return the single mapped object (may be {@code null} if the given | |
514 | + * {@link RowMapper} returned {@code} null) | |
515 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
516 | + * return exactly one row | |
517 | + * @throws DataAccessException if the query fails | |
518 | + */ | |
519 | + @Nullable | |
520 | + <T> T queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<T> rowMapper, Long tenantId) | |
521 | + throws DataAccessException; | |
522 | + | |
523 | + /** | |
524 | + * Query given SQL to create a prepared statement from SQL and a list | |
525 | + * of arguments to bind to the query, mapping a single result row to a | |
526 | + * result object via a RowMapper. | |
527 | + * @param sql the SQL query to execute | |
528 | + * @param args arguments to bind to the query | |
529 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
530 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
531 | + * only the argument value but also the SQL type and optionally the scale | |
532 | + * @param rowMapper a callback that will map one object per row | |
533 | + * @return the single mapped object (may be {@code null} if the given | |
534 | + * {@link RowMapper} returned {@code} null) | |
535 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
536 | + * return exactly one row | |
537 | + * @throws DataAccessException if the query fails | |
538 | + */ | |
539 | + @Nullable | |
540 | + <T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper, Long tenantId) throws DataAccessException; | |
541 | + | |
542 | + /** | |
543 | + * Query given SQL to create a prepared statement from SQL and a list | |
544 | + * of arguments to bind to the query, mapping a single result row to a | |
545 | + * result object via a RowMapper. | |
546 | + * @param sql the SQL query to execute | |
547 | + * @param rowMapper a callback that will map one object per row | |
548 | + * @param args arguments to bind to the query | |
549 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
550 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
551 | + * only the argument value but also the SQL type and optionally the scale | |
552 | + * @return the single mapped object (may be {@code null} if the given | |
553 | + * {@link RowMapper} returned {@code} null) | |
554 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
555 | + * return exactly one row | |
556 | + * @throws DataAccessException if the query fails | |
557 | + * @since 3.0.1 | |
558 | + */ | |
559 | + @Nullable | |
560 | + <T> T queryForObject(String sql, RowMapper<T> rowMapper, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
561 | + | |
562 | + /** | |
563 | + * Query given SQL to create a prepared statement from SQL and a list of | |
564 | + * arguments to bind to the query, expecting a result object. | |
565 | + * <p>The query is expected to be a single row/single column query; the returned | |
566 | + * result will be directly mapped to the corresponding object type. | |
567 | + * @param sql the SQL query to execute | |
568 | + * @param args arguments to bind to the query | |
569 | + * @param argTypes the SQL types of the arguments | |
570 | + * (constants from {@code java.sql.Types}) | |
571 | + * @param requiredType the type that the result object is expected to match | |
572 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | |
573 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | |
574 | + * exactly one row, or does not return exactly one column in that row | |
575 | + * @throws DataAccessException if the query fails | |
576 | + * @see #queryForObject(String, Class) | |
577 | + * @see java.sql.Types | |
578 | + */ | |
579 | + @Nullable | |
580 | + <T> T queryForObject(String sql, Object[] args, int[] argTypes, Class<T> requiredType, Long tenantId) | |
581 | + throws DataAccessException; | |
582 | + | |
583 | + /** | |
584 | + * Query given SQL to create a prepared statement from SQL and a list of | |
585 | + * arguments to bind to the query, expecting a result object. | |
586 | + * <p>The query is expected to be a single row/single column query; the returned | |
587 | + * result will be directly mapped to the corresponding object type. | |
588 | + * @param sql the SQL query to execute | |
589 | + * @param args arguments to bind to the query | |
590 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
591 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
592 | + * only the argument value but also the SQL type and optionally the scale | |
593 | + * @param requiredType the type that the result object is expected to match | |
594 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | |
595 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | |
596 | + * exactly one row, or does not return exactly one column in that row | |
597 | + * @throws DataAccessException if the query fails | |
598 | + * @see #queryForObject(String, Class) | |
599 | + */ | |
600 | + @Nullable | |
601 | + <T> T queryForObject(String sql, Object[] args, Class<T> requiredType, Long tenantId) throws DataAccessException; | |
602 | + | |
603 | + /** | |
604 | + * Query given SQL to create a prepared statement from SQL and a list of | |
605 | + * arguments to bind to the query, expecting a result object. | |
606 | + * <p>The query is expected to be a single row/single column query; the returned | |
607 | + * result will be directly mapped to the corresponding object type. | |
608 | + * @param sql the SQL query to execute | |
609 | + * @param requiredType the type that the result object is expected to match | |
610 | + * @param args arguments to bind to the query | |
611 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
612 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
613 | + * only the argument value but also the SQL type and optionally the scale | |
614 | + * @return the result object of the required type, or {@code null} in case of SQL NULL | |
615 | + * @throws IncorrectResultSizeDataAccessException if the query does not return | |
616 | + * exactly one row, or does not return exactly one column in that row | |
617 | + * @throws DataAccessException if the query fails | |
618 | + * @since 3.0.1 | |
619 | + * @see #queryForObject(String, Class) | |
620 | + */ | |
621 | + @Nullable | |
622 | + <T> T queryForObject(String sql, Class<T> requiredType, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
623 | + | |
624 | + /** | |
625 | + * Query given SQL to create a prepared statement from SQL and a list of | |
626 | + * arguments to bind to the query, expecting a result map. | |
627 | + * <p>The query is expected to be a single row query; the result row will be | |
628 | + * mapped to a Map (one entry for each column, using the column name as the key). | |
629 | + * @param sql the SQL query to execute | |
630 | + * @param args arguments to bind to the query | |
631 | + * @param argTypes the SQL types of the arguments | |
632 | + * (constants from {@code java.sql.Types}) | |
633 | + * @return the result Map (one entry per column, with column name as key) | |
634 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
635 | + * return exactly one row | |
636 | + * @throws DataAccessException if the query fails | |
637 | + * @see #queryForMap(String) | |
638 | + * @see ColumnMapRowMapper | |
639 | + * @see java.sql.Types | |
640 | + */ | |
641 | + Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes, Long tenantId) throws DataAccessException; | |
642 | + | |
643 | + /** | |
644 | + * Query given SQL to create a prepared statement from SQL and a list of | |
645 | + * arguments to bind to the query, expecting a result map. | |
646 | + * <p>The {@code queryForMap} methods defined by this interface are appropriate | |
647 | + * when you don't have a domain model. Otherwise, consider using one of the | |
648 | + * {@code queryForObject} methods. | |
649 | + * <p>The query is expected to be a single row query; the result row will be | |
650 | + * mapped to a Map (one entry for each column, using the column name as the key). | |
651 | + * @param sql the SQL query to execute | |
652 | + * @param args arguments to bind to the query | |
653 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
654 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
655 | + * only the argument value but also the SQL type and optionally the scale | |
656 | + * @return the result Map (one entry for each column, using the | |
657 | + * column name as the key) | |
658 | + * @throws IncorrectResultSizeDataAccessException if the query does not | |
659 | + * return exactly one row | |
660 | + * @throws DataAccessException if the query fails | |
661 | + * @see #queryForMap(String) | |
662 | + * @see ColumnMapRowMapper | |
663 | + */ | |
664 | + Map<String, Object> queryForMap(String sql, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
665 | + | |
666 | + /** | |
667 | + * Query given SQL to create a prepared statement from SQL and a list of | |
668 | + * arguments to bind to the query, expecting a result list. | |
669 | + * <p>The results will be mapped to a List (one entry for each row) of | |
670 | + * result objects, each of them matching the specified element type. | |
671 | + * @param sql the SQL query to execute | |
672 | + * @param args arguments to bind to the query | |
673 | + * @param argTypes the SQL types of the arguments | |
674 | + * (constants from {@code java.sql.Types}) | |
675 | + * @param elementType the required type of element in the result list | |
676 | + * (for example, {@code Integer.class}) | |
677 | + * @return a List of objects that match the specified element type | |
678 | + * @throws DataAccessException if the query fails | |
679 | + * @see #queryForList(String, Class) | |
680 | + * @see SingleColumnRowMapper | |
681 | + */ | |
682 | + <T> List<T> queryForList(String sql, Object[] args, int[] argTypes, Class<T> elementType, Long tenantId) | |
683 | + throws DataAccessException; | |
684 | + | |
685 | + /** | |
686 | + * Query given SQL to create a prepared statement from SQL and a list of | |
687 | + * arguments to bind to the query, expecting a result list. | |
688 | + * <p>The results will be mapped to a List (one entry for each row) of | |
689 | + * result objects, each of them matching the specified element type. | |
690 | + * @param sql the SQL query to execute | |
691 | + * @param args arguments to bind to the query | |
692 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
693 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
694 | + * only the argument value but also the SQL type and optionally the scale | |
695 | + * @param elementType the required type of element in the result list | |
696 | + * (for example, {@code Integer.class}) | |
697 | + * @return a List of objects that match the specified element type | |
698 | + * @throws DataAccessException if the query fails | |
699 | + * @see #queryForList(String, Class) | |
700 | + * @see SingleColumnRowMapper | |
701 | + */ | |
702 | + <T> List<T> queryForList(String sql, Object[] args, Class<T> elementType, Long tenantId) throws DataAccessException; | |
703 | + | |
704 | + /** | |
705 | + * Query given SQL to create a prepared statement from SQL and a list of | |
706 | + * arguments to bind to the query, expecting a result list. | |
707 | + * <p>The results will be mapped to a List (one entry for each row) of | |
708 | + * result objects, each of them matching the specified element type. | |
709 | + * @param sql the SQL query to execute | |
710 | + * @param elementType the required type of element in the result list | |
711 | + * (for example, {@code Integer.class}) | |
712 | + * @param args arguments to bind to the query | |
713 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
714 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
715 | + * only the argument value but also the SQL type and optionally the scale | |
716 | + * @return a List of objects that match the specified element type | |
717 | + * @throws DataAccessException if the query fails | |
718 | + * @since 3.0.1 | |
719 | + * @see #queryForList(String, Class) | |
720 | + * @see SingleColumnRowMapper | |
721 | + */ | |
722 | + <T> List<T> queryForList(String sql, Class<T> elementType, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
723 | + | |
724 | + /** | |
725 | + * Query given SQL to create a prepared statement from SQL and a list of | |
726 | + * arguments to bind to the query, expecting a result list. | |
727 | + * <p>The results will be mapped to a List (one entry for each row) of | |
728 | + * Maps (one entry for each column, using the column name as the key). | |
729 | + * Each element in the list will be of the form returned by this interface's | |
730 | + * {@code queryForMap} methods. | |
731 | + * @param sql the SQL query to execute | |
732 | + * @param args arguments to bind to the query | |
733 | + * @param argTypes the SQL types of the arguments | |
734 | + * (constants from {@code java.sql.Types}) | |
735 | + * @return a List that contains a Map per row | |
736 | + * @throws DataAccessException if the query fails | |
737 | + * @see #queryForList(String) | |
738 | + * @see java.sql.Types | |
739 | + */ | |
740 | + List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes, Long tenantId) throws DataAccessException; | |
741 | + | |
742 | + /** | |
743 | + * Query given SQL to create a prepared statement from SQL and a list of | |
744 | + * arguments to bind to the query, expecting a result list. | |
745 | + * <p>The results will be mapped to a List (one entry for each row) of | |
746 | + * Maps (one entry for each column, using the column name as the key). | |
747 | + * Each element in the list will be of the form returned by this interface's | |
748 | + * {@code queryForMap} methods. | |
749 | + * @param sql the SQL query to execute | |
750 | + * @param args arguments to bind to the query | |
751 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
752 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
753 | + * only the argument value but also the SQL type and optionally the scale | |
754 | + * @return a List that contains a Map per row | |
755 | + * @throws DataAccessException if the query fails | |
756 | + * @see #queryForList(String) | |
757 | + */ | |
758 | + List<Map<String, Object>> queryForList(String sql, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
759 | + | |
760 | + /** | |
761 | + * Query given SQL to create a prepared statement from SQL and a list of | |
762 | + * arguments to bind to the query, expecting a SqlRowSet. | |
763 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | |
764 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | |
765 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | |
766 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | |
767 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | |
768 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | |
769 | + * @param sql the SQL query to execute | |
770 | + * @param args arguments to bind to the query | |
771 | + * @param argTypes the SQL types of the arguments | |
772 | + * (constants from {@code java.sql.Types}) | |
773 | + * @return a SqlRowSet representation (possibly a wrapper around a | |
774 | + * {@code javax.sql.rowset.CachedRowSet}) | |
775 | + * @throws DataAccessException if there is any problem executing the query | |
776 | + * @see #queryForRowSet(String) | |
777 | + * @see SqlRowSetResultSetExtractor | |
778 | + * @see javax.sql.rowset.CachedRowSet | |
779 | + * @see java.sql.Types | |
780 | + */ | |
781 | + SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes, Long tenantId) throws DataAccessException; | |
782 | + | |
783 | + /** | |
784 | + * Query given SQL to create a prepared statement from SQL and a list of | |
785 | + * arguments to bind to the query, expecting a SqlRowSet. | |
786 | + * <p>The results will be mapped to an SqlRowSet which holds the data in a | |
787 | + * disconnected fashion. This wrapper will translate any SQLExceptions thrown. | |
788 | + * <p>Note that, for the default implementation, JDBC RowSet support needs to | |
789 | + * be available at runtime: by default, Sun's {@code com.sun.rowset.CachedRowSetImpl} | |
790 | + * class is used, which is part of JDK 1.5+ and also available separately as part of | |
791 | + * Sun's JDBC RowSet Implementations download (rowset.jar). | |
792 | + * @param sql the SQL query to execute | |
793 | + * @param args arguments to bind to the query | |
794 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
795 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
796 | + * only the argument value but also the SQL type and optionally the scale | |
797 | + * @return a SqlRowSet representation (possibly a wrapper around a | |
798 | + * {@code javax.sql.rowset.CachedRowSet}) | |
799 | + * @throws DataAccessException if there is any problem executing the query | |
800 | + * @see #queryForRowSet(String) | |
801 | + * @see SqlRowSetResultSetExtractor | |
802 | + * @see javax.sql.rowset.CachedRowSet | |
803 | + */ | |
804 | + SqlRowSet queryForRowSet(String sql, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
805 | + | |
806 | + /** | |
807 | + * Issue a single SQL update operation (such as an insert, update or delete | |
808 | + * statement) using a PreparedStatementCreator to provide SQL and any | |
809 | + * required parameters. | |
810 | + * <p>A PreparedStatementCreator can either be implemented directly or | |
811 | + * configured through a PreparedStatementCreatorFactory. | |
812 | + * @param psc a callback that provides SQL and any necessary parameters | |
813 | + * @return the number of rows affected | |
814 | + * @throws DataAccessException if there is any problem issuing the update | |
815 | + * @see PreparedStatementCreatorFactory | |
816 | + */ | |
817 | + int update(PreparedStatementCreator psc, Long tenantId) throws DataAccessException; | |
818 | + | |
819 | + /** | |
820 | + * Issue an update statement using a PreparedStatementCreator to provide SQL and | |
821 | + * any required parameters. Generated keys will be put into the given KeyHolder. | |
822 | + * <p>Note that the given PreparedStatementCreator has to create a statement | |
823 | + * with activated extraction of generated keys (a JDBC 3.0 feature). This can | |
824 | + * either be done directly or through using a PreparedStatementCreatorFactory. | |
825 | + * @param psc a callback that provides SQL and any necessary parameters | |
826 | + * @param generatedKeyHolder a KeyHolder that will hold the generated keys | |
827 | + * @return the number of rows affected | |
828 | + * @throws DataAccessException if there is any problem issuing the update | |
829 | + * @see PreparedStatementCreatorFactory | |
830 | + * @see org.springframework.jdbc.support.GeneratedKeyHolder | |
831 | + */ | |
832 | + int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder, Long tenantId) throws DataAccessException; | |
833 | + | |
834 | + /** | |
835 | + * Issue an update statement using a PreparedStatementSetter to set bind parameters, | |
836 | + * with given SQL. Simpler than using a PreparedStatementCreator as this method | |
837 | + * will create the PreparedStatement: The PreparedStatementSetter just needs to | |
838 | + * set parameters. | |
839 | + * @param sql the SQL containing bind parameters | |
840 | + * @param pss helper that sets bind parameters. If this is {@code null} | |
841 | + * we run an update with static SQL. | |
842 | + * @return the number of rows affected | |
843 | + * @throws DataAccessException if there is any problem issuing the update | |
844 | + */ | |
845 | + int update(String sql, @Nullable PreparedStatementSetter pss, Long tenantId) throws DataAccessException; | |
846 | + | |
847 | + /** | |
848 | + * Issue a single SQL update operation (such as an insert, update or delete statement) | |
849 | + * via a prepared statement, binding the given arguments. | |
850 | + * @param sql the SQL containing bind parameters | |
851 | + * @param args arguments to bind to the query | |
852 | + * @param argTypes the SQL types of the arguments | |
853 | + * (constants from {@code java.sql.Types}) | |
854 | + * @return the number of rows affected | |
855 | + * @throws DataAccessException if there is any problem issuing the update | |
856 | + * @see java.sql.Types | |
857 | + */ | |
858 | + int update(String sql, Object[] args, int[] argTypes, Long tenantId) throws DataAccessException; | |
859 | + | |
860 | + /** | |
861 | + * Issue a single SQL update operation (such as an insert, update or delete statement) | |
862 | + * via a prepared statement, binding the given arguments. | |
863 | + * @param sql the SQL containing bind parameters | |
864 | + * @param args arguments to bind to the query | |
865 | + * (leaving it to the PreparedStatement to guess the corresponding SQL type); | |
866 | + * may also contain {@link SqlParameterValue} objects which indicate not | |
867 | + * only the argument value but also the SQL type and optionally the scale | |
868 | + * @return the number of rows affected | |
869 | + * @throws DataAccessException if there is any problem issuing the update | |
870 | + */ | |
871 | + int update(String sql, Long tenantId, @Nullable Object... args) throws DataAccessException; | |
872 | + | |
873 | + /** | |
874 | + * Issue multiple update statements on a single PreparedStatement, | |
875 | + * using batch updates and a BatchPreparedStatementSetter to set values. | |
876 | + * <p>Will fall back to separate updates on a single PreparedStatement | |
877 | + * if the JDBC driver does not support batch updates. | |
878 | + * @param sql defining PreparedStatement that will be reused. | |
879 | + * All statements in the batch will use the same SQL. | |
880 | + * @param pss object to set parameters on the PreparedStatement | |
881 | + * created by this method | |
882 | + * @return an array of the number of rows affected by each statement | |
883 | + * @throws DataAccessException if there is any problem issuing the update | |
884 | + */ | |
885 | + int[] batchUpdate(String sql, BatchPreparedStatementSetter pss, Long tenantId) throws DataAccessException; | |
886 | + | |
887 | + /** | |
888 | + * Execute a batch using the supplied SQL statement with the batch of supplied arguments. | |
889 | + * @param sql the SQL statement to execute | |
890 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | |
891 | + * @return an array containing the numbers of rows affected by each update in the batch | |
892 | + */ | |
893 | + int[] batchUpdate(String sql, List<Object[]> batchArgs, Long tenantId) throws DataAccessException; | |
894 | + | |
895 | + /** | |
896 | + * Execute a batch using the supplied SQL statement with the batch of supplied arguments. | |
897 | + * @param sql the SQL statement to execute. | |
898 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | |
899 | + * @param argTypes the SQL types of the arguments | |
900 | + * (constants from {@code java.sql.Types}) | |
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, int[] argTypes, Long tenantId) throws DataAccessException; | |
904 | + | |
905 | + /** | |
906 | + * Execute multiple batches using the supplied SQL statement with the collect of supplied arguments. | |
907 | + * The arguments' values will be set using the ParameterizedPreparedStatementSetter. | |
908 | + * Each batch should be of size indicated in 'batchSize'. | |
909 | + * @param sql the SQL statement to execute. | |
910 | + * @param batchArgs the List of Object arrays containing the batch of arguments for the query | |
911 | + * @param batchSize batch size | |
912 | + * @param pss the ParameterizedPreparedStatementSetter to use | |
913 | + * @return an array containing for each batch another array containing the numbers of rows affected | |
914 | + * by each update in the batch | |
915 | + * @since 3.1 | |
916 | + */ | |
917 | + <T> int[][] batchUpdate(String sql, Collection<T> batchArgs, int batchSize, | |
918 | + ParameterizedPreparedStatementSetter<T> pss, Long tenantId) throws DataAccessException; | |
919 | + | |
920 | + | |
921 | + //------------------------------------------------------------------------- | |
922 | + // Methods dealing with callable statements | |
923 | + //------------------------------------------------------------------------- | |
924 | + | |
925 | + /** | |
926 | + * Execute a JDBC data access operation, implemented as callback action | |
927 | + * working on a JDBC CallableStatement. This allows for implementing arbitrary | |
928 | + * data access operations on a single Statement, within Spring's managed JDBC | |
929 | + * environment: that is, participating in Spring-managed transactions and | |
930 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
931 | + * <p>The callback action can return a result object, for example a domain | |
932 | + * object or a collection of domain objects. | |
933 | + * @param csc a callback that creates a CallableStatement given a Connection | |
934 | + * @param action a callback that specifies the action | |
935 | + * @return a result object returned by the action, or {@code null} if none | |
936 | + * @throws DataAccessException if there is any problem | |
937 | + */ | |
938 | + @Nullable | |
939 | + <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action, Long tenantId) throws DataAccessException; | |
940 | + | |
941 | + /** | |
942 | + * Execute a JDBC data access operation, implemented as callback action | |
943 | + * working on a JDBC CallableStatement. This allows for implementing arbitrary | |
944 | + * data access operations on a single Statement, within Spring's managed JDBC | |
945 | + * environment: that is, participating in Spring-managed transactions and | |
946 | + * converting JDBC SQLExceptions into Spring's DataAccessException hierarchy. | |
947 | + * <p>The callback action can return a result object, for example a domain | |
948 | + * object or a collection of domain objects. | |
949 | + * @param callString the SQL call string to execute | |
950 | + * @param action a callback that specifies the action | |
951 | + * @return a result object returned by the action, or {@code null} if none | |
952 | + * @throws DataAccessException if there is any problem | |
953 | + */ | |
954 | + @Nullable | |
955 | + <T> T execute(String callString, CallableStatementCallback<T> action, Long tenantId) throws DataAccessException; | |
956 | + | |
957 | + /** | |
958 | + * Execute a SQL call using a CallableStatementCreator to provide SQL and | |
959 | + * any required parameters. | |
960 | + * @param csc a callback that provides SQL and any necessary parameters | |
961 | + * @param declaredParameters list of declared SqlParameter objects | |
962 | + * @return a Map of extracted out parameters | |
963 | + * @throws DataAccessException if there is any problem issuing the update | |
964 | + */ | |
965 | + Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters, Long tenantId) throws DataAccessException; | |
966 | +} | ... | ... |
src/main/java/com/taover/repository/jdbctemplate/JdbcTemplateWrapperTenantImpl.java
0 → 100644
... | ... | @@ -0,0 +1,662 @@ |
1 | +package com.taover.repository.jdbctemplate; | |
2 | + | |
3 | +import java.util.Collection; | |
4 | +import java.util.List; | |
5 | +import java.util.Map; | |
6 | +import java.util.Map.Entry; | |
7 | + | |
8 | +import javax.annotation.Resource; | |
9 | + | |
10 | +import org.apache.shardingsphere.api.hint.HintManager; | |
11 | +import org.springframework.dao.DataAccessException; | |
12 | +import org.springframework.jdbc.core.BatchPreparedStatementSetter; | |
13 | +import org.springframework.jdbc.core.CallableStatementCallback; | |
14 | +import org.springframework.jdbc.core.CallableStatementCreator; | |
15 | +import org.springframework.jdbc.core.ConnectionCallback; | |
16 | +import org.springframework.jdbc.core.JdbcTemplate; | |
17 | +import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter; | |
18 | +import org.springframework.jdbc.core.PreparedStatementCallback; | |
19 | +import org.springframework.jdbc.core.PreparedStatementCreator; | |
20 | +import org.springframework.jdbc.core.PreparedStatementSetter; | |
21 | +import org.springframework.jdbc.core.ResultSetExtractor; | |
22 | +import org.springframework.jdbc.core.RowCallbackHandler; | |
23 | +import org.springframework.jdbc.core.RowMapper; | |
24 | +import org.springframework.jdbc.core.SqlParameter; | |
25 | +import org.springframework.jdbc.core.StatementCallback; | |
26 | +import org.springframework.jdbc.support.KeyHolder; | |
27 | +import org.springframework.jdbc.support.rowset.SqlRowSet; | |
28 | + | |
29 | +import com.taover.repository.shardingsphere.ShardingSphereService; | |
30 | + | |
31 | +public class JdbcTemplateWrapperTenantImpl implements JdbcTemplateWrapperTenant { | |
32 | + @Resource | |
33 | + private JdbcTemplate jdbcTemplate; | |
34 | + @Resource | |
35 | + private ShardingSphereService shardingSphereService; | |
36 | + | |
37 | + private void loadShardingInfo(Long tenantId) { | |
38 | + Map<String, String> shardingInfo = this.shardingSphereService.getShardingInfoMapByTenantId(tenantId); | |
39 | + if(shardingInfo == null || shardingInfo.isEmpty()) { | |
40 | + return; | |
41 | + } | |
42 | + HintManager.clear(); | |
43 | + for(Entry<String, String> item: shardingInfo.entrySet()) { | |
44 | + HintManager.getInstance().addTableShardingValue(item.getKey(), item.getValue()); | |
45 | + } | |
46 | + } | |
47 | + | |
48 | + private void clearShardingInfo() { | |
49 | + HintManager.clear(); | |
50 | + } | |
51 | + | |
52 | + @Override | |
53 | + public <E> E execute(ConnectionCallback<E> action, Long tenantId) throws DataAccessException { | |
54 | + try { | |
55 | + this.loadShardingInfo(tenantId); | |
56 | + return this.jdbcTemplate.execute(action); | |
57 | + }finally { | |
58 | + this.clearShardingInfo(); | |
59 | + } | |
60 | + } | |
61 | + | |
62 | + @Override | |
63 | + public <E> E execute(StatementCallback<E> action, Long tenantId) throws DataAccessException { | |
64 | + try { | |
65 | + this.loadShardingInfo(tenantId); | |
66 | + return this.jdbcTemplate.execute(action); | |
67 | + }finally { | |
68 | + this.clearShardingInfo(); | |
69 | + } | |
70 | + } | |
71 | + | |
72 | + @Override | |
73 | + public void execute(String sql, Long tenantId) throws DataAccessException { | |
74 | + try { | |
75 | + this.loadShardingInfo(tenantId); | |
76 | + this.jdbcTemplate.execute(sql); | |
77 | + }finally { | |
78 | + this.clearShardingInfo(); | |
79 | + } | |
80 | + } | |
81 | + | |
82 | + @Override | |
83 | + public <E> E query(String sql, ResultSetExtractor<E> rse, Long tenantId) throws DataAccessException { | |
84 | + try { | |
85 | + this.loadShardingInfo(tenantId); | |
86 | + return this.jdbcTemplate.query(sql, rse); | |
87 | + }finally { | |
88 | + this.clearShardingInfo(); | |
89 | + } | |
90 | + } | |
91 | + | |
92 | + @Override | |
93 | + public void query(String sql, RowCallbackHandler rch, Long tenantId) throws DataAccessException { | |
94 | + try { | |
95 | + this.loadShardingInfo(tenantId); | |
96 | + this.jdbcTemplate.query(sql, rch); | |
97 | + }finally { | |
98 | + this.clearShardingInfo(); | |
99 | + } | |
100 | + } | |
101 | + | |
102 | + @Override | |
103 | + public <E> List<E> query(String sql, RowMapper<E> rowMapper, Long tenantId) throws DataAccessException { | |
104 | + try { | |
105 | + this.loadShardingInfo(tenantId); | |
106 | + return this.jdbcTemplate.query(sql, rowMapper); | |
107 | + }finally { | |
108 | + this.clearShardingInfo(); | |
109 | + } | |
110 | + } | |
111 | + | |
112 | + @Override | |
113 | + public <E> E queryForObject(String sql, RowMapper<E> rowMapper, Long tenantId) throws DataAccessException { | |
114 | + try { | |
115 | + this.loadShardingInfo(tenantId); | |
116 | + return this.jdbcTemplate.queryForObject(sql, rowMapper); | |
117 | + }finally { | |
118 | + this.clearShardingInfo(); | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + @Override | |
123 | + public <E> E queryForObject(String sql, Class<E> requiredType, Long tenantId) throws DataAccessException { | |
124 | + try { | |
125 | + this.loadShardingInfo(tenantId); | |
126 | + return this.jdbcTemplate.queryForObject(sql, requiredType); | |
127 | + }finally { | |
128 | + this.clearShardingInfo(); | |
129 | + } | |
130 | + } | |
131 | + | |
132 | + @Override | |
133 | + public Map<String, Object> queryForMap(String sql, Long tenantId) throws DataAccessException { | |
134 | + try { | |
135 | + this.loadShardingInfo(tenantId); | |
136 | + return this.jdbcTemplate.queryForMap(sql); | |
137 | + }finally { | |
138 | + this.clearShardingInfo(); | |
139 | + } | |
140 | + } | |
141 | + | |
142 | + @Override | |
143 | + public <E> List<E> queryForList(String sql, Class<E> elementType, Long tenantId) throws DataAccessException { | |
144 | + try { | |
145 | + this.loadShardingInfo(tenantId); | |
146 | + return this.jdbcTemplate.queryForList(sql, elementType); | |
147 | + }finally { | |
148 | + this.clearShardingInfo(); | |
149 | + } | |
150 | + } | |
151 | + | |
152 | + @Override | |
153 | + public List<Map<String, Object>> queryForList(String sql, Long tenantId) throws DataAccessException { | |
154 | + try { | |
155 | + this.loadShardingInfo(tenantId); | |
156 | + return this.jdbcTemplate.queryForList(sql); | |
157 | + }finally { | |
158 | + this.clearShardingInfo(); | |
159 | + } | |
160 | + } | |
161 | + | |
162 | + @Override | |
163 | + public SqlRowSet queryForRowSet(String sql, Long tenantId) throws DataAccessException { | |
164 | + try { | |
165 | + this.loadShardingInfo(tenantId); | |
166 | + return this.jdbcTemplate.queryForRowSet(sql); | |
167 | + }finally { | |
168 | + this.clearShardingInfo(); | |
169 | + } | |
170 | + } | |
171 | + | |
172 | + @Override | |
173 | + public int update(String sql, Long tenantId) throws DataAccessException { | |
174 | + try { | |
175 | + this.loadShardingInfo(tenantId); | |
176 | + return this.jdbcTemplate.update(sql); | |
177 | + }finally { | |
178 | + this.clearShardingInfo(); | |
179 | + } | |
180 | + } | |
181 | + | |
182 | + @Override | |
183 | + public int[] batchUpdate(Long tenantId, String... sql) throws DataAccessException { | |
184 | + try { | |
185 | + this.loadShardingInfo(tenantId); | |
186 | + return this.jdbcTemplate.batchUpdate(sql); | |
187 | + }finally { | |
188 | + this.clearShardingInfo(); | |
189 | + } | |
190 | + } | |
191 | + | |
192 | + @Override | |
193 | + public <E> E execute(PreparedStatementCreator psc, PreparedStatementCallback<E> action, Long tenantId) | |
194 | + throws DataAccessException { | |
195 | + try { | |
196 | + this.loadShardingInfo(tenantId); | |
197 | + return this.jdbcTemplate.execute(psc, action); | |
198 | + }finally { | |
199 | + this.clearShardingInfo(); | |
200 | + } | |
201 | + } | |
202 | + | |
203 | + @Override | |
204 | + public <E> E execute(String sql, PreparedStatementCallback<E> action, Long tenantId) throws DataAccessException { | |
205 | + try { | |
206 | + this.loadShardingInfo(tenantId); | |
207 | + return this.jdbcTemplate.execute(sql, action); | |
208 | + }finally { | |
209 | + this.clearShardingInfo(); | |
210 | + } | |
211 | + } | |
212 | + | |
213 | + @Override | |
214 | + public <E> E query(PreparedStatementCreator psc, ResultSetExtractor<E> rse, Long tenantId) | |
215 | + throws DataAccessException { | |
216 | + try { | |
217 | + this.loadShardingInfo(tenantId); | |
218 | + return this.jdbcTemplate.query(psc, rse); | |
219 | + }finally { | |
220 | + this.clearShardingInfo(); | |
221 | + } | |
222 | + } | |
223 | + | |
224 | + @Override | |
225 | + public <E> E query(String sql, PreparedStatementSetter pss, ResultSetExtractor<E> rse, Long tenantId) | |
226 | + throws DataAccessException { | |
227 | + try { | |
228 | + this.loadShardingInfo(tenantId); | |
229 | + return this.jdbcTemplate.query(sql, pss, rse); | |
230 | + }finally { | |
231 | + this.clearShardingInfo(); | |
232 | + } | |
233 | + } | |
234 | + | |
235 | + @Override | |
236 | + public <E> E query(String sql, Object[] args, int[] argTypes, ResultSetExtractor<E> rse, Long tenantId) | |
237 | + throws DataAccessException { | |
238 | + try { | |
239 | + this.loadShardingInfo(tenantId); | |
240 | + return this.jdbcTemplate.query(sql, args, argTypes, rse); | |
241 | + }finally { | |
242 | + this.clearShardingInfo(); | |
243 | + } | |
244 | + } | |
245 | + | |
246 | + @Override | |
247 | + public <E> E query(String sql, Object[] args, ResultSetExtractor<E> rse, Long tenantId) throws DataAccessException { | |
248 | + try { | |
249 | + this.loadShardingInfo(tenantId); | |
250 | + return this.jdbcTemplate.query(sql, args, rse); | |
251 | + }finally { | |
252 | + this.clearShardingInfo(); | |
253 | + } | |
254 | + } | |
255 | + | |
256 | + @Override | |
257 | + public <E> E query(String sql, ResultSetExtractor<E> rse, Long tenantId, Object... args) | |
258 | + throws DataAccessException { | |
259 | + try { | |
260 | + this.loadShardingInfo(tenantId); | |
261 | + return this.jdbcTemplate.query(sql, rse, args); | |
262 | + }finally { | |
263 | + this.clearShardingInfo(); | |
264 | + } | |
265 | + } | |
266 | + | |
267 | + @Override | |
268 | + public void query(PreparedStatementCreator psc, RowCallbackHandler rch, Long tenantId) throws DataAccessException { | |
269 | + try { | |
270 | + this.loadShardingInfo(tenantId); | |
271 | + this.jdbcTemplate.query(psc, rch); | |
272 | + }finally { | |
273 | + this.clearShardingInfo(); | |
274 | + } | |
275 | + } | |
276 | + | |
277 | + @Override | |
278 | + public void query(String sql, PreparedStatementSetter pss, RowCallbackHandler rch, Long tenantId) | |
279 | + throws DataAccessException { | |
280 | + try { | |
281 | + this.loadShardingInfo(tenantId); | |
282 | + this.jdbcTemplate.query(sql, pss, rch); | |
283 | + }finally { | |
284 | + this.clearShardingInfo(); | |
285 | + } | |
286 | + } | |
287 | + | |
288 | + @Override | |
289 | + public void query(String sql, Object[] args, int[] argTypes, RowCallbackHandler rch, Long tenantId) | |
290 | + throws DataAccessException { | |
291 | + try { | |
292 | + this.loadShardingInfo(tenantId); | |
293 | + this.jdbcTemplate.query(sql, args, argTypes, rch); | |
294 | + }finally { | |
295 | + this.clearShardingInfo(); | |
296 | + } | |
297 | + } | |
298 | + | |
299 | + @Override | |
300 | + public void query(String sql, Object[] args, RowCallbackHandler rch, Long tenantId) throws DataAccessException { | |
301 | + try { | |
302 | + this.loadShardingInfo(tenantId); | |
303 | + this.jdbcTemplate.query(sql, args, rch); | |
304 | + }finally { | |
305 | + this.clearShardingInfo(); | |
306 | + } | |
307 | + } | |
308 | + | |
309 | + @Override | |
310 | + public void query(String sql, RowCallbackHandler rch, Long tenantId, Object... args) throws DataAccessException { | |
311 | + try { | |
312 | + this.loadShardingInfo(tenantId); | |
313 | + this.jdbcTemplate.query(sql, rch, args); | |
314 | + }finally { | |
315 | + this.clearShardingInfo(); | |
316 | + } | |
317 | + } | |
318 | + | |
319 | + @Override | |
320 | + public <E> List<E> query(PreparedStatementCreator psc, RowMapper<E> rowMapper, Long tenantId) | |
321 | + throws DataAccessException { | |
322 | + try { | |
323 | + this.loadShardingInfo(tenantId); | |
324 | + return this.jdbcTemplate.query(psc, rowMapper); | |
325 | + }finally { | |
326 | + this.clearShardingInfo(); | |
327 | + } | |
328 | + } | |
329 | + | |
330 | + @Override | |
331 | + public <E> List<E> query(String sql, PreparedStatementSetter pss, RowMapper<E> rowMapper, Long tenantId) | |
332 | + throws DataAccessException { | |
333 | + try { | |
334 | + this.loadShardingInfo(tenantId); | |
335 | + return this.jdbcTemplate.query(sql, pss, rowMapper); | |
336 | + }finally { | |
337 | + this.clearShardingInfo(); | |
338 | + } | |
339 | + } | |
340 | + | |
341 | + @Override | |
342 | + public <E> List<E> query(String sql, Object[] args, int[] argTypes, RowMapper<E> rowMapper, Long tenantId) | |
343 | + throws DataAccessException { | |
344 | + try { | |
345 | + this.loadShardingInfo(tenantId); | |
346 | + return this.jdbcTemplate.query(sql, args, argTypes, rowMapper); | |
347 | + }finally { | |
348 | + this.clearShardingInfo(); | |
349 | + } | |
350 | + } | |
351 | + | |
352 | + @Override | |
353 | + public <E> List<E> query(String sql, Object[] args, RowMapper<E> rowMapper, Long tenantId) | |
354 | + throws DataAccessException { | |
355 | + try { | |
356 | + this.loadShardingInfo(tenantId); | |
357 | + return this.jdbcTemplate.query(sql, args, rowMapper); | |
358 | + }finally { | |
359 | + this.clearShardingInfo(); | |
360 | + } | |
361 | + } | |
362 | + | |
363 | + @Override | |
364 | + public <E> List<E> query(String sql, RowMapper<E> rowMapper, Long tenantId, Object... args) | |
365 | + throws DataAccessException { | |
366 | + try { | |
367 | + this.loadShardingInfo(tenantId); | |
368 | + return this.jdbcTemplate.query(sql, rowMapper, args); | |
369 | + }finally { | |
370 | + this.clearShardingInfo(); | |
371 | + } | |
372 | + } | |
373 | + | |
374 | + @Override | |
375 | + public <E> E queryForObject(String sql, Object[] args, int[] argTypes, RowMapper<E> rowMapper, Long tenantId) | |
376 | + throws DataAccessException { | |
377 | + try { | |
378 | + this.loadShardingInfo(tenantId); | |
379 | + return this.jdbcTemplate.queryForObject(sql, args, argTypes, rowMapper); | |
380 | + }finally { | |
381 | + this.clearShardingInfo(); | |
382 | + } | |
383 | + } | |
384 | + | |
385 | + @Override | |
386 | + public <E> E queryForObject(String sql, Object[] args, RowMapper<E> rowMapper, Long tenantId) | |
387 | + throws DataAccessException { | |
388 | + try { | |
389 | + this.loadShardingInfo(tenantId); | |
390 | + return this.jdbcTemplate.queryForObject(sql, args, rowMapper); | |
391 | + }finally { | |
392 | + this.clearShardingInfo(); | |
393 | + } | |
394 | + } | |
395 | + | |
396 | + @Override | |
397 | + public <E> E queryForObject(String sql, RowMapper<E> rowMapper, Long tenantId, Object... args) | |
398 | + throws DataAccessException { | |
399 | + try { | |
400 | + this.loadShardingInfo(tenantId); | |
401 | + return this.jdbcTemplate.queryForObject(sql, rowMapper, args); | |
402 | + }finally { | |
403 | + this.clearShardingInfo(); | |
404 | + } | |
405 | + } | |
406 | + | |
407 | + @Override | |
408 | + public <E> E queryForObject(String sql, Object[] args, int[] argTypes, Class<E> requiredType, Long tenantId) | |
409 | + throws DataAccessException { | |
410 | + try { | |
411 | + this.loadShardingInfo(tenantId); | |
412 | + return this.jdbcTemplate.queryForObject(sql, args, argTypes, requiredType); | |
413 | + }finally { | |
414 | + this.clearShardingInfo(); | |
415 | + } | |
416 | + } | |
417 | + | |
418 | + @Override | |
419 | + public <E> E queryForObject(String sql, Object[] args, Class<E> requiredType, Long tenantId) | |
420 | + throws DataAccessException { | |
421 | + try { | |
422 | + this.loadShardingInfo(tenantId); | |
423 | + return this.jdbcTemplate.queryForObject(sql, args, requiredType); | |
424 | + }finally { | |
425 | + this.clearShardingInfo(); | |
426 | + } | |
427 | + } | |
428 | + | |
429 | + @Override | |
430 | + public <E> E queryForObject(String sql, Class<E> requiredType, Long tenantId, Object... args) | |
431 | + throws DataAccessException { | |
432 | + try { | |
433 | + this.loadShardingInfo(tenantId); | |
434 | + return this.jdbcTemplate.queryForObject(sql, requiredType, args); | |
435 | + }finally { | |
436 | + this.clearShardingInfo(); | |
437 | + } | |
438 | + } | |
439 | + | |
440 | + @Override | |
441 | + public Map<String, Object> queryForMap(String sql, Object[] args, int[] argTypes, Long tenantId) | |
442 | + throws DataAccessException { | |
443 | + try { | |
444 | + this.loadShardingInfo(tenantId); | |
445 | + return this.jdbcTemplate.queryForMap(sql, args, argTypes); | |
446 | + }finally { | |
447 | + this.clearShardingInfo(); | |
448 | + } | |
449 | + } | |
450 | + | |
451 | + @Override | |
452 | + public Map<String, Object> queryForMap(String sql, Long tenantId, Object... args) throws DataAccessException { | |
453 | + try { | |
454 | + this.loadShardingInfo(tenantId); | |
455 | + return this.jdbcTemplate.queryForMap(sql, args); | |
456 | + }finally { | |
457 | + this.clearShardingInfo(); | |
458 | + } | |
459 | + } | |
460 | + | |
461 | + @Override | |
462 | + public <E> List<E> queryForList(String sql, Object[] args, int[] argTypes, Class<E> elementType, Long tenantId) | |
463 | + throws DataAccessException { | |
464 | + try { | |
465 | + this.loadShardingInfo(tenantId); | |
466 | + return this.jdbcTemplate.queryForList(sql, args, argTypes, elementType); | |
467 | + }finally { | |
468 | + this.clearShardingInfo(); | |
469 | + } | |
470 | + } | |
471 | + | |
472 | + @Override | |
473 | + public <E> List<E> queryForList(String sql, Object[] args, Class<E> elementType, Long tenantId) | |
474 | + throws DataAccessException { | |
475 | + try { | |
476 | + this.loadShardingInfo(tenantId); | |
477 | + return this.jdbcTemplate.queryForList(sql, args, elementType); | |
478 | + }finally { | |
479 | + this.clearShardingInfo(); | |
480 | + } | |
481 | + } | |
482 | + | |
483 | + @Override | |
484 | + public <E> List<E> queryForList(String sql, Class<E> elementType, Long tenantId, Object... args) | |
485 | + throws DataAccessException { | |
486 | + try { | |
487 | + this.loadShardingInfo(tenantId); | |
488 | + return this.jdbcTemplate.queryForList(sql, elementType, args); | |
489 | + }finally { | |
490 | + this.clearShardingInfo(); | |
491 | + } | |
492 | + } | |
493 | + | |
494 | + @Override | |
495 | + public List<Map<String, Object>> queryForList(String sql, Object[] args, int[] argTypes, Long tenantId) | |
496 | + throws DataAccessException { | |
497 | + try { | |
498 | + this.loadShardingInfo(tenantId); | |
499 | + return this.jdbcTemplate.queryForList(sql, args, argTypes); | |
500 | + }finally { | |
501 | + this.clearShardingInfo(); | |
502 | + } | |
503 | + } | |
504 | + | |
505 | + @Override | |
506 | + public List<Map<String, Object>> queryForList(String sql, Long tenantId, Object... args) | |
507 | + throws DataAccessException { | |
508 | + try { | |
509 | + this.loadShardingInfo(tenantId); | |
510 | + return this.jdbcTemplate.queryForList(sql, args); | |
511 | + }finally { | |
512 | + this.clearShardingInfo(); | |
513 | + } | |
514 | + } | |
515 | + | |
516 | + @Override | |
517 | + public SqlRowSet queryForRowSet(String sql, Object[] args, int[] argTypes, Long tenantId) | |
518 | + throws DataAccessException { | |
519 | + try { | |
520 | + this.loadShardingInfo(tenantId); | |
521 | + return this.jdbcTemplate.queryForRowSet(sql, args, argTypes); | |
522 | + }finally { | |
523 | + this.clearShardingInfo(); | |
524 | + } | |
525 | + } | |
526 | + | |
527 | + @Override | |
528 | + public SqlRowSet queryForRowSet(String sql, Long tenantId, Object... args) throws DataAccessException { | |
529 | + try { | |
530 | + this.loadShardingInfo(tenantId); | |
531 | + return this.jdbcTemplate.queryForRowSet(sql, args); | |
532 | + }finally { | |
533 | + this.clearShardingInfo(); | |
534 | + } | |
535 | + } | |
536 | + | |
537 | + @Override | |
538 | + public int update(PreparedStatementCreator psc, Long tenantId) throws DataAccessException { | |
539 | + try { | |
540 | + this.loadShardingInfo(tenantId); | |
541 | + return this.jdbcTemplate.update(psc); | |
542 | + }finally { | |
543 | + this.clearShardingInfo(); | |
544 | + } | |
545 | + } | |
546 | + | |
547 | + @Override | |
548 | + public int update(PreparedStatementCreator psc, KeyHolder generatedKeyHolder, Long tenantId) | |
549 | + throws DataAccessException { | |
550 | + try { | |
551 | + this.loadShardingInfo(tenantId); | |
552 | + return this.jdbcTemplate.update(psc, generatedKeyHolder); | |
553 | + }finally { | |
554 | + this.clearShardingInfo(); | |
555 | + } | |
556 | + } | |
557 | + | |
558 | + @Override | |
559 | + public int update(String sql, PreparedStatementSetter pss, Long tenantId) throws DataAccessException { | |
560 | + try { | |
561 | + this.loadShardingInfo(tenantId); | |
562 | + return this.jdbcTemplate.update(sql, pss); | |
563 | + }finally { | |
564 | + this.clearShardingInfo(); | |
565 | + } | |
566 | + } | |
567 | + | |
568 | + @Override | |
569 | + public int update(String sql, Object[] args, int[] argTypes, Long tenantId) throws DataAccessException { | |
570 | + try { | |
571 | + this.loadShardingInfo(tenantId); | |
572 | + return this.jdbcTemplate.update(sql, args, argTypes); | |
573 | + }finally { | |
574 | + this.clearShardingInfo(); | |
575 | + } | |
576 | + } | |
577 | + | |
578 | + @Override | |
579 | + public int update(String sql, Long tenantId, Object... args) throws DataAccessException { | |
580 | + try { | |
581 | + this.loadShardingInfo(tenantId); | |
582 | + return this.jdbcTemplate.update(sql, args); | |
583 | + }finally { | |
584 | + this.clearShardingInfo(); | |
585 | + } | |
586 | + } | |
587 | + | |
588 | + @Override | |
589 | + public int[] batchUpdate(String sql, BatchPreparedStatementSetter pss, Long tenantId) throws DataAccessException { | |
590 | + try { | |
591 | + this.loadShardingInfo(tenantId); | |
592 | + return this.jdbcTemplate.batchUpdate(sql, pss); | |
593 | + }finally { | |
594 | + this.clearShardingInfo(); | |
595 | + } | |
596 | + } | |
597 | + | |
598 | + @Override | |
599 | + public int[] batchUpdate(String sql, List<Object[]> batchArgs, Long tenantId) throws DataAccessException { | |
600 | + try { | |
601 | + this.loadShardingInfo(tenantId); | |
602 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs); | |
603 | + }finally { | |
604 | + this.clearShardingInfo(); | |
605 | + } | |
606 | + } | |
607 | + | |
608 | + @Override | |
609 | + public int[] batchUpdate(String sql, List<Object[]> batchArgs, int[] argTypes, Long tenantId) | |
610 | + throws DataAccessException { | |
611 | + try { | |
612 | + this.loadShardingInfo(tenantId); | |
613 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs); | |
614 | + }finally { | |
615 | + this.clearShardingInfo(); | |
616 | + } | |
617 | + } | |
618 | + | |
619 | + @Override | |
620 | + public <E> int[][] batchUpdate(String sql, Collection<E> batchArgs, int batchSize, | |
621 | + ParameterizedPreparedStatementSetter<E> pss, Long tenantId) throws DataAccessException { | |
622 | + try { | |
623 | + this.loadShardingInfo(tenantId); | |
624 | + return this.jdbcTemplate.batchUpdate(sql, batchArgs, batchSize, pss); | |
625 | + }finally { | |
626 | + this.clearShardingInfo(); | |
627 | + } | |
628 | + } | |
629 | + | |
630 | + @Override | |
631 | + public <E> E execute(CallableStatementCreator csc, CallableStatementCallback<E> action, Long tenantId) | |
632 | + throws DataAccessException { | |
633 | + try { | |
634 | + this.loadShardingInfo(tenantId); | |
635 | + return this.jdbcTemplate.execute(csc, action); | |
636 | + }finally { | |
637 | + this.clearShardingInfo(); | |
638 | + } | |
639 | + } | |
640 | + | |
641 | + @Override | |
642 | + public <E> E execute(String callString, CallableStatementCallback<E> action, Long tenantId) | |
643 | + throws DataAccessException { | |
644 | + try { | |
645 | + this.loadShardingInfo(tenantId); | |
646 | + return this.jdbcTemplate.execute(callString, action); | |
647 | + }finally { | |
648 | + this.clearShardingInfo(); | |
649 | + } | |
650 | + } | |
651 | + | |
652 | + @Override | |
653 | + public Map<String, Object> call(CallableStatementCreator csc, List<SqlParameter> declaredParameters, Long tenantId) | |
654 | + throws DataAccessException { | |
655 | + try { | |
656 | + this.loadShardingInfo(tenantId); | |
657 | + return this.jdbcTemplate.call(csc, declaredParameters); | |
658 | + }finally { | |
659 | + this.clearShardingInfo(); | |
660 | + } | |
661 | + } | |
662 | +} | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingAlgorithmHint.java
0 → 100644
... | ... | @@ -0,0 +1,33 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | + | |
3 | +import java.util.Collection; | |
4 | +import java.util.HashSet; | |
5 | +import java.util.Set; | |
6 | + | |
7 | +import org.apache.commons.logging.Log; | |
8 | +import org.apache.commons.logging.LogFactory; | |
9 | +import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm; | |
10 | +import org.apache.shardingsphere.api.sharding.hint.HintShardingValue; | |
11 | + | |
12 | +public class ShardingAlgorithmHint implements HintShardingAlgorithm<String> { | |
13 | + Log log = LogFactory.getLog(ShardingAlgorithmHint.class); | |
14 | + | |
15 | + public ShardingAlgorithmHint() { | |
16 | + System.out.println("ShardingAlgorithmHint()"); | |
17 | + } | |
18 | + | |
19 | + @Override | |
20 | + public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<String> shardingValue) { | |
21 | + Collection<String> values = shardingValue.getValues(); | |
22 | + if(values == null || values.isEmpty()) { | |
23 | + String message = shardingValue.getLogicTableName()+"已启用分库分表,SQL语句请指定tenant_id 或 使用封装好的DAO层方法"; | |
24 | + log.error(message); | |
25 | + throw new RuntimeException(message); | |
26 | + } | |
27 | + Set<String> result = new HashSet<String>(availableTargetNames); | |
28 | + for(String item: values) { | |
29 | + result.add(shardingValue.getLogicTableName()+item); | |
30 | + } | |
31 | + return result; | |
32 | + } | |
33 | +} | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingInfoEntity.java
0 → 100644
... | ... | @@ -0,0 +1,106 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | +import java.math.BigDecimal; | |
5 | +import java.sql.Timestamp; | |
6 | +import java.util.Date; | |
7 | + | |
8 | +import javax.persistence.Entity; | |
9 | +import javax.persistence.Table; | |
10 | +import javax.persistence.Id; | |
11 | +import javax.persistence.Column; | |
12 | + | |
13 | +/** | |
14 | + * @version 1.0.0 | |
15 | + */ | |
16 | +@Entity | |
17 | +@Table(name="sharding_info", catalog="") | |
18 | +public class ShardingInfoEntity implements Serializable { | |
19 | + | |
20 | + private static final long serialVersionUID = 1L; | |
21 | + | |
22 | + | |
23 | + /** | |
24 | + * | |
25 | + */ | |
26 | + @Id | |
27 | + @Column(name="id") | |
28 | + private java.lang.Long id; | |
29 | + | |
30 | + public java.lang.Long getId(){ | |
31 | + return id; | |
32 | + } | |
33 | + public void setId(java.lang.Long id){ | |
34 | + this.id = id; | |
35 | + } | |
36 | + | |
37 | + /** | |
38 | + * 表名 | |
39 | + */ | |
40 | + @Column(name="table_name") | |
41 | + private java.lang.String tableName; | |
42 | + | |
43 | + public java.lang.String getTableName(){ | |
44 | + return tableName; | |
45 | + } | |
46 | + public void setTableName(java.lang.String tableName){ | |
47 | + this.tableName = tableName; | |
48 | + } | |
49 | + | |
50 | + /** | |
51 | + * 租户ID | |
52 | + */ | |
53 | + @Column(name="tenant_id") | |
54 | + private java.lang.Long tenantId; | |
55 | + | |
56 | + public java.lang.Long getTenantId(){ | |
57 | + return tenantId; | |
58 | + } | |
59 | + public void setTenantId(java.lang.Long tenantId){ | |
60 | + this.tenantId = tenantId; | |
61 | + } | |
62 | + | |
63 | + /** | |
64 | + * 后缀 | |
65 | + */ | |
66 | + @Column(name="sharding_suffix") | |
67 | + private java.lang.String shardingSuffix; | |
68 | + | |
69 | + public java.lang.String getShardingSuffix(){ | |
70 | + return shardingSuffix; | |
71 | + } | |
72 | + public void setShardingSuffix(java.lang.String shardingSuffix){ | |
73 | + this.shardingSuffix = shardingSuffix; | |
74 | + } | |
75 | + | |
76 | + /** | |
77 | + * | |
78 | + */ | |
79 | + @Column(name="create_time") | |
80 | + private java.sql.Timestamp createTime; | |
81 | + | |
82 | + public java.sql.Timestamp getCreateTime(){ | |
83 | + return createTime; | |
84 | + } | |
85 | + public void setCreateTime(java.sql.Timestamp createTime){ | |
86 | + this.createTime = createTime; | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * | |
91 | + */ | |
92 | + @Column(name="update_time") | |
93 | + private java.sql.Timestamp updateTime; | |
94 | + | |
95 | + public java.sql.Timestamp getUpdateTime(){ | |
96 | + return updateTime; | |
97 | + } | |
98 | + public void setUpdateTime(java.sql.Timestamp updateTime){ | |
99 | + this.updateTime = updateTime; | |
100 | + } | |
101 | + | |
102 | + @Override | |
103 | + public String toString() { | |
104 | + return "ShardingInfoEntity: [id="+id+",tableName="+tableName+",tenantId="+tenantId+",shardingSuffix="+shardingSuffix+",createTime="+createTime+",updateTime="+updateTime+"]"; | |
105 | + } | |
106 | + } | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingInfoRepository.java
0 → 100644
... | ... | @@ -0,0 +1,11 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | + | |
3 | +import com.taover.repository.CustomJdbcTemplate; | |
4 | + | |
5 | +public class ShardingInfoRepository extends CustomJdbcTemplate<ShardingInfoEntity, Long>{ | |
6 | + | |
7 | + public ShardingInfoRepository() throws Exception { | |
8 | + super(); | |
9 | + } | |
10 | + | |
11 | +} | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingKeyGeneratorExt.java
0 → 100644
... | ... | @@ -0,0 +1,21 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | + | |
3 | +import java.util.List; | |
4 | + | |
5 | +import com.taover.repository.autoconfigure.ShardingSphereKeyGeneratorConfiguration; | |
6 | + | |
7 | +public interface ShardingKeyGeneratorExt { | |
8 | + /** | |
9 | + * 生成ID List | |
10 | + * @param shardingOffset 分片索引 | |
11 | + * @param genNum 生成数量 | |
12 | + * @return | |
13 | + */ | |
14 | + List<Long> generateKeyList(int genNum); | |
15 | + | |
16 | + /** | |
17 | + * 设置属性值 | |
18 | + * @param config | |
19 | + */ | |
20 | + void loalConfig(ShardingSphereKeyGeneratorConfiguration config); | |
21 | +} | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingKeyGeneratorImpl.java
0 → 100644
... | ... | @@ -0,0 +1,212 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | +/* | |
3 | + * Licensed to the Apache Software Foundation (ASF) under one or more | |
4 | + * contributor license agreements. See the NOTICE file distributed with | |
5 | + * this work for additional information regarding copyright ownership. | |
6 | + * The ASF licenses this file to You under the Apache License, Version 2.0 | |
7 | + * (the "License"); you may not use this file except in compliance with | |
8 | + * the License. You may obtain a copy of the License at | |
9 | + * | |
10 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | + * | |
12 | + * Unless required by applicable law or agreed to in writing, software | |
13 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
14 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
15 | + * See the License for the specific language governing permissions and | |
16 | + * limitations under the License. | |
17 | + */ | |
18 | + | |
19 | +import java.util.ArrayList; | |
20 | +import java.util.Calendar; | |
21 | +import java.util.List; | |
22 | +import java.util.Properties; | |
23 | + | |
24 | +import org.apache.shardingsphere.core.strategy.keygen.TimeService; | |
25 | +import org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator; | |
26 | + | |
27 | +import com.google.common.base.Preconditions; | |
28 | +import com.taover.repository.autoconfigure.ShardingSphereKeyGeneratorConfiguration; | |
29 | + | |
30 | +/** | |
31 | + * Snowflake distributed primary key generator. | |
32 | + * | |
33 | + * <p> | |
34 | + * Use snowflake algorithm. Length is 64 bit. | |
35 | + * </p> | |
36 | + * | |
37 | + * <pre> | |
38 | + * 1bit sign bit. | |
39 | + * 41bits timestamp offset from 2016.11.01(ShardingSphere distributed primary key published data) to now. | |
40 | + * 10bits worker process id. | |
41 | + * 12bits auto increment offset in one mills | |
42 | + * </pre> | |
43 | + * | |
44 | + * <p> | |
45 | + * Call @{@code SnowflakeShardingKeyGenerator.setWorkerId} to set worker id, default value is 0. | |
46 | + * </p> | |
47 | + * | |
48 | + * <p> | |
49 | + * Call @{@code SnowflakeShardingKeyGenerator.setMaxTolerateTimeDifferenceMilliseconds} to set max tolerate time difference milliseconds, default value is 0. | |
50 | + * </p> | |
51 | + */ | |
52 | +public final class ShardingKeyGeneratorImpl implements ShardingKeyGenerator, ShardingKeyGeneratorExt { | |
53 | + | |
54 | + public static final long EPOCH; | |
55 | + | |
56 | + private static final long SEQUENCE_BITS = 11L; | |
57 | + | |
58 | + private static final long BATCH_FLAG_BITS = 1L; | |
59 | + | |
60 | + private static final long WORKER_ID_BITS = 10L; | |
61 | + | |
62 | + private static final long SEQUENCE_MASK = (1 << SEQUENCE_BITS) - 1; | |
63 | + | |
64 | + private static final long BATCH_FLAG_LEFT_SHIFT_BITS = SEQUENCE_BITS; | |
65 | + | |
66 | + private static final long WORKER_ID_LEFT_SHIFT_BITS = BATCH_FLAG_LEFT_SHIFT_BITS + BATCH_FLAG_BITS; | |
67 | + | |
68 | + private static final long TIMESTAMP_LEFT_SHIFT_BITS = WORKER_ID_LEFT_SHIFT_BITS + WORKER_ID_BITS; | |
69 | + | |
70 | + private static final long WORKER_ID_MAX_VALUE = 1L << WORKER_ID_BITS; | |
71 | + | |
72 | + private static final long WORKER_ID = 0; | |
73 | + | |
74 | + private static final int DEFAULT_VIBRATION_VALUE = 1; | |
75 | + | |
76 | + private static final int MAX_TOLERATE_TIME_DIFFERENCE_MILLISECONDS = 10; | |
77 | + | |
78 | + private static TimeService timeService = new TimeService(); | |
79 | + | |
80 | + private Properties properties = new Properties(); | |
81 | + | |
82 | + private int sequenceOffset = -1; | |
83 | + | |
84 | + private long sequence; | |
85 | + | |
86 | + private long lastMilliseconds; | |
87 | + | |
88 | + static { | |
89 | + Calendar calendar = Calendar.getInstance(); | |
90 | + calendar.set(2016, Calendar.NOVEMBER, 1); | |
91 | + calendar.set(Calendar.HOUR_OF_DAY, 0); | |
92 | + calendar.set(Calendar.MINUTE, 0); | |
93 | + calendar.set(Calendar.SECOND, 0); | |
94 | + calendar.set(Calendar.MILLISECOND, 0); | |
95 | + EPOCH = calendar.getTimeInMillis(); | |
96 | + } | |
97 | + | |
98 | + @Override | |
99 | + public String getType() { | |
100 | + return "SNOWFLAKE-SELF"; | |
101 | + } | |
102 | + | |
103 | + @Override | |
104 | + public synchronized Comparable<?> generateKey() { | |
105 | + long currentMilliseconds = timeService.getCurrentMillis(); | |
106 | + if (waitTolerateTimeDifferenceIfNeed(currentMilliseconds)) { | |
107 | + currentMilliseconds = timeService.getCurrentMillis(); | |
108 | + } | |
109 | + if (lastMilliseconds == currentMilliseconds) { | |
110 | + if (0L == (sequence = (sequence + 1) & SEQUENCE_MASK)) { | |
111 | + currentMilliseconds = waitUntilNextTime(currentMilliseconds); | |
112 | + } | |
113 | + } else { | |
114 | + vibrateSequenceOffset(); | |
115 | + sequence = sequenceOffset; | |
116 | + } | |
117 | + lastMilliseconds = currentMilliseconds; | |
118 | + return ((currentMilliseconds - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (getWorkerId() << WORKER_ID_LEFT_SHIFT_BITS) | (0 << BATCH_FLAG_LEFT_SHIFT_BITS) | sequence; | |
119 | + } | |
120 | + | |
121 | + private boolean waitTolerateTimeDifferenceIfNeed(final long currentMilliseconds) { | |
122 | + if (lastMilliseconds <= currentMilliseconds) { | |
123 | + return false; | |
124 | + } | |
125 | + long timeDifferenceMilliseconds = lastMilliseconds - currentMilliseconds; | |
126 | + Preconditions.checkState(timeDifferenceMilliseconds < getMaxTolerateTimeDifferenceMilliseconds(), | |
127 | + "Clock is moving backwards, last time is %d milliseconds, current time is %d milliseconds", lastMilliseconds, currentMilliseconds); | |
128 | + try { | |
129 | + Thread.sleep(timeDifferenceMilliseconds); | |
130 | + } catch (InterruptedException e) { | |
131 | + e.printStackTrace(); | |
132 | + } | |
133 | + return true; | |
134 | + } | |
135 | + | |
136 | + private long getWorkerId() { | |
137 | + long result = Long.valueOf(properties.getProperty("worker.id", String.valueOf(WORKER_ID))); | |
138 | + Preconditions.checkArgument(result >= 0L && result < WORKER_ID_MAX_VALUE); | |
139 | + return result; | |
140 | + } | |
141 | + | |
142 | + private int getMaxVibrationOffset() { | |
143 | + int result = Integer.parseInt(properties.getProperty("max.vibration.offset", String.valueOf(DEFAULT_VIBRATION_VALUE))); | |
144 | + Preconditions.checkArgument(result >= 0 && result <= SEQUENCE_MASK, "Illegal max vibration offset"); | |
145 | + return result; | |
146 | + } | |
147 | + | |
148 | + private int getMaxTolerateTimeDifferenceMilliseconds() { | |
149 | + return Integer.valueOf(properties.getProperty("max.tolerate.time.difference.milliseconds", String.valueOf(MAX_TOLERATE_TIME_DIFFERENCE_MILLISECONDS))); | |
150 | + } | |
151 | + | |
152 | + private long waitUntilNextTime(final long lastTime) { | |
153 | + long result = timeService.getCurrentMillis(); | |
154 | + while (result <= lastTime) { | |
155 | + result = timeService.getCurrentMillis(); | |
156 | + } | |
157 | + return result; | |
158 | + } | |
159 | + | |
160 | + private void vibrateSequenceOffset() { | |
161 | + sequenceOffset = sequenceOffset >= getMaxVibrationOffset() ? 0 : sequenceOffset + 1; | |
162 | + } | |
163 | + | |
164 | + @Override | |
165 | + public List<Long> generateKeyList(int genNum) { | |
166 | + long currentMilliseconds = timeService.getCurrentMillis(); | |
167 | + if (waitTolerateTimeDifferenceIfNeed(currentMilliseconds)) { | |
168 | + currentMilliseconds = timeService.getCurrentMillis(); | |
169 | + } | |
170 | + List<Long> data = new ArrayList<Long>(genNum); | |
171 | + for(int i=0; i<genNum; ++i) { | |
172 | + if (lastMilliseconds == currentMilliseconds) { | |
173 | + if (0L == (sequence = (sequence + 1) & SEQUENCE_MASK)) { | |
174 | + currentMilliseconds = waitUntilNextTime(currentMilliseconds); | |
175 | + } | |
176 | + } else { | |
177 | + vibrateSequenceOffset(); | |
178 | + sequence = sequenceOffset; | |
179 | + } | |
180 | + data.add(((currentMilliseconds - EPOCH) << TIMESTAMP_LEFT_SHIFT_BITS) | (getWorkerId() << WORKER_ID_LEFT_SHIFT_BITS) | (1 << BATCH_FLAG_LEFT_SHIFT_BITS) | sequence); | |
181 | + } | |
182 | + lastMilliseconds = currentMilliseconds; | |
183 | + return data; | |
184 | + } | |
185 | + | |
186 | + @Override | |
187 | + public Properties getProperties() { | |
188 | + return this.properties; | |
189 | + } | |
190 | + | |
191 | + @Override | |
192 | + public void setProperties(Properties properties) { | |
193 | + this.properties = properties; | |
194 | + } | |
195 | + | |
196 | + public static void setTimeService(TimeService timeService) { | |
197 | + ShardingKeyGeneratorImpl.timeService = timeService; | |
198 | + } | |
199 | + | |
200 | + @Override | |
201 | + public void loalConfig(ShardingSphereKeyGeneratorConfiguration config) { | |
202 | + if(config.getMaxTolerateTimeDifferenceMilliseconds() != null) { | |
203 | + properties.setProperty("max.tolerate.time.difference.milliseconds", config.getMaxTolerateTimeDifferenceMilliseconds()); | |
204 | + } | |
205 | + if(config.getWorkerId() != null) { | |
206 | + properties.setProperty("worker.id", config.getWorkerId()); | |
207 | + } | |
208 | + if(config.getMaxVibrationOffset() != null) { | |
209 | + properties.setProperty("max.vibration.offset", config.getMaxVibrationOffset()); | |
210 | + } | |
211 | + } | |
212 | +} | ... | ... |
src/main/java/com/taover/repository/shardingsphere/ShardingSphereService.java
0 → 100644
... | ... | @@ -0,0 +1,62 @@ |
1 | +package com.taover.repository.shardingsphere; | |
2 | + | |
3 | +import java.util.HashMap; | |
4 | +import java.util.List; | |
5 | +import java.util.Map; | |
6 | + | |
7 | +import javax.annotation.Resource; | |
8 | + | |
9 | +import org.springframework.stereotype.Service; | |
10 | + | |
11 | +import com.taover.repository.autoconfigure.ShardingSphereKeyGeneratorConfiguration; | |
12 | + | |
13 | +@Service | |
14 | +public class ShardingSphereService { | |
15 | + private Map<Long, Map<String, String>> CACHED_TABLE_SUFFIX_BY_TENANT = null; | |
16 | + private Map<String, ShardingKeyGeneratorExt> GENERATOR_HOLDER = new HashMap<String, ShardingKeyGeneratorExt>(); | |
17 | + | |
18 | + @Resource | |
19 | + private ShardingInfoRepository shardingInfoRepository; | |
20 | + private ShardingSphereKeyGeneratorConfiguration config; | |
21 | + | |
22 | + public ShardingSphereService(ShardingSphereKeyGeneratorConfiguration config) { | |
23 | + this.config = config; | |
24 | + } | |
25 | + | |
26 | + public List<Long> generateKeyList(String tableName, int number){ | |
27 | + if(!GENERATOR_HOLDER.containsKey(tableName)) { | |
28 | + loadShardingKeyGenerator(tableName); | |
29 | + } | |
30 | + return GENERATOR_HOLDER.get(tableName).generateKeyList(number); | |
31 | + } | |
32 | + | |
33 | + public Map<String, String> getShardingInfoMapByTenantId(Long tenantId) { | |
34 | + if(CACHED_TABLE_SUFFIX_BY_TENANT == null) { | |
35 | + loadCacheTableShardingInfoByTenantId(); | |
36 | + } | |
37 | + return CACHED_TABLE_SUFFIX_BY_TENANT.get(tenantId); | |
38 | + } | |
39 | + | |
40 | + private synchronized void loadCacheTableShardingInfoByTenantId() { | |
41 | + if(CACHED_TABLE_SUFFIX_BY_TENANT != null) { | |
42 | + return; | |
43 | + } | |
44 | + List<ShardingInfoEntity> dataList = this.shardingInfoRepository.findListBySql("1=1"); | |
45 | + Map<Long, Map<String, String>> tempData = new HashMap<Long, Map<String, String>>(); | |
46 | + for(ShardingInfoEntity item: dataList) { | |
47 | + Map<String, String> tempItem = tempData.getOrDefault(item.getTenantId(), new HashMap<String, String>()); | |
48 | + tempItem.put(item.getTableName(), item.getShardingSuffix()); | |
49 | + tempData.put(item.getTenantId(), tempItem); | |
50 | + } | |
51 | + CACHED_TABLE_SUFFIX_BY_TENANT = tempData; | |
52 | + } | |
53 | + | |
54 | + private synchronized void loadShardingKeyGenerator(String tableName) { | |
55 | + if(GENERATOR_HOLDER.containsKey(tableName)) { | |
56 | + return; | |
57 | + } | |
58 | + ShardingKeyGeneratorExt generator = new ShardingKeyGeneratorImpl(); | |
59 | + generator.loalConfig(config); | |
60 | + GENERATOR_HOLDER.put(tableName, generator); | |
61 | + } | |
62 | +} | ... | ... |
... | ... | @@ -0,0 +1,194 @@ |
1 | +package com.taover.repository.util; | |
2 | + | |
3 | +import java.util.HashMap; | |
4 | +import java.util.Map; | |
5 | +import java.util.Stack; | |
6 | + | |
7 | +import org.springframework.util.StringUtils; | |
8 | + | |
9 | +import com.taover.repository.exception.SqlParsePagerException; | |
10 | + | |
11 | +public class UtilsSql { | |
12 | + | |
13 | + public static String[] splitCoreSql(String coreSql) throws SqlParsePagerException { | |
14 | + //去除''内的信息 | |
15 | + int fromIndex = calcFromIndex(coreSql); | |
16 | + if(fromIndex > -1) { | |
17 | + return new String[] {coreSql.substring(0, fromIndex), coreSql.substring(fromIndex, coreSql.length())}; | |
18 | + }else { | |
19 | + throw new SqlParsePagerException("未找到FROM子句"); | |
20 | + } | |
21 | + } | |
22 | + | |
23 | + private static int calcFromIndex(String coreSql) { | |
24 | + Stack<String> operStack = new Stack<String>(); | |
25 | + String coreSqlUpperCase = coreSql.toUpperCase(); | |
26 | + int sqlLen = coreSqlUpperCase.length(); | |
27 | + int currIndex = 0; | |
28 | + while(currIndex < sqlLen) { | |
29 | + String originContainBlank = subFirstStrEndWithBlank(coreSqlUpperCase, currIndex); | |
30 | + String itemWithoutBlank = originContainBlank.trim(); | |
31 | + if("".equals(itemWithoutBlank)) { | |
32 | + currIndex += originContainBlank.length(); | |
33 | + continue; | |
34 | + } | |
35 | + if(operStack.isEmpty() && "FROM".equals(itemWithoutBlank)) { | |
36 | + return currIndex; | |
37 | + } | |
38 | + dealCoupleMark(itemWithoutBlank, operStack); | |
39 | + currIndex += originContainBlank.length(); | |
40 | + } | |
41 | + return -1; | |
42 | + } | |
43 | + private static void dealCoupleMark(String itemWithoutBlank, Stack<String> operStack) { | |
44 | + char preChar = ' '; | |
45 | + for(int i=0; i<itemWithoutBlank.length(); ++i) { | |
46 | + char currChar = itemWithoutBlank.charAt(i); | |
47 | + if(preChar != '\\' && currChar == '\'') { | |
48 | + if(operStack.isEmpty() || !operStack.peek().equals("'")) { | |
49 | + operStack.push("'"); | |
50 | + }else if(operStack.peek().equals("'")) { | |
51 | + operStack.pop(); | |
52 | + } | |
53 | + }else if(currChar == '('){ | |
54 | + if(operStack.isEmpty() || !operStack.peek().equals("'")) { | |
55 | + operStack.push("("); | |
56 | + } | |
57 | + }else if(currChar == ')') { | |
58 | + if(!operStack.isEmpty() && operStack.peek().equals("(")) { | |
59 | + operStack.pop(); | |
60 | + } | |
61 | + } | |
62 | + preChar = currChar; | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + private static String subFirstStrEndWithBlank(String coreSqlUpperCase, int startIndex) { | |
67 | + boolean startWithBlank = coreSqlUpperCase.charAt(startIndex)==' '; | |
68 | + int endIndex = startIndex; | |
69 | + int sqlLen = coreSqlUpperCase.length(); | |
70 | + char preChar = '0'; | |
71 | + for(int i=startIndex; i<sqlLen; ++i) { | |
72 | + char currChar = coreSqlUpperCase.charAt(i); | |
73 | + if(startWithBlank && currChar!=' ') { | |
74 | + endIndex = i; | |
75 | + break; | |
76 | + } | |
77 | + if(!startWithBlank && currChar!=' ' && preChar==' ') { | |
78 | + endIndex = i; | |
79 | + break; | |
80 | + } | |
81 | + preChar = currChar; | |
82 | + if(i == sqlLen-1) { | |
83 | + endIndex = sqlLen; | |
84 | + } | |
85 | + } | |
86 | + return coreSqlUpperCase.substring(startIndex, endIndex); | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * 获取排序字符串 | |
91 | + * @param sort | |
92 | + * @param order | |
93 | + * @param columnPreffix | |
94 | + * @return | |
95 | + */ | |
96 | + public static String getSortCondition(String sort, String order, String columnPreffix){ | |
97 | + String underScoreSort = UtilsString.underscoreName(sort).toLowerCase(); | |
98 | + if(StringUtils.isEmpty(columnPreffix)){ | |
99 | + columnPreffix = ""; | |
100 | + } | |
101 | + String sortCondition = " "; | |
102 | + if(!StringUtils.isEmpty(underScoreSort)){ | |
103 | + sortCondition = " order by "; | |
104 | + String[] sortArr = underScoreSort.split(","); | |
105 | + if(StringUtils.isEmpty(order)){ | |
106 | + sortCondition += columnPreffix+sortArr[0]+" DESC "; | |
107 | + for(int i=1; i<sortArr.length; ++i){ | |
108 | + sortCondition += ","+columnPreffix+sortArr[i]+" DESC "; | |
109 | + } | |
110 | + }else{ | |
111 | + String[] orderArr = order.split(","); | |
112 | + sortCondition += sortArr[0]+" "+orderArr[0]+" "; | |
113 | + for(int i=1; i<sortArr.length; ++i){ | |
114 | + if(i < orderArr.length){ | |
115 | + sortCondition = ","+columnPreffix+sortArr[i]+" "+orderArr[i]+" "; | |
116 | + }else{ | |
117 | + sortCondition = ","+columnPreffix+sortArr[i]+" DESC "; | |
118 | + } | |
119 | + } | |
120 | + } | |
121 | + } | |
122 | + return sortCondition; | |
123 | + } | |
124 | + | |
125 | + /** | |
126 | + * 获取分页 | |
127 | + * @param sort | |
128 | + * @param order | |
129 | + * @param columnPreffix | |
130 | + * @return | |
131 | + */ | |
132 | + public static String getLimitCondition(int page, int pageSize){ | |
133 | + String sql = ""; | |
134 | + if(page < -1){ | |
135 | + page = 0; | |
136 | + if(pageSize < 1){ | |
137 | + pageSize = 0; | |
138 | + } | |
139 | + sql += " limit "+pageSize*(page-1)+","+pageSize; | |
140 | + }else if(page == -1){ | |
141 | + sql = ""; | |
142 | + }else{ | |
143 | + if(pageSize < 1){ | |
144 | + pageSize = 0; | |
145 | + } | |
146 | + sql += " limit "+pageSize*(page-1)+","+pageSize; | |
147 | + } | |
148 | + return sql; | |
149 | + } | |
150 | + | |
151 | + /** | |
152 | + * 创建分页返回 | |
153 | + * @param page | |
154 | + * @param rows | |
155 | + * @param data | |
156 | + * @return | |
157 | + */ | |
158 | + public static Map<String, Object> createPage(int page, int size, int total, Object data){ | |
159 | + Map<String, Object> pageData = new HashMap<String, Object>(); | |
160 | + pageData.put("page", page); | |
161 | + pageData.put("rows", data); | |
162 | + pageData.put("size", size); | |
163 | + pageData.put("total", total); | |
164 | + return pageData; | |
165 | + } | |
166 | + | |
167 | + public static void main(String[] args) { | |
168 | + String[] testSql = new String[] { | |
169 | + "\\", | |
170 | + "select actionFrom as 'seelctsele\\'ctd',(select a as 'fromCActio' from t) from www where 223=1 ", | |
171 | + "SELECT wxorder_order.refund_way refundWay,wxorder_order.refund_delivery_sn refundDeliverySn, (SELECT sum(wxorder_compensate.`ware_refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as wareRefundMoney,(SELECT sum(wxorder_compensate.`refund_money`) from `wxorder_compensate` where wxorder_compensate.`order_id` = wxorder_order.id) as refundMoney, wxorder_order.operate_refund_time applyCompensateTime,wxorder_order.refund_instructions refundInstructions, wxorder_order.channel_id channelId, wxorder_channel.name channelName, wxorder_channel.platform_code platformCode, wxorder_order.pre_control_status as refundPreStatus, wxorder_order.ware_id wareId, wxorder_ware.name wareName, wxorder_order.id, wxorder_order.order_sn orderSn, wxorder_order.upload_sn uploadSn, wxorder_order.money_paid moneyPaid, wxorder_order.consignee, wxorder_order.mobile, wxorder_order.province_name provinceName, wxorder_order.city_name cityName, wxorder_order.district_name districtName, wxorder_order.address, wxorder_order.channel_remark channelRemark, wxorder_order.customer_remark customerRemark, wxorder_order.platform_customer_remark platformCustomerRemark, wxorder_order.sender_name senderName, wxorder_order.sender_mobile senderMobile, date_format(wxorder_order.create_time, '%Y-%m-%d %H:%i:%s') createTime, date_format(wxorder_order.real_delivery_time, '%Y-%m-%d %H:%i:%s') realDeliveryTime, wxorder_order.progress_distribute progressDistribute, wxorder_order.progress_delivery progressDelivery, wxorder_order.control_status controlStatus, wxorder_order.express_name expressName, wxorder_order.express_number expressNumber,wxorder_order.shipping_price shippingPrice, wxorder_order.customer_network_name ,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id) as compensateCountAll,(select count(*) from wxorder_compensate WHERE wxorder_compensate.order_id = wxorder_order.id and wxorder_compensate.progress_status = 1) as compensateCountDealed ,(select count(*) from wxorder_channel_refund_payment where wxorder_channel_refund_payment.order_id = wxorder_order.id) as channelRefundPaymentStatus,(select count(*) from wxorder_ware_refund_payment where wxorder_ware_refund_payment.order_id = wxorder_order.id) as wareRefundPaymentStatus FROM wxorder_order wxorder_order INNER JOIN wxorder_channel wxorder_channel ON wxorder_order.channel_id=wxorder_channel.id and wxorder_channel.tenant_id=54 INNER JOIN wxorder_ware wxorder_ware ON wxorder_order.ware_id=wxorder_ware.id and wxorder_ware.tenant_id=54 INNER JOIN wxorder_order_goods wxorder_order_goods ON wxorder_order.id=wxorder_order_goods.order_id and wxorder_order_goods.tenant_id=54 WHERE 1=1 AND wxorder_order.tenant_id='54' AND wxorder_order.control_status='4' GROUP BY wxorder_order.id", | |
172 | + "select wdd, fromType from www where 223", | |
173 | + "SELECT excel_data.already_deal_line alreadyDealLine, excel_data.channel_id channelId, excel_data.channel_name channelName, excel_data.contain_express_status containExpressStatus, excel_data.create_time createTime, excel_data.deal_control dealControl, excel_data.deal_status dealStatus, excel_data.excel_path excelPath, excel_data.excel_title_index excelTitleIndex, excel_data.exists_error existsError, excel_data.file_id fileId, excel_data.file_name fileName, excel_data.group_name groupName, excel_data.id, excel_data.key_mapping keyMapping, excel_data.message_ssid messageSsid, excel_data.order_line orderLine, excel_data.payload payload, excel_data.progress_step progressStep, excel_data.select_sheet_name selectSheetName, excel_data.step_deal_time stepDealTime, excel_data.tenant_id tenantId, excel_data.update_time updateTime, excel_data.xls_batch_no xlsBatchNo FROM wxorder_excel_data excel_data WHERE excel_data.tenant_id=16", | |
174 | + "SELECT excel_data.xls_batch_no as 'xlsBatchNo', (select now()) as 'temp' FROM wxorder_excel_data excel_data WHERE excel_data.tenant_id=16" | |
175 | + }; | |
176 | + | |
177 | + for(int i=0; i<testSql.length; ++i) { | |
178 | + String item = testSql[i]; | |
179 | + System.out.println("================testSql["+i+"]==============="); | |
180 | + try { | |
181 | + String[] data = splitCoreSql(item); | |
182 | + System.out.println(data[0]); | |
183 | + System.out.println(data[1]); | |
184 | + } catch (Exception e) { | |
185 | + System.out.println(e.getMessage()); | |
186 | + } | |
187 | + } | |
188 | + | |
189 | +// String testSub = " asdf asdf asdfaf"; | |
190 | +// System.out.println(subFirstStrEndWithBlank(testSub, 5)); | |
191 | +// System.out.println(subFirstStrEndWithBlank(testSub, 6)); | |
192 | +// System.out.println(subFirstStrEndWithBlank(testSub, 13)); | |
193 | + } | |
194 | +} | ... | ... |
src/main/java/com/taover/repository/util/UtilsString.java
0 → 100644
... | ... | @@ -0,0 +1,237 @@ |
1 | +package com.taover.repository.util; | |
2 | + | |
3 | +import java.net.URL; | |
4 | +import java.text.SimpleDateFormat; | |
5 | +import java.util.Date; | |
6 | + | |
7 | +public class UtilsString { | |
8 | + /** | |
9 | + * 格式化日期区间字符串 | |
10 | + * @param source | |
11 | + * @param splitStr | |
12 | + * @param dateFormat | |
13 | + * @return | |
14 | + * @throws Exception | |
15 | + */ | |
16 | + public static Date[] getDateFromString(String source, String splitStr, String dateFormat) throws Exception{ | |
17 | + Date[] resultObj = new Date[2]; | |
18 | + Date createdAtStart = null; | |
19 | + Date createdAtEnd = null; | |
20 | + if(source != null && !"".equals(source)){ | |
21 | + String[] createdAtArr = source.split(splitStr); | |
22 | + SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); | |
23 | + if(createdAtArr.length > 0){ | |
24 | + createdAtStart = sdf.parse(createdAtArr[0]); | |
25 | + } | |
26 | + if(createdAtArr.length > 1){ | |
27 | + createdAtEnd = sdf.parse(createdAtArr[1]); | |
28 | + } | |
29 | + } | |
30 | + resultObj[0] = createdAtStart; | |
31 | + resultObj[1] = createdAtEnd; | |
32 | + return resultObj; | |
33 | + } | |
34 | + | |
35 | + /** | |
36 | + * 获取URL path部分 | |
37 | + * @param url | |
38 | + * @return | |
39 | + */ | |
40 | + public static String getUrlPath(String url){ | |
41 | + if(url == null){ | |
42 | + return null; | |
43 | + } | |
44 | + if(url.startsWith("http")){ | |
45 | + try{ | |
46 | + URL dataUrl = new URL(url); | |
47 | + return dataUrl.getPath(); | |
48 | + }catch(Exception e){ | |
49 | + e.printStackTrace(); | |
50 | + } | |
51 | + } | |
52 | + return url; | |
53 | + } | |
54 | + | |
55 | + /** | |
56 | + * 在compares字符数组查找pattern字符串,找到则返回字串在数组中的索引,未找到返回-1 | |
57 | + * @param pattern | |
58 | + * @param compares | |
59 | + * @return | |
60 | + */ | |
61 | + public static int getStringIndex(String pattern, String compares[]){ | |
62 | + //参数检验 | |
63 | + if(pattern==null || compares==null){ | |
64 | + return -1; | |
65 | + } | |
66 | + | |
67 | + //循环遍历compares | |
68 | + for(int i=0; i<compares.length; ++i){ | |
69 | + if(compares[i].equals(pattern)){ | |
70 | + return i; | |
71 | + } | |
72 | + } | |
73 | + return -1; | |
74 | + } | |
75 | + | |
76 | + /** | |
77 | + * 生成发货单的发货单内部序号, 格式:'D'.date('Ymd') +8位数字 | |
78 | + * @return | |
79 | + */ | |
80 | + public static String getDeliverySn(){ | |
81 | + String result = "D"; | |
82 | + String date = new SimpleDateFormat("yyyyMMdd").format(new Date()); | |
83 | + long temp = System.currentTimeMillis()%100000000; | |
84 | + result = result + date + temp; | |
85 | + return result; | |
86 | + } | |
87 | + | |
88 | + /** | |
89 | + * 通过表名获取BEAN类名 | |
90 | + * @param tableName | |
91 | + * @return | |
92 | + */ | |
93 | + public static String getBeanNameFormTableName(String tableName){ | |
94 | + if (tableName == null) return null; | |
95 | + if (tableName.length() == 0) return ""; | |
96 | + byte[] ss = tableName.toLowerCase().getBytes(); | |
97 | + int len = ss.length; | |
98 | + byte[] ss1 = new byte[len]; | |
99 | + ss1[0] = new String(ss, 0).toUpperCase().getBytes()[0]; | |
100 | + int k = 1; | |
101 | + for (int i = 1; i < ss.length; i++) { | |
102 | + if (ss[i] == '_') { | |
103 | + if (i < ss.length - 1) { | |
104 | + ss1[k] = (byte)Character.toUpperCase(ss[(i + 1)]); | |
105 | + i++; | |
106 | + } | |
107 | + len--; | |
108 | + } else { | |
109 | + ss1[k] = ss[i]; | |
110 | + } | |
111 | + k++; | |
112 | + } | |
113 | + return new String(ss1, 0, len); | |
114 | + } | |
115 | + | |
116 | + /** | |
117 | + * 获取前缀 | |
118 | + * @param value | |
119 | + * @param digitNumber | |
120 | + * @param preffixChar | |
121 | + * @return | |
122 | + */ | |
123 | + public static String getCodeWithPreffix(long value, int digitNumber, char preffixChar){ | |
124 | + String result = ""; | |
125 | + if(value>Long.MAX_VALUE || value<Long.MIN_VALUE){ | |
126 | + return null; | |
127 | + } | |
128 | + for(int i=digitNumber; i>0; --i){ | |
129 | + long baseDiv = (long) Math.pow(10, i-1); | |
130 | + long baseRand = (long) Math.pow(10, i); | |
131 | + long currentDigit = value % baseRand / baseDiv; | |
132 | + if(currentDigit == 0){ | |
133 | + result = result + preffixChar; | |
134 | + }else{ | |
135 | + result = result + currentDigit; | |
136 | + } | |
137 | + } | |
138 | + return result; | |
139 | + } | |
140 | + | |
141 | + /** | |
142 | + * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> | |
143 | + * 例如:HelloWorld->HELLO_WORLD | |
144 | + * @param name 转换前的驼峰式命名的字符串 | |
145 | + * @return 转换后下划线大写方式命名的字符串 | |
146 | + */ | |
147 | + public static String underscoreName(String name) { | |
148 | + StringBuilder result = new StringBuilder(); | |
149 | + if (name != null && name.length() > 0) { | |
150 | + // 将第一个字符处理成大写 | |
151 | + result.append(name.substring(0, 1).toUpperCase()); | |
152 | + // 循环处理其余字符 | |
153 | + for (int i = 1; i < name.length(); i++) { | |
154 | + String s = name.substring(i, i + 1); | |
155 | + // 在大写字母前添加下划线 | |
156 | + if (Character.isUpperCase(s.charAt(0)) && Character.isLetter(s.charAt(0))) { | |
157 | + result.append("_"); | |
158 | + } | |
159 | + // 其他字符直接转成大写 | |
160 | + result.append(s.toUpperCase()); | |
161 | + } | |
162 | + } | |
163 | + return result.toString(); | |
164 | + } | |
165 | + | |
166 | + /** | |
167 | + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> | |
168 | + * 例如:HELLO_WORLD->HelloWorld | |
169 | + * @param name 转换前的下划线大写方式命名的字符串 | |
170 | + * @return 转换后的驼峰式命名的字符串 | |
171 | + */ | |
172 | + public static String camelName(String name) { | |
173 | + StringBuilder result = new StringBuilder(); | |
174 | + // 快速检查 | |
175 | + if (name == null || name.isEmpty()) { | |
176 | + // 没必要转换 | |
177 | + return ""; | |
178 | + } else if (!name.contains("_")) { | |
179 | + // 不含下划线,仅将首字母小写 | |
180 | + return name.substring(0, 1).toLowerCase() + name.substring(1); | |
181 | + } | |
182 | + // 用下划线将原始字符串分割 | |
183 | + String camels[] = name.split("_"); | |
184 | + for (String camel : camels) { | |
185 | + // 跳过原始字符串中开头、结尾的下换线或双重下划线 | |
186 | + if (camel.isEmpty()) { | |
187 | + continue; | |
188 | + } | |
189 | + // 处理真正的驼峰片段 | |
190 | + if (result.length() == 0) { | |
191 | + // 第一个驼峰片段,全部字母都小写 | |
192 | + result.append(camel.toLowerCase()); | |
193 | + } else { | |
194 | + // 其他的驼峰片段,首字母大写 | |
195 | + result.append(camel.substring(0, 1).toUpperCase()); | |
196 | + result.append(camel.substring(1).toLowerCase()); | |
197 | + } | |
198 | + } | |
199 | + return result.toString(); | |
200 | + } | |
201 | + | |
202 | + public static String getRandomStr(int digitNum){ | |
203 | + int numStartZero = 48; | |
204 | + int charStartUpperA = 65; | |
205 | + int charStartLowerA = 97; | |
206 | + int numSelectCount = 10; | |
207 | + int charSelectCount = 26; | |
208 | + int numCount = numSelectCount+2*charSelectCount; | |
209 | + String randomResult = ""; | |
210 | + for(int i=0; i<digitNum; ++i){ | |
211 | + int currIndex = (int)(Math.random()*numCount); | |
212 | + if(currIndex < numSelectCount){ | |
213 | + currIndex = numStartZero+currIndex; | |
214 | + }else if(currIndex < numSelectCount+charSelectCount){ | |
215 | + currIndex = charStartUpperA+(currIndex-numSelectCount); | |
216 | + }else{ | |
217 | + currIndex = charStartLowerA+(currIndex-numSelectCount-charSelectCount); | |
218 | + } | |
219 | + randomResult += (char)(currIndex)+""; | |
220 | + } | |
221 | + return randomResult; | |
222 | + } | |
223 | + | |
224 | + public static void main(String args[]){ | |
225 | +// System.out.println(getBeanNameFormTableName("asdf_asdf")); | |
226 | +// System.out.println(System.currentTimeMillis()); | |
227 | +// System.out.println(getCodeWithPreffix(1231212, 10, '-')); | |
228 | + /*String dd = "\"{\"success\":true,\"code\":1,\"printedorder_id\":\"1654\",\"error_message\":\"\"}\""; | |
229 | + dd = dd.substring(1, dd.length()-1); | |
230 | + System.out.println(dd); | |
231 | + JSONObject temp = JSONObject.fromObject(dd); | |
232 | + System.out.println(temp.getInt("code"));*/ | |
233 | + | |
234 | + //System.out.println(UtilsString.getUrlPath("https://ss0.umsapi.com/files/de/c1/13/dec11397254b06e1fd8750311ec2bb02ccd8d3dc.jpeg")); | |
235 | + System.out.println(getRandomStr(12)); | |
236 | + } | |
237 | +} | |
0 | 238 | \ No newline at end of file | ... | ... |
src/main/resources/META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
0 → 100644
src/test/java/com/taover/repository/test/TestAutoconfigure.java
0 → 100644
... | ... | @@ -0,0 +1,20 @@ |
1 | +package com.taover.repository.test; | |
2 | + | |
3 | +import org.springframework.boot.SpringApplication; | |
4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | |
5 | +import org.springframework.context.ConfigurableApplicationContext; | |
6 | +import org.springframework.scheduling.annotation.EnableScheduling; | |
7 | + | |
8 | +import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | |
9 | + | |
10 | +@SpringBootApplication | |
11 | +@EnableScheduling | |
12 | +public class TestAutoconfigure { | |
13 | + public static void main(String args[]) { | |
14 | + ConfigurableApplicationContext context = SpringApplication.run(TestAutoconfigure.class, args); | |
15 | + JdbcTemplateWrapperTenant jdbcTemplate = context.getBean(JdbcTemplateWrapperTenant.class); | |
16 | + System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 1L)); | |
17 | + System.out.println(jdbcTemplate.queryForList("select * from wxorder_order limit 1", 2L)); | |
18 | + System.out.println(jdbcTemplate.queryForList("select * from wxorder_order_express limit 1", 1L)); | |
19 | + } | |
20 | +} | ... | ... |
src/test/resources/META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
0 → 100644
... | ... | @@ -0,0 +1,52 @@ |
1 | + | |
2 | +server.port=80 | |
3 | +server.session.timeout=3600 | |
4 | + | |
5 | +spring.servlet.multipart.max-file-size=10MB | |
6 | +spring.servlet.multipart.max-request-size=20MB | |
7 | + | |
8 | +spring.jackson.time-zone=GMT+8 | |
9 | +spring.jackson.date-format=yyyy-MM-dd HH:mm:ss | |
10 | +spring.mvc.dateFormat = yyyy-MM-dd HH:mm:ss | |
11 | +spring.gson.serialize-nulls=true | |
12 | + | |
13 | +spring.mvc.dispatch-options-request=true | |
14 | + | |
15 | +# shardingspere | |
16 | +spring.shardingsphere.datasource.names=ds0 | |
17 | +spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource | |
18 | +spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver | |
19 | +#spring.shardingsphere.datasource.ds0.url=jdbc:mysql://121.42.142.102:3306/bzyun_wxorder?characterEncoding=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL | |
20 | +#spring.shardingsphere.datasource.ds0.username=dev | |
21 | +#spring.shardingsphere.datasource.ds0.password=taover02 | |
22 | +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 | |
24 | +spring.shardingsphere.datasource.ds0.password=lexi365 | |
25 | +spring.shardingsphere.datasource.ds0.initial-size=10 | |
26 | +spring.shardingsphere.datasource.ds0.max-active=20 | |
27 | +spring.shardingsphere.datasource.ds0.min-idle=5 | |
28 | +spring.shardingsphere.datasource.ds0.max-wait=60000 | |
29 | + | |
30 | +spring.shardingsphere.sharding.tables.wxorder_order.actual-data-nodes=ds0.wxorder_order | |
31 | +spring.shardingsphere.sharding.tables.wxorder_order.database-strategy.inline.sharding-column=id | |
32 | +spring.shardingsphere.sharding.tables.wxorder_order.database-strategy.inline.algorithm-expression=ds0 | |
33 | +spring.shardingsphere.sharding.tables.wxorder_order.table-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingAlgorithmHint | |
34 | +spring.shardingsphere.sharding.tables.wxorder_order.key-generator.column=id | |
35 | +spring.shardingsphere.sharding.tables.wxorder_order.key-generator.type=SNOWFLAKE-SELF | |
36 | + | |
37 | +spring.shardingsphere.sharding.tables.wxorder_order_goods.actual-data-nodes=ds0.wxorder_order_goods | |
38 | +spring.shardingsphere.sharding.tables.wxorder_order_goods.database-strategy.inline.sharding-column=id | |
39 | +spring.shardingsphere.sharding.tables.wxorder_order_goods.database-strategy.inline.algorithm-expression=ds0 | |
40 | +spring.shardingsphere.sharding.tables.wxorder_order.table-strategy.hint.algorithm-class-name=com.taover.repository.shardingsphere.ShardingAlgorithmHint | |
41 | +spring.shardingsphere.sharding.tables.wxorder_order_goods.key-generator.column=id | |
42 | +spring.shardingsphere.sharding.tables.wxorder_order_goods.key-generator.type=SNOWFLAKE-SELF | |
43 | + | |
44 | +taover.sharding.workerId=1 | |
45 | +taover.sharding.maxVibrationOffset=3 | |
46 | +taover.sharding.maxTolerateTimeDifferenceMilliseconds=1000 | |
47 | + | |
48 | +#spring.shardingsphere.sharding.default-key-generator.key-generator.column=id | |
49 | +#spring.shardingsphere.sharding.default-key-generator.type=SNOWFLAKE-SELF | |
50 | +#spring.shardingsphere.sharding.default-key-generator.props.worker.id=1 | |
51 | +#spring.shardingsphere.sharding.default-key-generator.props.max.vibration.offset=3 | |
52 | +#spring.shardingsphere.sharding.default-key-generator.props.max.tolerate.time.difference.milliseconds=1000 | ... | ... |