TableIdIncrementer.java
package com.github.mygreen.sqlmapper.core.id;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.Assert;
import com.github.mygreen.sqlmapper.core.util.NameUtils;
import lombok.NonNull;
/**
* テーブルを用いてIDの採番を行います。
*
*
* @author T.TSUCHIE
*
*/
public class TableIdIncrementer extends AllocatableIdGenerator {
private final JdbcTemplate jdbcTemplate;
/**
* テーブル情報
*/
private final TableIdContext context;
/**
* 採番用レコードを抽出するためのSQL
*/
private String sqlSelect;
/**
* 採番用レコードを作成するためのSQL
*/
private String sqlInsert;
/**
* 採番用レコードを更新するためのSQL
*/
private String sqlUpdate;
public TableIdIncrementer(@NonNull JdbcTemplate jdbcTemplate, @NonNull TableIdContext context) {
super(context.getAllocationSize());
this.jdbcTemplate = jdbcTemplate;
this.context = context;
init();
}
/**
* {@link TableIdContext} を元にこのクラスの初期化を行います。
* <p>実行するSQLの組み立てを行います。</p>
*/
private void init() {
Assert.notNull(context, "tableIdContext should not be null.");
if(context.getAllocationSize() <= 0) {
throw new IllegalArgumentException("TableIdContext#allocationSize shoule be greater than 1.");
}
if(context.getInitialValue() < 0) {
throw new IllegalArgumentException("TableIdContext#initialValue shoule be greater than 0.");
}
final String tableName = NameUtils.tableFullName(context.getTable(), context.getCatalog(), context.getSchema());
this.sqlSelect = new StringBuilder(100)
.append("SELECT ")
.append(context.getValueColumn())
.append(" FROM ")
.append(tableName)
.append(" WHERE ")
.append(context.getPkColumn())
.append(" = ?")
.append(" FOR UPDATE")
.toString();
this.sqlInsert = new StringBuilder(100)
.append("INSERT INTO ")
.append(tableName)
.append(" (")
.append(context.getPkColumn())
.append(", ")
.append(context.getValueColumn())
.append(" ) VALUES (?, ?)")
.toString();
this.sqlUpdate = new StringBuilder(100)
.append("UPDATE ")
.append(tableName)
.append(" SET ")
.append(context.getValueColumn())
.append(" = ")
.append(context.getValueColumn())
.append(" + ? WHERE ")
.append(context.getPkColumn())
.append(" = ?")
.toString();
}
@Override
protected long getCurrentValue(String sequenceName) {
Long currentValue = selectTable(sequenceName);
if(currentValue == null) {
insertTable(sequenceName, context.getInitialValue());
currentValue = context.getInitialValue();
}
return currentValue;
}
@Override
protected long allocateValue(final String sequenceName, final long allocationSize) {
updateTable(sequenceName, allocationSize);
return selectTable(sequenceName);
}
/**
* 現在の採番値を取得します。
* @param name 採番名。
* @return 採番値。該当する採番名のレコードが存在しない場合は、{@literal null} を返します。
*/
private Long selectTable(final String name) {
List<Long> result = jdbcTemplate.queryForList(sqlSelect, Long.class, name);
if(result.isEmpty()) {
return null;
} else {
return result.get(0);
}
}
/**
* 新たな採番情報を作成します。
* @param name 採番名
* @param value 採番値。
*/
private void insertTable(final String name, final long value) {
jdbcTemplate.update(sqlInsert, name, value);
}
/**
* 既存の採番値を更新します。
* @param name 採番名
* @param incrementValue 採番値に対する加算する値
*/
private void updateTable(final String name, final long incrementValue) {
jdbcTemplate.update(sqlUpdate, incrementValue, name);
}
}