Commit 12322a429b100962350a93643a003441dd2307b3
1 parent
0dd7b201
Exists in
master
and in
2 other branches
repository support tenant wrapper
Showing
8 changed files
with
796 additions
and
5 deletions
Show diff stats
build.gradle
src/main/java/com/taover/repository/CustomJdbcTemplate.java
... | ... | @@ -451,7 +451,7 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { |
451 | 451 | * 批量添加 |
452 | 452 | * @throws Exception |
453 | 453 | */ |
454 | - public int addEntityList(List<T> entityList) throws Exception { | |
454 | + public void addEntityList(List<T> entityList) throws Exception { | |
455 | 455 | if(entityList == null || entityList.isEmpty()) { |
456 | 456 | throw new Exception("entitylist is empty or null"); |
457 | 457 | } |
... | ... | @@ -482,9 +482,6 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { |
482 | 482 | |
483 | 483 | //执行SQL |
484 | 484 | this.jdbcTemplateWrite.update(exeSql.toString(), args.toArray()); |
485 | - | |
486 | - //获取第一个ID | |
487 | - return this.jdbcTemplateWrite.queryForObject("SELECT LAST_INSERT_ID();", BigInteger.class).intValue(); | |
488 | 485 | } |
489 | 486 | |
490 | 487 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { | ... | ... |
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenant.java
0 → 100644
... | ... | @@ -0,0 +1,623 @@ |
1 | +package com.taover.repository; | |
2 | + | |
3 | +import java.io.Serializable; | |
4 | +import java.lang.reflect.Field; | |
5 | +import java.lang.reflect.ParameterizedType; | |
6 | +import java.math.BigDecimal; | |
7 | +import java.util.ArrayList; | |
8 | +import java.util.HashMap; | |
9 | +import java.util.Iterator; | |
10 | +import java.util.List; | |
11 | +import java.util.Map; | |
12 | + | |
13 | +import javax.annotation.Resource; | |
14 | +import javax.persistence.Column; | |
15 | +import javax.persistence.Id; | |
16 | +import javax.persistence.Table; | |
17 | + | |
18 | +import org.springframework.dao.DataAccessException; | |
19 | +import org.springframework.jdbc.core.JdbcTemplate; | |
20 | + | |
21 | +import com.taover.repository.exception.MultiRowException; | |
22 | +import com.taover.repository.exception.NoContainTenantException; | |
23 | +import com.taover.repository.exception.NotFoundException; | |
24 | +import com.taover.repository.exception.ObjectReflectException; | |
25 | + | |
26 | +/** | |
27 | + * | |
28 | + * @author root | |
29 | + * | |
30 | + * @param <T> | |
31 | + * @param <ID> | |
32 | + */ | |
33 | +public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> implements JdbcRepositoryWrapperTenant<T, ID>{ | |
34 | + @Resource | |
35 | + private JdbcTemplate jdbcTemplateWrite; | |
36 | + | |
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; | |
46 | + | |
47 | + public CustomJdbcTemplateRowMapper getCustomJdbcTemplateRowMapper(){ | |
48 | + return this.customJdbcTemplateRowMapper; | |
49 | + } | |
50 | + | |
51 | + public CustomJdbcTemplateWrapperTenant() throws Exception{ | |
52 | + //获取泛型类Class | |
53 | + this.tClassInfo = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]; | |
54 | + | |
55 | + //检查实体声明 | |
56 | + Table annoTable = (Table) tClassInfo.getAnnotation(Table.class); | |
57 | + if(annoTable == null){ | |
58 | + throw new Exception("DAO层初始化失败,失败原因:"+tClassInfo.getName()+"实体类,没有@Table注解指定表名"); | |
59 | + } | |
60 | + this.tableName = annoTable.name(); | |
61 | + String schema = annoTable.schema(); | |
62 | + String catalog = annoTable.catalog(); | |
63 | + if(schema != null && !"".equals(schema)){ | |
64 | + this.dbName = schema; | |
65 | + }else if(catalog != null && !"".equals(catalog)){ | |
66 | + this.dbName = catalog; | |
67 | + } | |
68 | + | |
69 | + //初始化数据 | |
70 | + beanToTableField = new HashMap<String, String>(); | |
71 | + tableToBeanField = new HashMap<String, String>(); | |
72 | + tableFieldNameListGapWithComma = ""; | |
73 | + Field[] declaredFields = tClassInfo.getDeclaredFields(); | |
74 | + for(int i=0; i<declaredFields.length; ++i){ | |
75 | + Field currField = declaredFields[i]; | |
76 | + String fieldName = currField.getName(); | |
77 | + Id annoId = (Id)currField.getAnnotation(Id.class); | |
78 | + Column annoColumn = (Column)currField.getAnnotation(Column.class); | |
79 | + if(annoId != null){ | |
80 | + if(annoColumn == null){ | |
81 | + idTableFieldName = this.camelToUnderline(fieldName); | |
82 | + }else{ | |
83 | + idTableFieldName = annoColumn.name(); | |
84 | + } | |
85 | + idBeanFieldName = fieldName; | |
86 | + tableFieldNameListGapWithComma += idTableFieldName+","; | |
87 | + beanToTableField.put(fieldName, idTableFieldName); | |
88 | + tableToBeanField.put(idTableFieldName, fieldName); | |
89 | + }else{ | |
90 | + if(annoColumn != null){ | |
91 | + String tableFieldName = annoColumn.name(); | |
92 | + tableFieldNameListGapWithComma += tableFieldName+","; | |
93 | + beanToTableField.put(fieldName, tableFieldName); | |
94 | + tableToBeanField.put(tableFieldName, fieldName); | |
95 | + } | |
96 | + } | |
97 | + } | |
98 | + | |
99 | + //检验是否有属性 | |
100 | + if(beanToTableField.isEmpty()){ | |
101 | + throw new Exception("DAO层初始化失败,失败原因:"+this.tClassInfo.getName()+"实体类,没有在实体中找到属性信息"); | |
102 | + } | |
103 | + | |
104 | + //去除逗号 | |
105 | + tableFieldNameListGapWithComma = tableFieldNameListGapWithComma.substring(0, tableFieldNameListGapWithComma.length()-1); | |
106 | + | |
107 | + //创建rowmapper | |
108 | + this.customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper(this.tClassInfo, this.tableToBeanField); | |
109 | + } | |
110 | + | |
111 | + /** | |
112 | + * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> | |
113 | + * 例如:HelloWorld->HELLO_WORLD | |
114 | + * @param name 转换前的驼峰式命名的字符串 | |
115 | + * @return 转换后下划线大写方式命名的字符串 | |
116 | + */ | |
117 | + private String camelToUnderline(String name) { | |
118 | + StringBuilder result = new StringBuilder(); | |
119 | + if (name != null && name.length() > 0) { | |
120 | + // 将第一个字符处理成大写 | |
121 | + result.append(name.substring(0, 1).toUpperCase()); | |
122 | + // 循环处理其余字符 | |
123 | + for (int i = 1; i < name.length(); i++) { | |
124 | + String s = name.substring(i, i + 1); | |
125 | + // 在大写字母前添加下划线 | |
126 | + if (Character.isUpperCase(s.charAt(0)) && Character.isLetter(s.charAt(0))) { | |
127 | + result.append("_"); | |
128 | + } | |
129 | + // 其他字符直接转成大写 | |
130 | + result.append(s.toUpperCase()); | |
131 | + } | |
132 | + } | |
133 | + return result.toString(); | |
134 | + } | |
135 | + | |
136 | + /** | |
137 | + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> | |
138 | + * 例如:HELLO_WORLD->HelloWorld | |
139 | + * @param name 转换前的下划线大写方式命名的字符串 | |
140 | + * @return 转换后的驼峰式命名的字符串 | |
141 | + */ | |
142 | + private String underlineToCamel(String name) { | |
143 | + StringBuilder result = new StringBuilder(); | |
144 | + // 快速检查 | |
145 | + if (name == null || name.isEmpty()) { | |
146 | + // 没必要转换 | |
147 | + return ""; | |
148 | + } else if (!name.contains("_")) { | |
149 | + // 不含下划线,仅将首字母小写 | |
150 | + return name.substring(0, 1).toLowerCase() + name.substring(1); | |
151 | + } | |
152 | + // 用下划线将原始字符串分割 | |
153 | + String camels[] = name.split("_"); | |
154 | + for (String camel : camels) { | |
155 | + // 跳过原始字符串中开头、结尾的下换线或双重下划线 | |
156 | + if (camel.isEmpty()) { | |
157 | + continue; | |
158 | + } | |
159 | + // 处理真正的驼峰片段 | |
160 | + if (result.length() == 0) { | |
161 | + // 第一个驼峰片段,全部字母都小写 | |
162 | + result.append(camel.toLowerCase()); | |
163 | + } else { | |
164 | + // 其他的驼峰片段,首字母大写 | |
165 | + result.append(camel.substring(0, 1).toUpperCase()); | |
166 | + result.append(camel.substring(1).toLowerCase()); | |
167 | + } | |
168 | + } | |
169 | + return result.toString(); | |
170 | + } | |
171 | + | |
172 | + private void appendWhereCondition(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> condition) { | |
173 | + if (condition == null || condition.size() == 0) return; | |
174 | + Object[] con = condition.get(0); | |
175 | + int iLen = condition.size(); | |
176 | + sql.append(" WHERE "); | |
177 | + pql.append(" WHERE "); | |
178 | + sql.append(con[0]); | |
179 | + pql.append(con[0]); | |
180 | + if (null != con[1] && con[1] != "" && con[1] != "useArg[0]") { | |
181 | + sql.append(" " + con[1] + " ?"); | |
182 | + pql.append(" " + con[1] + " " + con[2]); | |
183 | + list.add(con[2]); | |
184 | + } | |
185 | + for (int i = 1; i < iLen; i++) { | |
186 | + con = condition.get(i); | |
187 | + sql.append(" AND "); | |
188 | + pql.append(" AND "); | |
189 | + sql.append(con[0]); | |
190 | + pql.append(con[0]); | |
191 | + if (null == con[1] || "" == con[1] || con[1] == "useArg[0]") continue; | |
192 | + sql.append(" " + con[1] + " ?"); | |
193 | + pql.append(" " + con[1] + " " + con[2]); | |
194 | + list.add(con[2]); | |
195 | + } | |
196 | + } | |
197 | + | |
198 | + private void appendWhereConditionForCount(StringBuffer sql, List<Object[]> condition) { | |
199 | + if (condition == null || condition.size() == 0) return; | |
200 | + Object[] con = condition.get(0); | |
201 | + int iLen = condition.size(); | |
202 | + sql.append(" WHERE "); | |
203 | + sql.append(con[0]); | |
204 | + if (null != con[1] && con[1] != "" && con[1] != "useArg[0]") { | |
205 | + sql.append(" " + con[1] + " ?"); | |
206 | + } | |
207 | + for (int i = 1; i < iLen; i++) { | |
208 | + con = condition.get(i); | |
209 | + sql.append(" AND "); | |
210 | + sql.append(con[0]); | |
211 | + if (null == con[1] || "" == con[1] || con[1] == "useArg[0]") continue; | |
212 | + sql.append(" " + con[1] + " ?"); | |
213 | + } | |
214 | + } | |
215 | + | |
216 | + private void appendSetSql(StringBuffer sql, StringBuffer pql, List<Object> list, List<Object[]> obj) { | |
217 | + for (Object[] arg : obj) { | |
218 | + if (arg.length > 2) { | |
219 | + sql.append(" " + arg[0] + " = " + arg[0] + arg[2] + " ?,"); | |
220 | + pql.append(" " + arg[0] + " = " + arg[0] + arg[2] + arg[1] +","); | |
221 | + list.add(arg[1]); | |
222 | + }else if(arg.length == 2) { | |
223 | + sql.append(" " + arg[0] + " = ?,"); | |
224 | + pql.append(" " + arg[0] + " = " + arg[1] + ","); | |
225 | + list.add(arg[1]); | |
226 | + }else if(arg.length == 1) { | |
227 | + sql.append(" " + arg[0] + ","); | |
228 | + pql.append(" " + arg[0] + ","); | |
229 | + } | |
230 | + } | |
231 | + } | |
232 | + | |
233 | + private String getTableSql(){ | |
234 | + return (this.dbName == null || "".equals(this.dbName.trim()))? | |
235 | + ("`"+this.tableName+"`"): | |
236 | + ("`"+this.dbName+"`.`"+this.tableName+"`"); | |
237 | + } | |
238 | + | |
239 | + private String constructUpdateSql(T entity, List<Field> beanFieldList) { | |
240 | + StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | |
241 | + Iterator<String> beanFieldIter = this.beanToTableField.keySet().iterator(); | |
242 | + while(beanFieldIter.hasNext()){ | |
243 | + String beanFieldName = beanFieldIter.next(); | |
244 | + String tableFieldName = this.beanToTableField.get(beanFieldName); | |
245 | + Field beanField = null; | |
246 | + try { | |
247 | + beanField = this.tClassInfo.getDeclaredField(beanFieldName); | |
248 | + beanField.setAccessible(true); | |
249 | + if(beanField.get(entity) == null) { | |
250 | + continue; | |
251 | + } | |
252 | + } catch (Exception e) { | |
253 | + continue; | |
254 | + } | |
255 | + | |
256 | + if(tableFieldName == null || beanFieldName == null){ | |
257 | + continue; | |
258 | + } | |
259 | + | |
260 | + beanFieldList.add(beanField); | |
261 | + sqlInsertPart.append("`"+tableFieldName+"`,"); | |
262 | + } | |
263 | + return sqlInsertPart.substring(0, sqlInsertPart.length()-1)+")"; | |
264 | + } | |
265 | + | |
266 | + private Object getDefaultValueByFieldType(Field itemField) { | |
267 | + String simpleName = itemField.getType().getSimpleName(); | |
268 | + if("String".equals(simpleName)) { | |
269 | + return ""; | |
270 | + }else if("Date".equals(simpleName) || "Timestamp".equals(simpleName)) { | |
271 | + return "2000-01-01 00:00:00"; | |
272 | + }else if("BigDecimal".equals(simpleName)){ | |
273 | + return BigDecimal.ZERO; | |
274 | + }else { | |
275 | + return 0; | |
276 | + } | |
277 | + } | |
278 | + | |
279 | + @Override | |
280 | + public T findEntityByID(ID id, Long tenantId) throws NotFoundException { | |
281 | + return findEntityByID(id, tenantId, false); | |
282 | + } | |
283 | + | |
284 | + @Override | |
285 | + public T findEntityByID(ID id, Long tenantId, boolean isLock) throws NotFoundException { | |
286 | + StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
287 | + sql.append(" WHERE "+idTableFieldName+" = ? and tenant_id="+tenantId); | |
288 | + if (isLock) { | |
289 | + sql.append(" FOR UPDATE"); | |
290 | + } | |
291 | + try { | |
292 | + return (T) jdbcTemplateWrite.queryForObject(sql.toString(), this.customJdbcTemplateRowMapper, id); | |
293 | + }catch (DataAccessException e) { | |
294 | + throw new NotFoundException(); | |
295 | + } | |
296 | + } | |
297 | + | |
298 | + @Override | |
299 | + public T findEntityByCondition(List<Object[]> condition) throws NotFoundException, MultiRowException, NoContainTenantException { | |
300 | + this.checkTenantInfoFromCondition(condition); | |
301 | + List<T> tempList = findListByCondition(condition); | |
302 | + if(tempList == null || tempList.size() == 0){ | |
303 | + throw new NotFoundException(); | |
304 | + } | |
305 | + if(tempList != null && tempList.size() == 1){ | |
306 | + return tempList.get(0); | |
307 | + }else{ | |
308 | + throw new MultiRowException(); | |
309 | + } | |
310 | + } | |
311 | + | |
312 | + private void checkTenantInfoFromCondition(List<Object[]> condition) throws NoContainTenantException{ | |
313 | + for(Object[] item: condition) { | |
314 | + if(item == null || item.length == 0) { | |
315 | + continue; | |
316 | + } | |
317 | + if(item[0].toString().contains("tenant_id")) { | |
318 | + return; | |
319 | + } | |
320 | + } | |
321 | + throw new NoContainTenantException(); | |
322 | + } | |
323 | + | |
324 | + @Override | |
325 | + public T findEntityBySql(String sqlCondition) throws NotFoundException, MultiRowException, NoContainTenantException { | |
326 | + this.checkTenantInfoFromSql(sqlCondition); | |
327 | + List<T> tempList = findListBySql(sqlCondition); | |
328 | + if(tempList == null || tempList.size() == 0){ | |
329 | + throw new NotFoundException(); | |
330 | + } | |
331 | + if(tempList != null && tempList.size() == 1){ | |
332 | + return tempList.get(0); | |
333 | + }else{ | |
334 | + throw new MultiRowException(); | |
335 | + } | |
336 | + } | |
337 | + | |
338 | + private void checkTenantInfoFromSql(String sqlCondition) throws NoContainTenantException{ | |
339 | + if(sqlCondition.contains("tenant_id")) { | |
340 | + return; | |
341 | + }else { | |
342 | + throw new NoContainTenantException(); | |
343 | + } | |
344 | + } | |
345 | + | |
346 | + @Override | |
347 | + public List<T> findListByCondition(List<Object[]> condition) throws NoContainTenantException { | |
348 | + return findListByCondition(condition, null); | |
349 | + } | |
350 | + | |
351 | + @Override | |
352 | + public List<T> findListByCondition(List<Object[]> condition, String sortCondition) throws NoContainTenantException { | |
353 | + this.checkTenantInfoFromCondition(condition); | |
354 | + StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
355 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
356 | + List<Object> list = new ArrayList<Object>(); | |
357 | + this.appendWhereCondition(sql, pql, list, condition); | |
358 | + if(sortCondition != null && !sortCondition.equals("")){ | |
359 | + sql.append(" " + sortCondition + " "); | |
360 | + pql.append(" " + sortCondition + " "); | |
361 | + } | |
362 | + return (List<T>)jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper, list.toArray()); | |
363 | + } | |
364 | + | |
365 | + @Override | |
366 | + public List<T> findListBySql(String sqlCondition) throws NoContainTenantException { | |
367 | + this.checkTenantInfoFromSql(sqlCondition); | |
368 | + StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE " + sqlCondition); | |
369 | + return (List<T>)jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper); | |
370 | + } | |
371 | + | |
372 | + @Override | |
373 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize) throws NoContainTenantException { | |
374 | + return findPageByCondition(condition, null , page, pageSize); | |
375 | + } | |
376 | + | |
377 | + @Override | |
378 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, String sortCondition, int page, int pageSize) throws NoContainTenantException { | |
379 | + this.checkTenantInfoFromCondition(condition); | |
380 | + StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()); | |
381 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
382 | + StringBuffer sqlCount = new StringBuffer("SELECT COUNT(1) rowCount FROM "+this.getTableSql()); | |
383 | + | |
384 | + List<Object> count_list = new ArrayList<Object>(); | |
385 | + List<Object> page_list = new ArrayList<Object>(); | |
386 | + this.appendWhereConditionForCount(sqlCount, condition); | |
387 | + this.appendWhereCondition(sql, pql, count_list, condition); | |
388 | + for (int i = 0; i < count_list.size(); i++) | |
389 | + page_list.add(count_list.get(i)); | |
390 | + | |
391 | + page_list.add((page - 1) * pageSize); | |
392 | + page_list.add(pageSize); | |
393 | + | |
394 | + if(sortCondition != null && !sortCondition.equals("")){ | |
395 | + sql.append(" " + sortCondition + " "); | |
396 | + pql.append(" " + sortCondition + " "); | |
397 | + } | |
398 | + | |
399 | + String pageSql = sql.toString() + " limit ?, ?"; | |
400 | + | |
401 | + Map<String, Object> totalRowsMap = jdbcTemplateWrite.queryForMap(sqlCount.toString(), count_list.toArray()) ; | |
402 | + List<T> resultList = jdbcTemplateWrite.query(pageSql.toString(), this.customJdbcTemplateRowMapper, page_list.toArray()); | |
403 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | |
404 | + } | |
405 | + | |
406 | + @Override | |
407 | + public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize) throws NoContainTenantException { | |
408 | + this.checkTenantInfoFromSql(sqlCondition); | |
409 | + StringBuffer sql = new StringBuffer("SELECT "+this.tableFieldNameListGapWithComma+" FROM "+this.getTableSql()+" WHERE " + sqlCondition ); | |
410 | + StringBuffer sqlCount = new StringBuffer("SELECT count(1) rowCount FROM "+this.getTableSql()+" WHERE " + sqlCondition); | |
411 | + sql.append(" limit ?, ?"); | |
412 | + List<Object> page_list = new ArrayList<Object>(); | |
413 | + page_list.add((page - 1) * pageSize); | |
414 | + page_list.add(page * pageSize); | |
415 | + | |
416 | + Map<String, Object> totalRowsMap = jdbcTemplateWrite.queryForMap(sqlCount.toString()); | |
417 | + List<T> resultList = jdbcTemplateWrite.query(sql.toString(), this.customJdbcTemplateRowMapper, page_list.toArray()); | |
418 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(totalRowsMap.get("rowCount").toString()), resultList); | |
419 | + } | |
420 | + | |
421 | + @Override | |
422 | + public void addEntity(T entity) { | |
423 | + StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | |
424 | + StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); | |
425 | + List<Object> paramList = new ArrayList<Object>(); | |
426 | + | |
427 | + Iterator<String> beanFieldIter = this.beanToTableField.keySet().iterator(); | |
428 | + while(beanFieldIter.hasNext()){ | |
429 | + String beanFieldName = beanFieldIter.next(); | |
430 | + String tableFieldName = this.beanToTableField.get(beanFieldName); | |
431 | + Field beanField; | |
432 | + Object beanFieldValue = null; | |
433 | + try { | |
434 | + beanField = this.tClassInfo.getDeclaredField(beanFieldName); | |
435 | + beanField.setAccessible(true); | |
436 | + beanFieldValue = beanField.get(entity); | |
437 | + } catch (Exception e) { | |
438 | + e.printStackTrace(); | |
439 | + } | |
440 | + | |
441 | + if(tableFieldName == null || beanFieldName == null || beanFieldValue == null){ | |
442 | + continue; | |
443 | + } | |
444 | + sqlInsertPart.append("`"+tableFieldName+"`,"); | |
445 | + sqlColumnPart.append(" ?,"); | |
446 | + paramList.add(beanFieldValue); | |
447 | + } | |
448 | + | |
449 | + //执行SQL | |
450 | + String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | |
451 | + jdbcTemplateWrite.update(exeSql, paramList.toArray()); | |
452 | + } | |
453 | + | |
454 | + @Override | |
455 | + public void addEntityList(List<T> entityList) { | |
456 | + if(entityList == null || entityList.isEmpty()) { | |
457 | + return; | |
458 | + } | |
459 | + //构造SQL语句及Entity Field列表 | |
460 | + List<Field> beanFieldList = new ArrayList<Field>(this.beanToTableField.size()); | |
461 | + StringBuffer exeSql = new StringBuffer(this.constructUpdateSql(entityList.get(0), beanFieldList)); | |
462 | + | |
463 | + //构造参数信息 | |
464 | + List<Object> args = new ArrayList<Object>(); | |
465 | + exeSql.append(" VALUES"); | |
466 | + for(int itemIndex=0; itemIndex<entityList.size(); ++itemIndex) { | |
467 | + T item = entityList.get(itemIndex); | |
468 | + exeSql.append("("); | |
469 | + for(int i=0; i<beanFieldList.size(); ++i) { | |
470 | + Field itemField = beanFieldList.get(i); | |
471 | + Object itemData = null; | |
472 | + try { | |
473 | + itemData = itemField.get(item); | |
474 | + } catch (Exception e) { | |
475 | + throw new ObjectReflectException(); | |
476 | + } | |
477 | + if(itemData == null) { | |
478 | + args.add(this.getDefaultValueByFieldType(itemField)); | |
479 | + }else { | |
480 | + args.add(itemData); | |
481 | + } | |
482 | + exeSql.append("?,"); | |
483 | + } | |
484 | + exeSql.setCharAt(exeSql.length()-1, ' '); | |
485 | + exeSql.append("),"); | |
486 | + } | |
487 | + exeSql.setCharAt(exeSql.length()-1, ';'); | |
488 | + | |
489 | + //执行SQL | |
490 | + this.jdbcTemplateWrite.update(exeSql.toString(), args.toArray()); | |
491 | + } | |
492 | + | |
493 | + @Override | |
494 | + public int deleteEntityByID(ID id, Long tenantId) { | |
495 | + StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+" WHERE"); | |
496 | + sql.append(" "+this.idTableFieldName+" = ? and tenant_id="+tenantId); | |
497 | + return jdbcTemplateWrite.update(sql.toString(), id); | |
498 | + } | |
499 | + | |
500 | + @Override | |
501 | + public int deleteEntityByCondition(List<Object[]> condition) throws NoContainTenantException { | |
502 | + if (null == condition || condition.size() == 0) { | |
503 | + throw new RuntimeException("params[condition] is empty"); | |
504 | + } | |
505 | + this.checkTenantInfoFromCondition(condition); | |
506 | + | |
507 | + List<Object> list = new ArrayList<Object>(); | |
508 | + StringBuffer sql = new StringBuffer("DELETE FROM "+this.getTableSql()+""); | |
509 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
510 | + this.appendWhereCondition(sql, pql, list, condition); | |
511 | + return jdbcTemplateWrite.update( sql.toString(), list.toArray()); | |
512 | + } | |
513 | + | |
514 | + @Override | |
515 | + public int deleteEntityBySql(String sqlCondition) throws NoContainTenantException { | |
516 | + if("".equals(sqlCondition.trim())) { | |
517 | + throw new RuntimeException("params[sqlCondition] is empty"); | |
518 | + } | |
519 | + this.checkTenantInfoFromSql(sqlCondition); | |
520 | + return jdbcTemplateWrite.update( "DELETE FROM "+this.getTableSql()+" WHERE " + sqlCondition); | |
521 | + } | |
522 | + | |
523 | + @Override | |
524 | + public int deleteEntityList(List<ID> idList, Long tenantId) throws NoContainTenantException { | |
525 | + StringBuffer idSb = new StringBuffer(); | |
526 | + for(ID id: idList) { | |
527 | + idSb.append(id); | |
528 | + } | |
529 | + return this.deleteEntityBySql(this.idTableFieldName + " in ("+idSb.toString().substring(0, idSb.length()-1)+") and tenant_id="+tenantId); | |
530 | + } | |
531 | + | |
532 | + @Override | |
533 | + public int updateEntityById(List<Object[]> changeList, ID id, Long tenantId) { | |
534 | + if(null == id){ | |
535 | + throw new RuntimeException("params[id] is null"); | |
536 | + } | |
537 | + if (null == changeList || changeList.size() == 0) { | |
538 | + throw new RuntimeException("params[changeList] is empty"); | |
539 | + } | |
540 | + | |
541 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | |
542 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
543 | + List<Object> list = new ArrayList<Object>(); | |
544 | + this.appendSetSql(sql, pql, list, changeList); | |
545 | + | |
546 | + String where = " WHERE "+this.idTableFieldName+"=? and tenant_id="+tenantId; | |
547 | + String updateSql = sql.substring(0, sql.length()-1)+where; | |
548 | + list.add(id); | |
549 | + return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
550 | + } | |
551 | + | |
552 | + @Override | |
553 | + public int updateEntityByCondition(List<Object[]> updateObj, List<Object[]> condition) throws NoContainTenantException { | |
554 | + if (null == updateObj || updateObj.size() == 0) { | |
555 | + throw new RuntimeException("params[updateObj] is empty"); | |
556 | + } | |
557 | + if (null == condition || condition.size() == 0) { | |
558 | + throw new RuntimeException("params[condition] is empty"); | |
559 | + } | |
560 | + this.checkTenantInfoFromCondition(condition); | |
561 | + | |
562 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | |
563 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
564 | + List<Object> list = new ArrayList<Object>(); | |
565 | + this.appendSetSql(sql, pql, list, updateObj); | |
566 | + | |
567 | + StringBuffer where = new StringBuffer(""); | |
568 | + StringBuffer pwhere = new StringBuffer(""); | |
569 | + this.appendWhereCondition(where, pwhere, list, condition); | |
570 | + | |
571 | + String updateSql = sql.substring(0, sql.length()-1)+where.toString(); | |
572 | + return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
573 | + } | |
574 | + | |
575 | + @Override | |
576 | + public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition) throws NoContainTenantException { | |
577 | + if (null == updateObj || updateObj.size() == 0) { | |
578 | + throw new RuntimeException("params[updateObj] is empty"); | |
579 | + } | |
580 | + if ("".equals(sqlCondition)) { | |
581 | + throw new RuntimeException("params[sqlCondition] is empty"); | |
582 | + } | |
583 | + this.checkTenantInfoFromSql(sqlCondition); | |
584 | + | |
585 | + StringBuffer sql = new StringBuffer("UPDATE "+this.getTableSql()+" SET"); | |
586 | + StringBuffer pql = new StringBuffer(sql.toString()); | |
587 | + List<Object> list = new ArrayList<Object>(); | |
588 | + this.appendSetSql(sql, pql, list, updateObj); | |
589 | + | |
590 | + String updateSql = sql.toString().substring(0, sql.length()-1) + " WHERE "+sqlCondition; | |
591 | + return jdbcTemplateWrite.update(updateSql, list.toArray()); | |
592 | + } | |
593 | + | |
594 | + @Override | |
595 | + public Map<String, Object> getPageData(String coreSql, String orderByPartSql, Integer page, Integer pageSize) throws NoContainTenantException { | |
596 | + this.checkTenantInfoFromSql(coreSql); | |
597 | + try { | |
598 | + String[] splitedSql = UtilsSql.splitCoreSql(coreSql); | |
599 | + return this.getPageData(splitedSql[0], splitedSql[1], orderByPartSql, page, pageSize); | |
600 | + }catch (Exception e) { | |
601 | + return UtilsSql.createPage(page, pageSize, 0, new ArrayList<Object>()); | |
602 | + } | |
603 | + } | |
604 | + | |
605 | + @Override | |
606 | + public Map<String, Object> getPageData(String selectSql, String fromAndWhereSql, String orderByPartSql, Integer page, Integer pageSize) throws NoContainTenantException { | |
607 | + this.checkTenantInfoFromSql(fromAndWhereSql); | |
608 | + | |
609 | + //构造查询语句 | |
610 | + String querySql = selectSql+" "+fromAndWhereSql+" "+orderByPartSql+" "+UtilsSql.getLimitCondition(page, pageSize); | |
611 | + | |
612 | + //构造统计计数语句 | |
613 | + String countSql = "select count(*) rowsCount from ( select 1 "+fromAndWhereSql+" ) t "; | |
614 | + | |
615 | + //执行查询 | |
616 | + List<Map<String, Object>> queryData = new ArrayList<Map<String, Object>>(); | |
617 | + Map<String, Object> countData = new HashMap<String, Object>(); | |
618 | + queryData = this.jdbcTemplateWrite.queryForList(querySql); | |
619 | + countData = this.jdbcTemplateWrite.queryForMap(countSql); | |
620 | + return UtilsSql.createPage(page, pageSize, Integer.valueOf(countData.get("rowsCount").toString()), queryData); | |
621 | + } | |
622 | + | |
623 | +} | ... | ... |
src/main/java/com/taover/repository/JdbcRepositoryWrapperTenant.java
0 → 100644
... | ... | @@ -0,0 +1,152 @@ |
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) throws NotFoundException,MultiRowException,NoContainTenantException; | |
31 | + | |
32 | + /** | |
33 | + * 根据条件sql查询 | |
34 | + * sqlCondition 为where 后面的条件。 | |
35 | + */ | |
36 | + public T findEntityBySql(String sqlCondition) throws NotFoundException,MultiRowException,NoContainTenantException; | |
37 | + | |
38 | + /** | |
39 | + * 根据条件List<Object[]>查询 | |
40 | + * Object[]数组长度是3 | |
41 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
42 | + */ | |
43 | + public List<T> findListByCondition(List<Object[]> condition) throws NoContainTenantException; | |
44 | + | |
45 | + /** | |
46 | + * 根据条件List<Object[]>查询 | |
47 | + * Object[]数组长度是3 | |
48 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
49 | + */ | |
50 | + public List<T> findListByCondition(List<Object[]> condition, String sortCondition) throws NoContainTenantException; | |
51 | + | |
52 | + /** | |
53 | + * 根据条件sql查询 | |
54 | + * sqlCondition 为where 后面的条件。 | |
55 | + */ | |
56 | + public List<T> findListBySql(String sqlCondition) throws NoContainTenantException; | |
57 | + | |
58 | + /** | |
59 | + * 按条件分页查询 | |
60 | + * Object[]数组长度是3 | |
61 | + * Object[], 第一个参数是列名,第二个参数是操作符,第三个参数是查询条件的值。 | |
62 | + */ | |
63 | + public Map<String, Object> findPageByCondition(List<Object[]> condition, int page, int pageSize) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
73 | + | |
74 | + /** | |
75 | + * 按sql分页查询, sqlCondition为where 后条件sql | |
76 | + */ | |
77 | + public Map<String, Object> findPageBySql(String sqlCondition, int page, int pageSize) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
108 | + | |
109 | + /** | |
110 | + * 根据list对象逐个删除。 | |
111 | + * @throws NoContainTenantException | |
112 | + */ | |
113 | + public int deleteEntityList(List<ID> idList, Long tenantId) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
125 | + | |
126 | + /** | |
127 | + * List<Object[]> updateObj 要修改成的值,数组长度为2,第一个值为列名,第二个值是要改成的值。 | |
128 | + * String sqlCondition 修改的条件。 | |
129 | + */ | |
130 | + public int updateEntityBySql(List<Object[]> updateObj, String sqlCondition) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
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) throws NoContainTenantException; | |
152 | +} | ... | ... |
src/main/java/com/taover/repository/exception/MultiRowException.java
0 → 100644
src/main/java/com/taover/repository/exception/NoContainTenantException.java
0 → 100644
src/main/java/com/taover/repository/exception/NotFoundException.java
0 → 100644
src/main/java/com/taover/repository/exception/ObjectReflectException.java
0 → 100644