File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
package egovframework.com.idgen.impl;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement; // java.sql.PreparedStatement로 임포트
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import egovframework.com.idgen.CustomIdGnrService;
import egovframework.rte.fdl.cmmn.exception.FdlException;
import egovframework.rte.fdl.idgnr.EgovIdGnrStrategy;
public class CustomTableIdGnrServiceImpl implements CustomIdGnrService {
private long allocatedId;
private long allocatedMaxId;
private int blockSize = 10; // 기본값, 필요에 따라 변경
private DataSource dataSource;
private String table; // 실제 테이블 이름 (예: IDS)
private String tableName; // TABLE_NAME 컬럼에서 사용할 값 (예: MSG_ID)
private String columnName = "NEXT_ID"; // NEXT_ID 컬럼명
private String prefix;
private String fillChar = "0"; // 채울 문자 (예: 0)
private int cipers = 14; // 자리수 (예: 14)
private boolean applyYear;
private boolean useBigDecimals = false;
@Override
public synchronized List<String> getNextStringId(int count) throws FdlException {
List<String> idList = new ArrayList<>(count);
try {
for (int i = 0; i < count; i++) {
if (allocatedId >= allocatedMaxId) {
allocateIdBlock(count);
}
long id = allocatedId++;
idList.add(createStringId(id));
}
} catch (Exception e) {
throw new FdlException("ID Generation Error", e);
}
return idList;
}
private void allocateIdBlock(int requiredCount) throws SQLException, FdlException {
Connection conn = DataSourceUtils.getConnection(dataSource);
try {
conn.setAutoCommit(false);
int newBlockSize = Math.max(this.blockSize, requiredCount);
// SELECT 쿼리 수정
String query = "SELECT " + columnName + " FROM " + table + " WHERE TABLE_NAME = ? FOR UPDATE";
try (PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setString(1, tableName);
try (ResultSet rs = stmt.executeQuery()) {
long oldId = 0;
if (rs.next()) {
oldId = rs.getLong(1);
} else {
throw new FdlException(
"ID Generation Error: No record found in " + table + " for TABLE_NAME = " + tableName);
}
long newId = oldId + newBlockSize;
// UPDATE 쿼리 수정
String update = "UPDATE " + table + " SET " + columnName + " = ? WHERE TABLE_NAME = ? AND "
+ columnName + " = ?";
try (PreparedStatement updateStmt = conn.prepareStatement(update)) {
updateStmt.setLong(1, newId);
updateStmt.setString(2, tableName);
updateStmt.setLong(3, oldId);
int row = updateStmt.executeUpdate();
if (row == 0) {
throw new FdlException(
"ID Generation Error: Failed to update ID. Possible concurrent modification.");
}
}
conn.commit();
allocatedId = oldId;
allocatedMaxId = newId;
}
} catch (SQLException e) {
conn.rollback();
throw e;
}
} catch (SQLException e) {
throw new FdlException("ID Generation Error", e);
} finally {
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
private String createStringId(long id) {
StringBuilder sb = new StringBuilder();
if (prefix != null) {
sb.append(prefix);
}
if (applyYear) {
sb.append(new SimpleDateFormat("yyyy").format(new Date()));
}
String idStr = String.format("%0" + cipers + "d", id);
sb.append(idStr);
return sb.toString();
}
// 인터페이스의 다른 메서드 구현 (필요에 따라 UnsupportedOperationException 또는 직접 구현)
@Override
public BigDecimal getNextBigDecimalId() throws FdlException {
throw new UnsupportedOperationException("getNextBigDecimalId is not supported");
}
@Override
public long getNextLongId() throws FdlException {
throw new UnsupportedOperationException("getNextLongId is not supported");
}
@Override
public int getNextIntegerId() throws FdlException {
throw new UnsupportedOperationException("getNextIntegerId is not supported");
}
@Override
public short getNextShortId() throws FdlException {
throw new UnsupportedOperationException("getNextShortId is not supported");
}
@Override
public byte getNextByteId() throws FdlException {
throw new UnsupportedOperationException("getNextByteId is not supported");
}
@Override
public String getNextStringId() throws FdlException {
throw new UnsupportedOperationException("getNextStringId is not supported");
}
@Override
public String getNextStringId(String strategyId) throws FdlException {
throw new UnsupportedOperationException("getNextStringId(String strategyId) is not supported");
}
@Override
public String getNextStringId(EgovIdGnrStrategy strategy) throws FdlException {
throw new UnsupportedOperationException("getNextStringId(EgovIdGnrStrategy strategy) is not supported");
}
// 필요한 setter 메서드들 추가
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTable(String table) {
this.table = table;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setFillChar(String fillChar) {
this.fillChar = fillChar;
}
public void setCipers(int cipers) {
this.cipers = cipers;
}
public void setApplyYear(boolean applyYear) {
this.applyYear = applyYear;
}
public void setBlockSize(int blockSize) {
this.blockSize = blockSize;
}
}