1: public class SerialNumberedInserter {
2: /**
3: * 看有幾種不同的序號邏輯,都要繼承這個介面
4: */
5: public interface SerialNumberGenerator {
6: String generate();
7: }
8: /**
9: * 建構子,可以自訂重覆取號的最大次數
10: * @param jdbcTemplate 對資料庫存取的jdbcTemplate
11: * @param generator 產生流水號的邏輯,實作Generator介面
12: * @param maxRetry 最多重複嘗試產生流水號的次數
13: */
14: public SerialNumberedInserter(JdbcTemplate jdbcTemplate,
15: SerialNumberGenerator generator,
16: int maxRetry) {
17: this.jdbcTemplate = jdbcTemplate;
18: this.generator = generator;
19: this.maxRetry = maxRetry;
20: }
21: /**
22: * 建構子,預設可以重覆取號三次
23: * @param jdbcTemplate 對資料庫存取的jdbcTemplate
24: * @param generator 產生流水號的邏輯,實作Generator介面
25: */
26: public SerialNumberedInserter(JdbcTemplate jdbcTemplate,
27: SerialNumberGenerator generator) {
28: this(jdbcTemplate, generator, 3);
29: }
30:
31:
32: /**
33: * @param sql 要執行新增的sql,如:
34: * INSERT INTO foo (id, serial_number) VALUES( ?, ? )
35: * @param param jdbcTemplate要執行sql時需要的參數,如:
36: * Object[] param = new Object[]{ foo_seq, "" ); 序號的地方要傳空值。
37: * @param serialNumberPos 序號欄位在param中的第幾位(第一位是0)。
38: * @param retries 目前因失敗已重複嘗試產生序號的次數
39: */
40:
41: private void tryInsert(String sql, Object[] param,
42: int serialNumberPos, int retries) {
43: param[serialNumberPos] = generator.generate(); //取號
44: try {
45: jdbcTemplate.update(sql, param);
46: }
47: catch (DataIntegrityViolationException ex) {
48: if (retries < maxRetry) {
49: tryInsert(sql, param, serialNumberPos, retries + 1);
50: }
51: throw ex;
52: }
53: }
54:
55:
56: /**
57: * 產生序號,並執行資料新增
58: * @param sql 要執行新增的sql,如:
59: * INSERT INTO foo (id, serial_number) VALUES( ?, ? )
60: * @param param jdbcTemplate要執行sql時需要的參數,如:
61: * Object[] param = new Object[]{ foo_seq, "" ); 序號的地方要傳空值。
62: * @param serialNumberPos 序號欄位在param中的第幾位(第一位是0)
63: */
64:
65: public String insert(String sql, Object[] param, int serialNumberPos) {
66: tryInsert(sql, param, serialNumberPos, 0);
67: //如果有需要將產生的序號,存到另一個TABLE當FK時,可以將序號傳回
68: return param[serialNumberPos].toString();
69: }
70:
71: }