Commit 75c80abe5310ae6c7dceccd831616d9f9627aa57
1 parent
bc66f2ad
Exists in
master
and in
1 other branch
1.upgrade dao to fetch insert id by jdbctemplate keyholder
Showing
6 changed files
with
271 additions
and
25 deletions
Show diff stats
src/main/java/com/taover/repository/CustomJdbcTemplate.java
| @@ -5,6 +5,9 @@ import java.lang.reflect.Field; | @@ -5,6 +5,9 @@ import java.lang.reflect.Field; | ||
| 5 | import java.lang.reflect.ParameterizedType; | 5 | import java.lang.reflect.ParameterizedType; |
| 6 | import java.math.BigDecimal; | 6 | import java.math.BigDecimal; |
| 7 | import java.math.BigInteger; | 7 | import java.math.BigInteger; |
| 8 | +import java.sql.Connection; | ||
| 9 | +import java.sql.PreparedStatement; | ||
| 10 | +import java.sql.SQLException; | ||
| 8 | import java.util.ArrayList; | 11 | import java.util.ArrayList; |
| 9 | import java.util.HashMap; | 12 | import java.util.HashMap; |
| 10 | import java.util.Iterator; | 13 | import java.util.Iterator; |
| @@ -16,7 +19,13 @@ import javax.persistence.Column; | @@ -16,7 +19,13 @@ import javax.persistence.Column; | ||
| 16 | import javax.persistence.Id; | 19 | import javax.persistence.Id; |
| 17 | import javax.persistence.Table; | 20 | import javax.persistence.Table; |
| 18 | 21 | ||
| 22 | +import org.springframework.dao.DataRetrievalFailureException; | ||
| 23 | +import org.springframework.jdbc.core.ArgumentPreparedStatementSetter; | ||
| 19 | import org.springframework.jdbc.core.JdbcTemplate; | 24 | import org.springframework.jdbc.core.JdbcTemplate; |
| 25 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
| 26 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
| 27 | +import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
| 28 | +import org.springframework.jdbc.support.KeyHolder; | ||
| 20 | 29 | ||
| 21 | import com.taover.repository.mapper.CustomJdbcTemplateRowMapper; | 30 | import com.taover.repository.mapper.CustomJdbcTemplateRowMapper; |
| 22 | import com.taover.repository.util.UtilsSql; | 31 | import com.taover.repository.util.UtilsSql; |
| @@ -43,6 +52,7 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | @@ -43,6 +52,7 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | ||
| 43 | private String tableName; | 52 | private String tableName; |
| 44 | private Class<T> tClassInfo; | 53 | private Class<T> tClassInfo; |
| 45 | private CustomJdbcTemplateRowMapper customJdbcTemplateRowMapper; | 54 | private CustomJdbcTemplateRowMapper customJdbcTemplateRowMapper; |
| 55 | + private KeyHolder keyHolder; | ||
| 46 | 56 | ||
| 47 | public CustomJdbcTemplateRowMapper getCustomJdbcTemplateRowMapper(){ | 57 | public CustomJdbcTemplateRowMapper getCustomJdbcTemplateRowMapper(){ |
| 48 | return this.customJdbcTemplateRowMapper; | 58 | return this.customJdbcTemplateRowMapper; |
| @@ -112,6 +122,9 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | @@ -112,6 +122,9 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | ||
| 112 | 122 | ||
| 113 | //创建rowmapper | 123 | //创建rowmapper |
| 114 | this.customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper(this.tClassInfo, this.tableToBeanField); | 124 | this.customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper(this.tClassInfo, this.tableToBeanField); |
| 125 | + | ||
| 126 | + //主键ID保存 | ||
| 127 | + this.keyHolder = new GeneratedKeyHolder(); | ||
| 115 | } | 128 | } |
| 116 | 129 | ||
| 117 | /** | 130 | /** |
| @@ -412,7 +425,7 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | @@ -412,7 +425,7 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | ||
| 412 | /** | 425 | /** |
| 413 | * 添加 | 426 | * 添加 |
| 414 | */ | 427 | */ |
| 415 | - public BigInteger addEntityForAutoincrementId(T entity) { | 428 | + public Number addEntityForAutoincrementId(T entity) { |
| 416 | StringBuffer sqlForLog = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 429 | StringBuffer sqlForLog = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
| 417 | StringBuffer sqlValueForLog = new StringBuffer(") VALUES ("); | 430 | StringBuffer sqlValueForLog = new StringBuffer(") VALUES ("); |
| 418 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 431 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
| @@ -450,17 +463,26 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | @@ -450,17 +463,26 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | ||
| 450 | //UtilsLog.infoForMessage(sqlForLog.toString(), this.getClass()); | 463 | //UtilsLog.infoForMessage(sqlForLog.toString(), this.getClass()); |
| 451 | 464 | ||
| 452 | //执行SQL | 465 | //执行SQL |
| 453 | - String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | ||
| 454 | - jdbcTemplateWrite.update(exeSql, paramList.toArray()); | ||
| 455 | - Map<String, Object> lastInsertIdMap = jdbcTemplateWrite.queryForMap("SELECT LAST_INSERT_ID() lastInsertId"); | ||
| 456 | - return (BigInteger)lastInsertIdMap.get("lastInsertId"); | 466 | + String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; |
| 467 | + jdbcTemplateWrite.update(new PreparedStatementCreator() { | ||
| 468 | + @Override | ||
| 469 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 470 | + PreparedStatement stat = con.prepareStatement(exeSql, new String[] {idTableFieldName}); | ||
| 471 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(paramList.toArray()); | ||
| 472 | + setter.setValues(stat); | ||
| 473 | + return stat; | ||
| 474 | + } | ||
| 475 | + | ||
| 476 | + }, keyHolder); | ||
| 477 | + | ||
| 478 | + return keyHolder.getKey(); | ||
| 457 | } | 479 | } |
| 458 | 480 | ||
| 459 | /** | 481 | /** |
| 460 | * 批量添加 | 482 | * 批量添加 |
| 461 | * @throws Exception | 483 | * @throws Exception |
| 462 | */ | 484 | */ |
| 463 | - public void addEntityList(List<T> entityList) throws Exception { | 485 | + public List<Number> addEntityList(List<T> entityList) throws Exception { |
| 464 | if(entityList == null || entityList.isEmpty()) { | 486 | if(entityList == null || entityList.isEmpty()) { |
| 465 | throw new Exception("entitylist is empty or null"); | 487 | throw new Exception("entitylist is empty or null"); |
| 466 | } | 488 | } |
| @@ -489,8 +511,41 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | @@ -489,8 +511,41 @@ public class CustomJdbcTemplate<T, ID extends Serializable> { | ||
| 489 | } | 511 | } |
| 490 | exeSql.setCharAt(exeSql.length()-1, ';'); | 512 | exeSql.setCharAt(exeSql.length()-1, ';'); |
| 491 | 513 | ||
| 492 | - //执行SQL | ||
| 493 | - this.jdbcTemplateWrite.update(exeSql.toString(), args.toArray()); | 514 | + //调用更新接口 |
| 515 | + jdbcTemplateWrite.update(new PreparedStatementCreator() { | ||
| 516 | + @Override | ||
| 517 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 518 | + PreparedStatement stat = con.prepareStatement(exeSql.toString(), new String[] {idTableFieldName}); | ||
| 519 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(args.toArray()); | ||
| 520 | + setter.setValues(stat); | ||
| 521 | + return stat; | ||
| 522 | + } | ||
| 523 | + | ||
| 524 | + }, keyHolder); | ||
| 525 | + | ||
| 526 | + //处理结果数据 | ||
| 527 | + List<Map<String, Object>> data = keyHolder.getKeyList(); | ||
| 528 | + if(data.size() != entityList.size()) { | ||
| 529 | + throw new Exception("param entity size not equal return generate key list size"); | ||
| 530 | + } | ||
| 531 | + List<Number> dataT = new ArrayList<Number>(data.size()); | ||
| 532 | + for(Map<String, Object> item: data) { | ||
| 533 | + Iterator<Object> keyIter = item.values().iterator(); | ||
| 534 | + if (keyIter.hasNext()) { | ||
| 535 | + Object key = keyIter.next(); | ||
| 536 | + if (!(key instanceof Number)) { | ||
| 537 | + throw new DataRetrievalFailureException( | ||
| 538 | + "The generated key is not of a supported numeric type. " + | ||
| 539 | + "Unable to cast [" + (key != null ? key.getClass().getName() : null) + | ||
| 540 | + "] to [" + Number.class.getName() + "]"); | ||
| 541 | + } | ||
| 542 | + dataT.add((Number)key); | ||
| 543 | + }else { | ||
| 544 | + throw new DataRetrievalFailureException("Unable to retrieve the generated key. " + | ||
| 545 | + "Check that the table has an identity column enabled."); | ||
| 546 | + } | ||
| 547 | + } | ||
| 548 | + return dataT; | ||
| 494 | } | 549 | } |
| 495 | 550 | ||
| 496 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { | 551 | private String constructUpdateSql(T entity, List<Field> beanFieldList) { |
src/main/java/com/taover/repository/CustomJdbcTemplateBroadcast.java
| @@ -4,7 +4,11 @@ import java.io.Serializable; | @@ -4,7 +4,11 @@ import java.io.Serializable; | ||
| 4 | import java.lang.reflect.Field; | 4 | import java.lang.reflect.Field; |
| 5 | import java.lang.reflect.ParameterizedType; | 5 | import java.lang.reflect.ParameterizedType; |
| 6 | import java.math.BigDecimal; | 6 | import java.math.BigDecimal; |
| 7 | +import java.sql.Connection; | ||
| 8 | +import java.sql.PreparedStatement; | ||
| 9 | +import java.sql.SQLException; | ||
| 7 | import java.util.ArrayList; | 10 | import java.util.ArrayList; |
| 11 | +import java.util.Collections; | ||
| 8 | import java.util.HashMap; | 12 | import java.util.HashMap; |
| 9 | import java.util.Iterator; | 13 | import java.util.Iterator; |
| 10 | import java.util.List; | 14 | import java.util.List; |
| @@ -16,6 +20,12 @@ import javax.persistence.Id; | @@ -16,6 +20,12 @@ import javax.persistence.Id; | ||
| 16 | import javax.persistence.Table; | 20 | import javax.persistence.Table; |
| 17 | 21 | ||
| 18 | import org.springframework.dao.DataAccessException; | 22 | import org.springframework.dao.DataAccessException; |
| 23 | +import org.springframework.dao.DataRetrievalFailureException; | ||
| 24 | +import org.springframework.jdbc.core.ArgumentPreparedStatementSetter; | ||
| 25 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
| 26 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
| 27 | +import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
| 28 | +import org.springframework.jdbc.support.KeyHolder; | ||
| 19 | 29 | ||
| 20 | import com.taover.repository.exception.MultiRowException; | 30 | import com.taover.repository.exception.MultiRowException; |
| 21 | import com.taover.repository.exception.NoContainTenantException; | 31 | import com.taover.repository.exception.NoContainTenantException; |
| @@ -44,6 +54,7 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | @@ -44,6 +54,7 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | ||
| 44 | private String _tableName; | 54 | private String _tableName; |
| 45 | private Class<T> _tClassInfo; | 55 | private Class<T> _tClassInfo; |
| 46 | private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; | 56 | private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; |
| 57 | + private KeyHolder _keyHolder; | ||
| 47 | 58 | ||
| 48 | public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ | 59 | public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ |
| 49 | return this._customJdbcTemplateRowMapper; | 60 | return this._customJdbcTemplateRowMapper; |
| @@ -107,6 +118,9 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | @@ -107,6 +118,9 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | ||
| 107 | 118 | ||
| 108 | //创建rowmapper | 119 | //创建rowmapper |
| 109 | this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); | 120 | this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); |
| 121 | + | ||
| 122 | + //主键ID保存 | ||
| 123 | + this._keyHolder = new GeneratedKeyHolder(); | ||
| 110 | } | 124 | } |
| 111 | 125 | ||
| 112 | /** | 126 | /** |
| @@ -354,7 +368,7 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | @@ -354,7 +368,7 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | ||
| 354 | } | 368 | } |
| 355 | 369 | ||
| 356 | @Override | 370 | @Override |
| 357 | - public void addEntity(T entity) { | 371 | + public Number addEntity(T entity) { |
| 358 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 372 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
| 359 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); | 373 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); |
| 360 | List<Object> paramList = new ArrayList<Object>(); | 374 | List<Object> paramList = new ArrayList<Object>(); |
| @@ -383,13 +397,24 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | @@ -383,13 +397,24 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | ||
| 383 | 397 | ||
| 384 | //执行SQL | 398 | //执行SQL |
| 385 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | 399 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; |
| 386 | - _jdbcTemplateBroadcast.update(exeSql, new String[] {this._tableName}, paramList.toArray()); | 400 | + _jdbcTemplateBroadcast.update(new PreparedStatementCreator() { |
| 401 | + @Override | ||
| 402 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 403 | + PreparedStatement stat = con.prepareStatement(exeSql, new String[] {_idTableFieldName}); | ||
| 404 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(paramList.toArray()); | ||
| 405 | + setter.setValues(stat); | ||
| 406 | + return stat; | ||
| 407 | + } | ||
| 408 | + | ||
| 409 | + }, _keyHolder, new String[] {this._tableName}); | ||
| 410 | + | ||
| 411 | + return _keyHolder.getKey(); | ||
| 387 | } | 412 | } |
| 388 | 413 | ||
| 389 | @Override | 414 | @Override |
| 390 | - public void addEntityList(List<T> entityList) { | 415 | + public List<Number> addEntityList(List<T> entityList) throws Exception { |
| 391 | if(entityList == null || entityList.isEmpty()) { | 416 | if(entityList == null || entityList.isEmpty()) { |
| 392 | - return; | 417 | + return Collections.EMPTY_LIST; |
| 393 | } | 418 | } |
| 394 | //构造SQL语句及Entity Field列表 | 419 | //构造SQL语句及Entity Field列表 |
| 395 | List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); | 420 | List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); |
| @@ -421,8 +446,41 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | @@ -421,8 +446,41 @@ public class CustomJdbcTemplateBroadcast<T, ID extends Serializable> implements | ||
| 421 | } | 446 | } |
| 422 | exeSql.setCharAt(exeSql.length()-1, ';'); | 447 | exeSql.setCharAt(exeSql.length()-1, ';'); |
| 423 | 448 | ||
| 424 | - //执行SQL | ||
| 425 | - this._jdbcTemplateBroadcast.update(exeSql.toString(), new String[] {this._tableName}, args.toArray()); | 449 | + //调用更新接口 |
| 450 | + _jdbcTemplateBroadcast.update(new PreparedStatementCreator() { | ||
| 451 | + @Override | ||
| 452 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 453 | + PreparedStatement stat = con.prepareStatement(exeSql.toString(), new String[] {_idTableFieldName}); | ||
| 454 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(args.toArray()); | ||
| 455 | + setter.setValues(stat); | ||
| 456 | + return stat; | ||
| 457 | + } | ||
| 458 | + | ||
| 459 | + }, _keyHolder, new String[] {this._tableName}); | ||
| 460 | + | ||
| 461 | + //处理结果数据 | ||
| 462 | + List<Map<String, Object>> data = _keyHolder.getKeyList(); | ||
| 463 | + if(data.size() != entityList.size()) { | ||
| 464 | + throw new Exception("param entity size not equal return generate key list size"); | ||
| 465 | + } | ||
| 466 | + List<Number> dataT = new ArrayList<Number>(data.size()); | ||
| 467 | + for(Map<String, Object> item: data) { | ||
| 468 | + Iterator<Object> keyIter = item.values().iterator(); | ||
| 469 | + if (keyIter.hasNext()) { | ||
| 470 | + Object key = keyIter.next(); | ||
| 471 | + if (!(key instanceof Number)) { | ||
| 472 | + throw new DataRetrievalFailureException( | ||
| 473 | + "The generated key is not of a supported numeric type. " + | ||
| 474 | + "Unable to cast [" + (key != null ? key.getClass().getName() : null) + | ||
| 475 | + "] to [" + Number.class.getName() + "]"); | ||
| 476 | + } | ||
| 477 | + dataT.add((Number)key); | ||
| 478 | + }else { | ||
| 479 | + throw new DataRetrievalFailureException("Unable to retrieve the generated key. " + | ||
| 480 | + "Check that the table has an identity column enabled."); | ||
| 481 | + } | ||
| 482 | + } | ||
| 483 | + return dataT; | ||
| 426 | } | 484 | } |
| 427 | 485 | ||
| 428 | @Override | 486 | @Override |
src/main/java/com/taover/repository/CustomJdbcTemplateBroadcastInterface.java
| @@ -79,13 +79,13 @@ public interface CustomJdbcTemplateBroadcastInterface<T, ID extends Serializable | @@ -79,13 +79,13 @@ public interface CustomJdbcTemplateBroadcastInterface<T, ID extends Serializable | ||
| 79 | /** | 79 | /** |
| 80 | * 添加 | 80 | * 添加 |
| 81 | */ | 81 | */ |
| 82 | - public void addEntity(T entity); | 82 | + public Number addEntity(T entity); |
| 83 | 83 | ||
| 84 | /** | 84 | /** |
| 85 | * 批量添加 | 85 | * 批量添加 |
| 86 | * @throws Exception | 86 | * @throws Exception |
| 87 | */ | 87 | */ |
| 88 | - public void addEntityList(List<T> entityList); | 88 | + public List<Number> addEntityList(List<T> entityList) throws Exception; |
| 89 | 89 | ||
| 90 | /** | 90 | /** |
| 91 | * 按ID删除 | 91 | * 按ID删除 |
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenant.java
| @@ -4,7 +4,11 @@ import java.io.Serializable; | @@ -4,7 +4,11 @@ import java.io.Serializable; | ||
| 4 | import java.lang.reflect.Field; | 4 | import java.lang.reflect.Field; |
| 5 | import java.lang.reflect.ParameterizedType; | 5 | import java.lang.reflect.ParameterizedType; |
| 6 | import java.math.BigDecimal; | 6 | import java.math.BigDecimal; |
| 7 | +import java.sql.Connection; | ||
| 8 | +import java.sql.PreparedStatement; | ||
| 9 | +import java.sql.SQLException; | ||
| 7 | import java.util.ArrayList; | 10 | import java.util.ArrayList; |
| 11 | +import java.util.Collections; | ||
| 8 | import java.util.HashMap; | 12 | import java.util.HashMap; |
| 9 | import java.util.Iterator; | 13 | import java.util.Iterator; |
| 10 | import java.util.List; | 14 | import java.util.List; |
| @@ -16,6 +20,12 @@ import javax.persistence.Id; | @@ -16,6 +20,12 @@ import javax.persistence.Id; | ||
| 16 | import javax.persistence.Table; | 20 | import javax.persistence.Table; |
| 17 | 21 | ||
| 18 | import org.springframework.dao.DataAccessException; | 22 | import org.springframework.dao.DataAccessException; |
| 23 | +import org.springframework.dao.DataRetrievalFailureException; | ||
| 24 | +import org.springframework.jdbc.core.ArgumentPreparedStatementSetter; | ||
| 25 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
| 26 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
| 27 | +import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
| 28 | +import org.springframework.jdbc.support.KeyHolder; | ||
| 19 | 29 | ||
| 20 | import com.taover.repository.exception.MultiRowException; | 30 | import com.taover.repository.exception.MultiRowException; |
| 21 | import com.taover.repository.exception.NoContainTenantException; | 31 | import com.taover.repository.exception.NoContainTenantException; |
| @@ -44,6 +54,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -44,6 +54,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
| 44 | private String _tableName; | 54 | private String _tableName; |
| 45 | private Class<T> _tClassInfo; | 55 | private Class<T> _tClassInfo; |
| 46 | private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; | 56 | private CustomJdbcTemplateRowMapper<T> _customJdbcTemplateRowMapper; |
| 57 | + private KeyHolder _keyHolder; | ||
| 47 | 58 | ||
| 48 | public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ | 59 | public CustomJdbcTemplateRowMapper<T> getCustomJdbcTemplateRowMapper(){ |
| 49 | return this._customJdbcTemplateRowMapper; | 60 | return this._customJdbcTemplateRowMapper; |
| @@ -107,6 +118,9 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -107,6 +118,9 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
| 107 | 118 | ||
| 108 | //创建rowmapper | 119 | //创建rowmapper |
| 109 | this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); | 120 | this._customJdbcTemplateRowMapper = new CustomJdbcTemplateRowMapper<T>(this._tClassInfo, this._tableToBeanField); |
| 121 | + | ||
| 122 | + //主键ID保存 | ||
| 123 | + this._keyHolder = new GeneratedKeyHolder(); | ||
| 110 | } | 124 | } |
| 111 | 125 | ||
| 112 | /** | 126 | /** |
| @@ -356,7 +370,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -356,7 +370,7 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
| 356 | } | 370 | } |
| 357 | 371 | ||
| 358 | @Override | 372 | @Override |
| 359 | - public void addEntity(T entity, Long tenantId) { | 373 | + public Number addEntity(T entity, Long tenantId) { |
| 360 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); | 374 | StringBuffer sqlInsertPart = new StringBuffer("INSERT INTO "+this.getTableSql()+"("); |
| 361 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); | 375 | StringBuffer sqlColumnPart = new StringBuffer(") VALUES ("); |
| 362 | List<Object> paramList = new ArrayList<Object>(); | 376 | List<Object> paramList = new ArrayList<Object>(); |
| @@ -385,13 +399,24 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -385,13 +399,24 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
| 385 | 399 | ||
| 386 | //执行SQL | 400 | //执行SQL |
| 387 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; | 401 | String exeSql = sqlInsertPart.substring(0, sqlInsertPart.length()-1)+sqlColumnPart.substring(0, sqlColumnPart.length()-1)+")"; |
| 388 | - _jdbcTemplateWrapperTenant.update(exeSql, tenantId, paramList.toArray()); | 402 | + _jdbcTemplateWrapperTenant.update(new PreparedStatementCreator() { |
| 403 | + @Override | ||
| 404 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 405 | + PreparedStatement stat = con.prepareStatement(exeSql, new String[] {_idTableFieldName}); | ||
| 406 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(paramList.toArray()); | ||
| 407 | + setter.setValues(stat); | ||
| 408 | + return stat; | ||
| 409 | + } | ||
| 410 | + | ||
| 411 | + }, _keyHolder, tenantId); | ||
| 412 | + | ||
| 413 | + return _keyHolder.getKey(); | ||
| 389 | } | 414 | } |
| 390 | 415 | ||
| 391 | @Override | 416 | @Override |
| 392 | - public void addEntityList(List<T> entityList, Long tenantId) { | 417 | + public List<Number> addEntityList(List<T> entityList, Long tenantId) throws Exception { |
| 393 | if(entityList == null || entityList.isEmpty()) { | 418 | if(entityList == null || entityList.isEmpty()) { |
| 394 | - return; | 419 | + return Collections.EMPTY_LIST; |
| 395 | } | 420 | } |
| 396 | //构造SQL语句及Entity Field列表 | 421 | //构造SQL语句及Entity Field列表 |
| 397 | List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); | 422 | List<Field> beanFieldList = new ArrayList<Field>(this._beanToTableField.size()); |
| @@ -423,8 +448,41 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | @@ -423,8 +448,41 @@ public class CustomJdbcTemplateWrapperTenant<T, ID extends Serializable> impleme | ||
| 423 | } | 448 | } |
| 424 | exeSql.setCharAt(exeSql.length()-1, ';'); | 449 | exeSql.setCharAt(exeSql.length()-1, ';'); |
| 425 | 450 | ||
| 426 | - //执行SQL | ||
| 427 | - this._jdbcTemplateWrapperTenant.update(exeSql.toString(), tenantId, args.toArray()); | 451 | + //调用更新接口 |
| 452 | + _jdbcTemplateWrapperTenant.update(new PreparedStatementCreator() { | ||
| 453 | + @Override | ||
| 454 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 455 | + PreparedStatement stat = con.prepareStatement(exeSql.toString(), new String[] {_idTableFieldName}); | ||
| 456 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(args.toArray()); | ||
| 457 | + setter.setValues(stat); | ||
| 458 | + return stat; | ||
| 459 | + } | ||
| 460 | + | ||
| 461 | + }, _keyHolder, tenantId); | ||
| 462 | + | ||
| 463 | + //处理结果数据 | ||
| 464 | + List<Map<String, Object>> data = _keyHolder.getKeyList(); | ||
| 465 | + if(data.size() != entityList.size()) { | ||
| 466 | + throw new Exception("param entity size not equal return generate key list size"); | ||
| 467 | + } | ||
| 468 | + List<Number> dataT = new ArrayList<Number>(data.size()); | ||
| 469 | + for(Map<String, Object> item: data) { | ||
| 470 | + Iterator<Object> keyIter = item.values().iterator(); | ||
| 471 | + if (keyIter.hasNext()) { | ||
| 472 | + Object key = keyIter.next(); | ||
| 473 | + if (!(key instanceof Number)) { | ||
| 474 | + throw new DataRetrievalFailureException( | ||
| 475 | + "The generated key is not of a supported numeric type. " + | ||
| 476 | + "Unable to cast [" + (key != null ? key.getClass().getName() : null) + | ||
| 477 | + "] to [" + Number.class.getName() + "]"); | ||
| 478 | + } | ||
| 479 | + dataT.add((Number)key); | ||
| 480 | + }else { | ||
| 481 | + throw new DataRetrievalFailureException("Unable to retrieve the generated key. " + | ||
| 482 | + "Check that the table has an identity column enabled."); | ||
| 483 | + } | ||
| 484 | + } | ||
| 485 | + return dataT; | ||
| 428 | } | 486 | } |
| 429 | 487 | ||
| 430 | @Override | 488 | @Override |
src/main/java/com/taover/repository/CustomJdbcTemplateWrapperTenantInterface.java
| @@ -79,13 +79,13 @@ public interface CustomJdbcTemplateWrapperTenantInterface<T, ID extends Serializ | @@ -79,13 +79,13 @@ public interface CustomJdbcTemplateWrapperTenantInterface<T, ID extends Serializ | ||
| 79 | /** | 79 | /** |
| 80 | * 添加 | 80 | * 添加 |
| 81 | */ | 81 | */ |
| 82 | - public void addEntity(T entity, Long tenantId); | 82 | + public Number addEntity(T entity, Long tenantId); |
| 83 | 83 | ||
| 84 | /** | 84 | /** |
| 85 | * 批量添加 | 85 | * 批量添加 |
| 86 | * @throws Exception | 86 | * @throws Exception |
| 87 | */ | 87 | */ |
| 88 | - public void addEntityList(List<T> entityList, Long tenantId); | 88 | + public List<Number> addEntityList(List<T> entityList, Long tenantId) throws Exception; |
| 89 | 89 | ||
| 90 | /** | 90 | /** |
| 91 | * 按ID删除 | 91 | * 按ID删除 |
src/test/java/com/taover/repository/test/TestAutoconfigure.java
| 1 | package com.taover.repository.test; | 1 | package com.taover.repository.test; |
| 2 | 2 | ||
| 3 | +import java.sql.Connection; | ||
| 4 | +import java.sql.PreparedStatement; | ||
| 5 | +import java.sql.SQLException; | ||
| 3 | import java.util.List; | 6 | import java.util.List; |
| 4 | import java.util.Map; | 7 | import java.util.Map; |
| 5 | 8 | ||
| 6 | import org.springframework.boot.SpringApplication; | 9 | import org.springframework.boot.SpringApplication; |
| 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; | 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| 8 | import org.springframework.context.ConfigurableApplicationContext; | 11 | import org.springframework.context.ConfigurableApplicationContext; |
| 12 | +import org.springframework.jdbc.core.ArgumentPreparedStatementSetter; | ||
| 13 | +import org.springframework.jdbc.core.JdbcTemplate; | ||
| 14 | +import org.springframework.jdbc.core.PreparedStatementCreator; | ||
| 15 | +import org.springframework.jdbc.core.PreparedStatementSetter; | ||
| 16 | +import org.springframework.jdbc.support.GeneratedKeyHolder; | ||
| 17 | +import org.springframework.jdbc.support.KeyHolder; | ||
| 9 | import org.springframework.scheduling.annotation.EnableScheduling; | 18 | import org.springframework.scheduling.annotation.EnableScheduling; |
| 10 | 19 | ||
| 11 | import com.taover.repository.jdbctemplate.JdbcTemplateBroadcast; | 20 | import com.taover.repository.jdbctemplate.JdbcTemplateBroadcast; |
| @@ -16,12 +25,14 @@ import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | @@ -16,12 +25,14 @@ import com.taover.repository.jdbctemplate.JdbcTemplateWrapperTenant; | ||
| 16 | public class TestAutoconfigure { | 25 | public class TestAutoconfigure { |
| 17 | private static JdbcTemplateBroadcast jdbcTemplateBroadcast; | 26 | private static JdbcTemplateBroadcast jdbcTemplateBroadcast; |
| 18 | private static JdbcTemplateWrapperTenant jdbcTemplateWrapperTenant; | 27 | private static JdbcTemplateWrapperTenant jdbcTemplateWrapperTenant; |
| 28 | + private static JdbcTemplate jdbcTemplate; | ||
| 19 | 29 | ||
| 20 | 30 | ||
| 21 | public static void main(String args[]) { | 31 | public static void main(String args[]) { |
| 22 | ConfigurableApplicationContext context = SpringApplication.run(TestAutoconfigure.class, args); | 32 | ConfigurableApplicationContext context = SpringApplication.run(TestAutoconfigure.class, args); |
| 23 | jdbcTemplateBroadcast = context.getBean(JdbcTemplateBroadcast.class); | 33 | jdbcTemplateBroadcast = context.getBean(JdbcTemplateBroadcast.class); |
| 24 | jdbcTemplateWrapperTenant = context.getBean(JdbcTemplateWrapperTenant.class); | 34 | jdbcTemplateWrapperTenant = context.getBean(JdbcTemplateWrapperTenant.class); |
| 35 | + jdbcTemplate = context.getBean(JdbcTemplate.class); | ||
| 25 | 36 | ||
| 26 | // testBroadCast(); | 37 | // testBroadCast(); |
| 27 | //testSelectSubQuery(); | 38 | //testSelectSubQuery(); |
| @@ -43,9 +54,73 @@ public class TestAutoconfigure { | @@ -43,9 +54,73 @@ public class TestAutoconfigure { | ||
| 43 | //testDeliveryGoodsExcel(); | 54 | //testDeliveryGoodsExcel(); |
| 44 | //testExcelSelectForSale(); | 55 | //testExcelSelectForSale(); |
| 45 | //testChannelPrintSelect(); | 56 | //testChannelPrintSelect(); |
| 46 | - testWarePaymentExport(); | 57 | + //testWarePaymentExport(); |
| 58 | + //testChannelDeliveryOrderQuery(); | ||
| 59 | + | ||
| 60 | +// testKeyHolder(); | ||
| 61 | +// testKeyHolderWithoutId(); | ||
| 62 | + testKeyHolderWithMultiInsert(); | ||
| 47 | } | 63 | } |
| 48 | 64 | ||
| 65 | + private static void testKeyHolderWithMultiInsert() { | ||
| 66 | + KeyHolder keyHolder = new GeneratedKeyHolder(); | ||
| 67 | + String exeSql = "insert into demo(`name`) values(?),(?),(?),(?),(?),(?);"; | ||
| 68 | + jdbcTemplate.update(new PreparedStatementCreator() { | ||
| 69 | + @Override | ||
| 70 | + public PreparedStatement createPreparedStatement(Connection con) throws SQLException { | ||
| 71 | + PreparedStatement stat = con.prepareStatement(exeSql.toString(), new String[] {"id"}); | ||
| 72 | + PreparedStatementSetter setter = new ArgumentPreparedStatementSetter(new String[] {"Jack", "Lucy", "Lily", "Mary", "Carlin", "Michael"}); | ||
| 73 | + setter.setValues(stat); | ||
| 74 | + return stat; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + }, keyHolder); | ||
| 78 | + System.out.println(keyHolder.getKey()); | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + private static void testKeyHolderWithoutId() { | ||
| 82 | + String sql = "insert into demo(`id`,`name`) values(100,'zhangfei');"; | ||
| 83 | + jdbcTemplate.update( | ||
| 84 | + new PreparedStatementCreator() { | ||
| 85 | + @Override | ||
| 86 | + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { | ||
| 87 | + PreparedStatement psst = connection.prepareStatement(sql); | ||
| 88 | + return psst; | ||
| 89 | + } | ||
| 90 | + }); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + private static void testKeyHolder() { | ||
| 94 | + KeyHolder keyHolder = new GeneratedKeyHolder(); | ||
| 95 | + String sql = "insert into demo(`name`) values(?);"; | ||
| 96 | + jdbcTemplate.update( | ||
| 97 | + new PreparedStatementCreator() { | ||
| 98 | + @Override | ||
| 99 | + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { | ||
| 100 | + PreparedStatement psst = connection.prepareStatement(sql, new String[] { "id" }); | ||
| 101 | + psst.setString(1, "wangbin"); | ||
| 102 | + return psst; | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | + , keyHolder); | ||
| 106 | + System.out.println(keyHolder.getKey().longValue()); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + private static void testChannelDeliveryOrderQuery() { | ||
| 110 | + String sql = "SELECT * FROM ( (SELECT wxorder_order.id FROM wxorder_order wxorder_order " | ||
| 111 | + + "WHERE wxorder_order.tenant_id = 16 AND wxorder_order.control_status = 3" | ||
| 112 | + +" AND wxorder_order.consignee = '13621051230' AND wxorder_order.channel_id = 20)" | ||
| 113 | + +" UNION ALL " | ||
| 114 | + + "(SELECT wxorder_order.id FROM wxorder_order wxorder_order WHERE 1 = 1 AND wxorder_order.tenant_id = 16" | ||
| 115 | + +" AND wxorder_order.control_status = 3" | ||
| 116 | + +" AND wxorder_order.mobile = '13621051230' AND wxorder_order.channel_id = 20)" | ||
| 117 | + + " UNION ALL (SELECT wxorder_order.id FROM wxorder_order wxorder_order WHERE wxorder_order.tenant_id = 16" | ||
| 118 | + +" AND wxorder_order.control_status = 3" | ||
| 119 | + +" AND wxorder_order.express_number = '13621051230' AND wxorder_order.channel_id = 20" | ||
| 120 | + +")) aa LIMIT 1,10"; | ||
| 121 | + System.out.println(jdbcTemplateWrapperTenant.queryForList(sql, 16L)); | ||
| 122 | + } | ||
| 123 | + | ||
| 49 | private static void testWarePaymentExport() { | 124 | private static void testWarePaymentExport() { |
| 50 | String sql = "SELECT wc.manager_nickname,cp.id as paymentId, wo.order_sn,wo.`upload_sn`,wo.consignee,wo.mobile," | 125 | String sql = "SELECT wc.manager_nickname,cp.id as paymentId, wo.order_sn,wo.`upload_sn`,wo.consignee,wo.mobile," |
| 51 | + " wgbs.sku_unit_num as skuUnitNum, wgbs.unit, " | 126 | + " wgbs.sku_unit_num as skuUnitNum, wgbs.unit, " |