ㅏ입핸들5

import java.sql.CallableStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedTypes; /* * ResultMap usage example: * * * * * * * One-parameter parseable mixed column examples: * * SELECT * NVL(#{typeCode, jdbcType=VARCHAR}, '') * || '^|^' * || NVL(DECODE(OTS.SHOW_BIRTHDAY, 'N', '99991231', EMP.BIRTH_DATE_ENC), '') * || '^|^' * || NVL(EMP.HIRE_DATE, '') * || '^|^' * || NVL(TO_CHAR(SYSDATE, 'YYYYMMDD'), '') AS ATT_DETAIL_MIXED * , NVL(#{typeCode, jdbcType=VARCHAR}, '') * || '^|^' * || NVL(DECODE(OTS.SHOW_BIRTHDAY, 'N', '99991231', EMP.BIRTH_DATE_ENC), '') * || '^|^' * || NVL(EMP.HIRE_DATE, '') * || '^|^' * || NVL(TO_CHAR(SYSDATE, 'YYYYMMDD'), '') AS START_YMD_MIXED * FROM ... * * Mixed value format: * typeCode^|^birthDateEncOr99991231^|^syStaDate^|^targetDay * * Only BIRTH_DATE_ENC is decrypted as decrypt(BIRTH_DATE_ENC), and only when * it is not the birthday-hidden sentinel value 99991231. SY_STA_DATE and * targetDay are treated as plain YYYYMMDD values. * Replace Crypto.decrypt(...) with the project's real decrypt API. */ @MappedTypes(String.class) @MappedJdbcTypes(JdbcType.VARCHAR) class AttDetailTypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(java.sql.PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return toAttDetail(rs.getString(columnName)); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return toAttDetail(rs.getString(columnIndex)); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return toAttDetail(cs.getString(columnIndex)); } private String toAttDetail(String mixedValue) throws SQLException { MixedAttendanceValue value = MixedAttendanceValue.parse(mixedValue); if (value.isBlank()) { return ""; } switch (value.typeCode) { case "BDAY": return value.birthDateYmd(); case "JOIN": return value.syStaDate; case "LONG": if (value.targetDay.length() < 4 || value.syStaDate.length() < 4) { return ""; } int targetYear = Integer.parseInt(value.targetDay.substring(0, 4)); int joinYear = Integer.parseInt(value.syStaDate.substring(0, 4)); return String.valueOf(targetYear - joinYear); default: return ""; } } } @MappedTypes(String.class) @MappedJdbcTypes(JdbcType.VARCHAR) class StartYmdTypeHandler extends BaseTypeHandler { @Override public void setNonNullParameter(java.sql.PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, parameter); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { return toStartYmd(rs.getString(columnName)); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return toStartYmd(rs.getString(columnIndex)); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return toStartYmd(cs.getString(columnIndex)); } private String toStartYmd(String mixedValue) throws SQLException { MixedAttendanceValue value = MixedAttendanceValue.parse(mixedValue); if (value.isBlank()) { return ""; } switch (value.typeCode) { case "BDAY": return toMonthDay(value.birthDateYmd()); case "JOIN": case "LONG": return toMonthDay(value.syStaDate); default: return ""; } } private String toMonthDay(String ymd) { if (ymd == null || ymd.length() != 8) { return ""; } return ymd.substring(4, 6) + "." + ymd.substring(6, 8); } } final class MixedAttendanceValue { private static final String DELIMITER = "^|^"; private static final String HIDDEN_BIRTHDAY = "99991231"; final String typeCode; final String birthDateEncOrMask; final String syStaDate; final String targetDay; private MixedAttendanceValue(String typeCode, String birthDateEncOrMask, String syStaDate, String targetDay) { this.typeCode = normalize(typeCode); this.birthDateEncOrMask = normalize(birthDateEncOrMask); this.syStaDate = normalize(syStaDate); this.targetDay = normalize(targetDay); } static MixedAttendanceValue parse(String mixedValue) throws SQLException { if (mixedValue == null || mixedValue.trim().isEmpty()) { return new MixedAttendanceValue("", "", "", ""); } String[] parts = mixedValue.split("\\Q" + DELIMITER + "\\E", -1); if (parts.length < 4) { throw new SQLException("Invalid attendance mixed value. Expected typeCode^|^birthDateEncOrMask^|^syStaDate^|^targetDay."); } return new MixedAttendanceValue(parts[0], parts[1], parts[2], parts[3]); } boolean isBlank() { return typeCode.isEmpty(); } String birthDateYmd() throws SQLException { if (birthDateEncOrMask.isEmpty()) { return ""; } if (HIDDEN_BIRTHDAY.equals(birthDateEncOrMask)) { return HIDDEN_BIRTHDAY; } // Only BIRTH_DATE_ENC is decrypted. The other mixed fields stay plain. return normalize(Crypto.decrypt(birthDateEncOrMask)); } private static String normalize(String value) { return value == null ? "" : value.trim(); } } final class Crypto { private Crypto() { } static String decrypt(String encryptedValue) throws SQLException { /* * TODO Replace this stub with the real project decrypt call. * Example: * return KmsCipher.decrypt(encryptedValue); */ return encryptedValue; } }

댓글

이 블로그의 인기 게시물

food eff privacy

판다 스픽 , 개인정보 처리방침 , Panda Speak Privacy Term

판다 수학 개인정보 처리방침 , Privacy , Panda Math