File name
Commit message
Commit date
File name
Commit message
Commit date
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 = 13; // 자리수 (예: 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;
}
}