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,7 +5,6 @@ | ||
5 | * For more details take a look at the Java Libraries chapter in the Gradle | 5 | * For more details take a look at the Java Libraries chapter in the Gradle |
6 | * user guide available at https://docs.gradle.org/4.5.1/userguide/java_library_plugin.html | 6 | * user guide available at https://docs.gradle.org/4.5.1/userguide/java_library_plugin.html |
7 | */ | 7 | */ |
8 | - | ||
9 | plugins { | 8 | plugins { |
10 | // Apply the java-library plugin to add support for Java Library | 9 | // Apply the java-library plugin to add support for Java Library |
11 | id 'java' | 10 | id 'java' |
@@ -19,10 +18,12 @@ group = 'com.taover.repository' | @@ -19,10 +18,12 @@ group = 'com.taover.repository' | ||
19 | mainClassName = 'com.taover.repository.UtilsString' | 18 | mainClassName = 'com.taover.repository.UtilsString' |
20 | 19 | ||
21 | dependencies { | 20 | dependencies { |
21 | + compile("org.springframework.boot:spring-boot-starter:2.0.5.RELEASE") | ||
22 | compile("org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final") | 22 | compile("org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final") |
23 | compile('org.springframework:spring-jdbc:5.1.9.RELEASE') | 23 | compile('org.springframework:spring-jdbc:5.1.9.RELEASE') |
24 | compile('mysql:mysql-connector-java:5.1.47') | 24 | compile('mysql:mysql-connector-java:5.1.47') |
25 | compile('com.alibaba:druid:1.2.4') | 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 | repositories { | 29 | repositories { |
@@ -56,7 +57,7 @@ uploadArchives { | @@ -56,7 +57,7 @@ uploadArchives { | ||
56 | authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD) | 57 | authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD) |
57 | } | 58 | } |
58 | pom.project { | 59 | pom.project { |
59 | - version '2.1.38' | 60 | + version '2.1.44' |
60 | artifactId ARTIFACT_Id | 61 | artifactId ARTIFACT_Id |
61 | groupId GROUP_ID | 62 | groupId GROUP_ID |
62 | packaging TYPE | 63 | packaging TYPE |
gradle.properties
src/main/java/com/taover/repository/CustomJdbcTemplate.java
@@ -18,6 +18,8 @@ import javax.persistence.Table; | @@ -18,6 +18,8 @@ import javax.persistence.Table; | ||
18 | 18 | ||
19 | import org.springframework.jdbc.core.JdbcTemplate; | 19 | import org.springframework.jdbc.core.JdbcTemplate; |
20 | 20 | ||
21 | +import com.taover.repository.util.UtilsSql; | ||
22 | + | ||
21 | /** | 23 | /** |
22 | * | 24 | * |
23 | * @author root | 25 | * @author root |
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenant.java
@@ -16,12 +16,13 @@ import javax.persistence.Id; | @@ -16,12 +16,13 @@ import javax.persistence.Id; | ||
16 | import javax.persistence.Table; | 16 | import javax.persistence.Table; |
17 | 17 | ||
18 | import org.springframework.dao.DataAccessException; | 18 | import org.springframework.dao.DataAccessException; |
19 | -import org.springframework.jdbc.core.JdbcTemplate; | ||
20 | 19 | ||
21 | import com.taover.repository.exception.MultiRowException; | 20 | import com.taover.repository.exception.MultiRowException; |
22 | import com.taover.repository.exception.NoContainTenantException; | 21 | import com.taover.repository.exception.NoContainTenantException; |
23 | import com.taover.repository.exception.NotFoundException; | 22 | import com.taover.repository.exception.NotFoundException; |
24 | import com.taover.repository.exception.ObjectReflectException; | 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,52 +31,47 @@ import com.taover.repository.exception.ObjectReflectException; | ||
30 | * @param <T> | 31 | * @param <T> |
31 | * @param <ID> | 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 | @Resource | 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 | public CustomJdbcTemplateWrapperTenant() throws Exception{ | 52 | public CustomJdbcTemplateWrapperTenant() throws Exception{ |
57 | //获取泛型类Class | 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 | if(annoTable == null){ | 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 | String schema = annoTable.schema(); | 62 | String schema = annoTable.schema(); |
67 | String catalog = annoTable.catalog(); | 63 | String catalog = annoTable.catalog(); |
68 | if(schema != null && !"".equals(schema)){ | 64 | if(schema != null && !"".equals(schema)){ |
69 | - this.dbName = schema; | 65 | + this._dbName = schema; |
70 | }else if(catalog != null && !"".equals(catalog)){ | 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 | for(int i=0; i<declaredFields.length; ++i){ | 75 | for(int i=0; i<declaredFields.length; ++i){ |
80 | Field currField = declaredFields[i]; | 76 | Field currField = declaredFields[i]; |
81 | String fieldName = currField.getName(); | 77 | String fieldName = currField.getName(); |
@@ -83,34 +79,33 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -83,34 +79,33 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
83 | Column annoColumn = (Column)currField.getAnnotation(Column.class); | 79 | Column annoColumn = (Column)currField.getAnnotation(Column.class); |
84 | if(annoId != null){ | 80 | if(annoId != null){ |
85 | if(annoColumn == null){ | 81 | if(annoColumn == null){ |
86 | - idTableFieldName = this.camelToUnderline(fieldName); | 82 | + _idTableFieldName = this.camelToUnderline(fieldName); |
87 | }else{ | 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 | }else{ | 89 | }else{ |
95 | if(annoColumn != null){ | 90 | if(annoColumn != null){ |
96 | String tableFieldName = annoColumn.name(); | 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 | //创建rowmapper | 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,42 +132,6 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
137 | } | 132 | } |
138 | return result.toString(); | 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 | private void appendWhereCondition(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> condition) { | 136 | private void appendWhereCondition(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> condition) { |
178 | if (condition == null || condition.size() == 0) return; | 137 | if (condition == null || condition.size() == 0) return; |
@@ -236,20 +195,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -236,20 +195,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
236 | } | 195 | } |
237 | 196 | ||
238 | private String getTableSql(){ | 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 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { | 203 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { |
245 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 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 | while(beanFieldIter.hasNext()){ | 206 | while(beanFieldIter.hasNext()){ |
248 | String beanFieldName = beanFieldIter.next(); | 207 | String beanFieldName = beanFieldIter.next(); |
249 | - String tableFieldName = this.beanToTableField.get(beanFieldName); | 208 | + String tableFieldName = this._beanToTableField.get(beanFieldName); |
250 | Field beanField = null; | 209 | Field beanField = null; |
251 | try { | 210 | try { |
252 | - beanField = this.tClassInfo.getDeclaredField(beanFieldName); | 211 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); |
253 | beanField.setAccessible(true); | 212 | beanField.setAccessible(true); |
254 | if(beanField.get(entity) == null) { | 213 | if(beanField.get(entity) == null) { |
255 | continue; | 214 | continue; |
@@ -280,7 +239,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -280,7 +239,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
280 | return 0; | 239 | return 0; |
281 | } | 240 | } |
282 | } | 241 | } |
283 | - | 242 | + |
284 | @Override | 243 | @Override |
285 | public T findEntityByID(ID id, Long tenantId) throws NotFoundException { | 244 | public T findEntityByID(ID id, Long tenantId) throws NotFoundException { |
286 | return findEntityByID(id, tenantId, false); | 245 | return findEntityByID(id, tenantId, false); |
@@ -288,16 +247,16 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -288,16 +247,16 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
288 | 247 | ||
289 | @Override | 248 | @Override |
290 | public T findEntityByID(ID id, Long tenantId, boolean isLock) throws NotFoundException { | 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 | if (isLock) { | 252 | if (isLock) { |
294 | sql.append(" FOR UPDATE"); | 253 | sql.append(" FOR UPDATE"); |
295 | } | 254 | } |
296 | try { | 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 | @Override | 262 | @Override |
@@ -333,20 +292,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -333,20 +292,20 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
333 | 292 | ||
334 | @Override | 293 | @Override |
335 | public List<T> findListByCondition(List<Object[]> condition, String sortCondition, Long tenantId){ | 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 | List<Object> list = new ArrayList<Object>(); | 296 | List<Object> list = new ArrayList<Object>(); |
338 | condition.add(new Object[] {"tenant_id", "=", tenantId}); | 297 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
339 | this.appendWhereCondition(sql, new StringBuffer(), list, condition); | 298 | this.appendWhereCondition(sql, new StringBuffer(), list, condition); |
340 | if(sortCondition != null && !sortCondition.equals("")){ | 299 | if(sortCondition != null && !sortCondition.equals("")){ |
341 | sql.append(" " + sortCondition + " "); | 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 | @Override | 305 | @Override |
347 | public List<T> findListBySql(String sqlCondition, Long tenantId){ | 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 | @Override | 311 | @Override |
@@ -356,7 +315,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -356,7 +315,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
356 | 315 | ||
357 | @Override | 316 | @Override |
358 | public Map<String, Object> findPageByCondition(List<Object[]> condition, String sortCondition, int page, int pageSize, Long tenantId){ | 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 | StringBuffer pql = new StringBuffer(sql.toString()); | 319 | StringBuffer pql = new StringBuffer(sql.toString()); |
361 | StringBuffer sqlCount = new StringBuffer("SELECT COUNT(1) rowCount FROM "+this.getTableSql()); | 320 | StringBuffer sqlCount = new StringBuffer("SELECT COUNT(1) rowCount FROM "+this.getTableSql()); |
362 | condition.add(new Object[] {"tenant_id", "=", tenantId}); | 321 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
@@ -376,40 +335,39 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -376,40 +335,39 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
376 | } | 335 | } |
377 | 336 | ||
378 | String pageSql = sql.toString() + " limit ?, ?"; | 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 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | 340 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); |
383 | } | 341 | } |
384 | 342 | ||
385 | @Override | 343 | @Override |
386 | public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize, Long tenantId){ | 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 | StringBuffer sqlCount = new StringBuffer("SELECT count(1) rowCount FROM "+this.getTableSql()+" WHERE tenant_id=" + tenantId + " and " + sqlCondition); | 346 | StringBuffer sqlCount = new StringBuffer("SELECT count(1) rowCount FROM "+this.getTableSql()+" WHERE tenant_id=" + tenantId + " and " + sqlCondition); |
389 | sql.append(" limit ?, ?"); | 347 | sql.append(" limit ?, ?"); |
390 | List<Object> page_list = new ArrayList<Object>(); | 348 | List<Object> page_list = new ArrayList<Object>(); |
391 | page_list.add((page - 1) * pageSize); | 349 | page_list.add((page - 1) * pageSize); |
392 | page_list.add(page * pageSize); | 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 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | 354 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); |
397 | } | 355 | } |
398 | 356 | ||
399 | @Override | 357 | @Override |
400 | - public void addEntity(T entity) { | 358 | + public void addEntity(T entity, Long tenantId) { |
401 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 359 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
402 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); | 360 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); |
403 | List<Object> paramList = new ArrayList<Object>(); | 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 | while(beanFieldIter.hasNext()){ | 364 | while(beanFieldIter.hasNext()){ |
407 | String beanFieldName = beanFieldIter.next(); | 365 | String beanFieldName = beanFieldIter.next(); |
408 | - String tableFieldName = this.beanToTableField.get(beanFieldName); | 366 | + String tableFieldName = this._beanToTableField.get(beanFieldName); |
409 | Field beanField; | 367 | Field beanField; |
410 | Object beanFieldValue = null; | 368 | Object beanFieldValue = null; |
411 | try { | 369 | try { |
412 | - beanField = this.tClassInfo.getDeclaredField(beanFieldName); | 370 | + beanField = this._tClassInfo.getDeclaredField(beanFieldName); |
413 | beanField.setAccessible(true); | 371 | beanField.setAccessible(true); |
414 | beanFieldValue = beanField.get(entity); | 372 | beanFieldValue = beanField.get(entity); |
415 | } catch (Exception e) { | 373 | } catch (Exception e) { |
@@ -423,19 +381,19 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -423,19 +381,19 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
423 | sqlColumnPart.append(" ?,"); | 381 | sqlColumnPart.append(" ?,"); |
424 | paramList.add(beanFieldValue); | 382 | paramList.add(beanFieldValue); |
425 | } | 383 | } |
426 | - | 384 | + |
427 | //执行SQL | 385 | //执行SQL |
428 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | 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 | @Override | 390 | @Override |
433 | - public void addEntityList(List<T> entityList) { | 391 | + public void addEntityList(List<T> entityList, Long tenantId) { |
434 | if(entityList == null || entityList.isEmpty()) { | 392 | if(entityList == null || entityList.isEmpty()) { |
435 | return; | 393 | return; |
436 | } | 394 | } |
437 | //构造SQL语句及Entity Field列表 | 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 | StringBuffer exeSql = new StringBuffer(this.constructUpdateSql(entityList.get(0), beanFieldList)); | 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,15 +422,15 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
464 | } | 422 | } |
465 | exeSql.setCharAt(exeSql.length()-1, ';'); | 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 | @Override | 429 | @Override |
472 | public int deleteEntityByID(ID id, Long tenantId) { | 430 | public int deleteEntityByID(ID id, Long tenantId) { |
473 | StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+" WHERE"); | 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 | @Override | 436 | @Override |
@@ -486,7 +444,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -486,7 +444,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
486 | StringBuffer pql = new StringBuffer(sql.toString()); | 444 | StringBuffer pql = new StringBuffer(sql.toString()); |
487 | condition.add(new Object[] {"tenant_id", "=", tenantId}); | 445 | condition.add(new Object[] {"tenant_id", "=", tenantId}); |
488 | this.appendWhereCondition(sql, pql, list, condition); | 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 | @Override | 450 | @Override |
@@ -494,7 +452,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -494,7 +452,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
494 | if("".equals(sqlCondition.trim())) { | 452 | if("".equals(sqlCondition.trim())) { |
495 | throw new RuntimeException("params[sqlCondition] is empty"); | 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 | @Override | 458 | @Override |
@@ -503,7 +461,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -503,7 +461,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
503 | for(ID id: idList) { | 461 | for(ID id: idList) { |
504 | idSb.append(id); | 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 | @Override | 467 | @Override |
@@ -520,10 +478,10 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -520,10 +478,10 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
520 | List<Object> list = new ArrayList<Object>(); | 478 | List<Object> list = new ArrayList<Object>(); |
521 | this.appendSetSql(sql, pql, list, changeList); | 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 | String updateSql = sql.substring(0, sql.length()-1)+where; | 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 | @Override | 487 | @Override |
@@ -546,7 +504,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -546,7 +504,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
546 | this.appendWhereCondition(where, pwhere, list, condition); | 504 | this.appendWhereCondition(where, pwhere, list, condition); |
547 | 505 | ||
548 | String updateSql = sql.substring(0, sql.length()-1)+where.toString(); | 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 | @Override | 510 | @Override |
@@ -564,17 +522,13 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -564,17 +522,13 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
564 | this.appendSetSql(sql, pql, list, updateObj); | 522 | this.appendSetSql(sql, pql, list, updateObj); |
565 | 523 | ||
566 | String updateSql = sql.toString().substring(0, sql.length()-1) + " WHERE tenant_id="+tenantId+" and "+sqlCondition; | 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 | @Override | 528 | @Override |
571 | public Map<String, Object> getPageData(String coreSql, String orderByPartSql, Integer page, Integer pageSize, Long tenantId){ | 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 | @Override | 534 | @Override |
@@ -589,10 +543,9 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -589,10 +543,9 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
589 | 543 | ||
590 | //执行查询 | 544 | //执行查询 |
591 | List<Map<String, Object>> queryData = new ArrayList<Map<String, Object>>(); | 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 | return UtilsSql.createPage(page, pageSize, Integer.valueOf(countData.get("rowsCount").toString()), queryData); | 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 @@ | @@ -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,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,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,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 | \ No newline at end of file | 0 | \ No newline at end of file |
src/main/java/com/taover/repository/autoconfigure/ShardingSphereKeyGeneratorConfiguration.java
0 → 100644
@@ -0,0 +1,31 @@ | @@ -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 @@ | @@ -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
1 | package com.taover.repository.exception; | 1 | package com.taover.repository.exception; |
2 | 2 | ||
3 | public class NotFoundException extends Exception { | 3 | public class NotFoundException extends Exception { |
4 | - | 4 | + private Exception originError; |
5 | + | ||
6 | + public NotFoundException() {} | ||
7 | + | ||
8 | + public NotFoundException(Exception e) { | ||
9 | + this.originError = e; | ||
10 | + } | ||
5 | } | 11 | } |
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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 @@ | @@ -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 | \ No newline at end of file | 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 @@ | @@ -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 @@ | @@ -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 |