
IBSheet 에서 단일 행 수정하는 방법이다.
등록 Dialog를 통해 수정하는 건 큰 어려움 없이 했는데
IBSheet를 통해 수정하는 건 왜이렇게 어렵던지 ... 특히 Date형을 자꾸 TimeStamp 로 변경해버려서 너무 힘들었다 ....
백에서 JsonFormat ... 프론트에서 Format.. 뭘 해도 에러 ..에러 ....!!
onMounted 에서 Events 주고,
컬럼 변경하는 함수 생성하고 .. 난리를 쳐보았는데.
그러지 말고 진작 이것 저것 다 콘솔 찍어보고
IBSheet8 매뉴얼을 보고
천천히 생각해볼 걸 그랬다..
너무 급하게 타자 먼저 치면서 에러 잡기에만 몰두했다 ...
IBSheet가 제공하는 함수를 이용하면 간단하다.
행 전체 데이터를 수정할 때는 onAfterEdit() 을 쓸 수 있고
행 한 개 데이터를 수정할 때는 onAfterChange() 를 쓸 수 있다.
onAfterChange: async function (evtParam) {
console.log('onAfterChange 발생');
console.log('evtParam:', evtParam);
const rowData = evtParam.row;
const rowIndex = rowData.OrgIndex ?? rowData.HasIndex;
const colName = evtParam.col;
const newValue = evtParam.val; // 수정된 값
// 기존 값은 IBSheet 내부 속성 중 하나를 써야 함
const oldValue = rowData[colName + 'BeforeVal'] ?? rowData[colName + 'Orig'] ?? null;
console.log('수정된 행 인덱스:', rowIndex);
console.log('수정된 컬럼명:', colName);
console.log('새로운 값:', newValue);
console.log('기존 값:', oldValue);
console.log('행 데이터:', rowData);
if (newValue === oldValue) return;
const changedData = {
assetCode: rowData.assetCode,
col: colName,
value: newValue
};
console.log('서버로 전송하는 데이터:', JSON.stringify(changedData));
axios.post(`http://localhost:8080/main/updateColAsset.do`, changedData)
.then(res => {
if (res.data.result === 1) {
console.log('단일 셀 수정 성공');
} else {
console.error('단일 셀 수정 실패:', res.data);
}
}).catch(err => {
console.error('단일 셀 수정 중 오류:', err);
});
},
에러 체크하려고 console을 얼마나 많이 찍어보았던가 ..ㅎㅎ
어제 11시간 동안 모니터를 들여다본 끝에 성공하고 얼마나 기쁘던지 ..!
코딩하다가 손목이 아팠던 건 이번이 처음이다.
어쨌든, GPT한테도 많이 물어보고 매뉴얼 보고 따라해보면서 바꾸다가 얻어걸린 거라 한 줄씩 공부를 해야겠다.
한 줄씩 주석 공부
** 일단 IBSheet에서 셀 하나를 수정했을 때
알아내서 서버에 보내야 한다.
onAfterChange: async function (evtParam) {
// 사용자가 셀을 수정한 후 실행되는 IBSheet 이벤트
console.log('onAfterChange 발생');
console.log('evtParam:', evtParam);
// evtParam : 이벤트 파라미터. IBSheet 제공. 이벤트 발생 시 관련 정보를 evtParam 객체에 담아서 제공
const rowData = evtParam.row;
// 수정된 행 데이터 전체를 rowData에 저장 (어떤 행 바뀜?)
const rowIndex = rowData.OrgIndex ?? rowData.HasIndex;
// 수정된 행의 원래 인덱스 찾기
// rowData는 IBSheet에서 수정된 셀의 행 전체를 나타내는 객체
// OrgIndex : 원본 데이터 기준의 행 번호 (서버에서 처음 불러왔을 때 기존 데이터)
// HasIndex : 새로운 행이거나 OrgIndex 없을 때 대체하는 백업 인덱스
(HasIndex는 행 추가 안해도 IBSheet가 모든 row객체에 부여하는 내부 순번)
// ?? 연산자 : 왼쪽 값이 null, undefined 일 때 오른쪽 값 사용
따라서 원래 있는 값이면 OrgIndex를 쓰고 새로 추가된 행이면 HasIndex를 써서 어떤 행인지 알 수 있다.
const colName = evtParam.col;
// 수정된 컬럼명을 colName에 저장 (어떤 컬럼 바뀜?)
const newValue = evtParam.val;
// 새로운 값을 newValue에 저장 (새로운 값이 뭐?)
// 기존 값은 IBSheet 내부 속성 중 하나를 써야 함
const oldValue = rowData[colName + 'BeforeVal'] ?? rowData[colName + 'Orig'] ?? null;
// 수정하기 전의 기존 값 가져오기
// IBSheet 가 제공하는 필드 : BeforeVal, Orig
// oldValue를 구할 때 사용 -> 방금 전 값 있으면 그거 쓰고, 없으면 서버에서 온 원래 값 쓰고, 없으면 null
// 진짜 수정된 게 맞는지 확인하기 위
// ?? 연산자 : 왼쪽 값이 null, undefined 일 때 오른쪽 값 사용
// colName + 'BeforeVal' 로 이전 값 접근하는 건 JavaScript 동적 속성 접근 방식
console.log('수정된 행 인덱스:', rowIndex);
console.log('수정된 컬럼명:', colName);
console.log('새로운 값:', newValue);
console.log('기존 값:', oldValue);
console.log('행 데이터:', rowData);
if (newValue === oldValue) return;
// oldValue가 null일 경우 newValue와 같지 않아 여기서 종료될 수 있기 때문에
// console.log를 if문 전 후로 찍어보는 게 도움이 된다.
const changedData = {
assetCode: rowData.assetCode,
col: colName,
value: newValue
};
// 기존 값의 assetCode, 컬럼명, 변경된 새 값을 changedData 에 담아서
console.log('서버로 전송하는 데이터:', JSON.stringify(changedData));
// JSON.stringify() : JavaScript 객체(Object)를 문자열로 변환
// changedData를 JSON형식 문자열로 바꾸는 것 : 서버에 전송해야 하니까
axios.post(`http://localhost:8080/main/updateColAsset.do`, changedData)
.then(res => {
if (res.data.result === 1) {
console.log('단일 셀 수정 성공');
} else {
console.error('단일 셀 수정 실패:', res.data);
}
}).catch(err => {
console.error('단일 셀 수정 중 오류:', err);
});
}
// 수정된 데이터만 서버로 보내는 것
// 서버에서 성공 시 result 에 1을 담아 보내기 때문에 res.data.result 가 1이면 성공, 아니면 실패
JavaScript 동적 속성 접근 방식
const colName = 'acqPrice';
const key = colName + 'BeforeVal'; // 결과: "acqPriceBeforeVal"
const oldValue = rowData[key]; // → rowData["acqPriceBeforeVal"]
rowData[colName + 'BeforeVal']
=
rowData["acqPriceBeforeVal"]
같은 의미
[] 써서 접근
● IBSheet 가 제공하는 필드
- evtParam
: 이벤트 파라미터. IBSheet 제공. 이벤트 발생 시 관련 정보를 evtParam 객체에 담아서 제공
- evtParam.col
: 현재 수정/클릭된 컬럼 이름
- evtParam.row
: 현재 수정/클릭된 행 전체 객체
- evtParam.val
: 사용자가 입력한 새로운 값 (**onAfterChange 등에서만)
- OrgIndex
: 원본 데이터 기준의 행 번호 (서버에서 처음 불러왔을 때 기존 데이터)
- HasIndex
: 행 추가 안해도 IBSheet가 모든 row객체에 부여하는 내부 순번
- evtParam.row[컬럼명 + 'BeforeVal']
: 해당 컬럼의 변경 직전 값
→ rowData['acqPriceBeforeVal'] 이런식으로 됨
- evtParam.row[컬럼명 + 'Orig']
: 해당 컬럼의 서버에서 처음 불러온 값
**
evtParam.row 는 객체라 rowData로 접근해도 되고 그냥 접근해도 됨
mapper.xml
<update id="updateColAsset" parameterType="map">
UPDATE tbl_asset
<set>
${col} = #{value}
</set>
WHERE asset_code = #{assetCode}
</update>
Controller
@PostMapping("/updateColAsset.do")
public MainDto updateColAsset(@RequestBody Map<String, Object> map) {
try {
Map<String, String> colMap = Map.of(
"assetName", "asset_name",
"assetPrice", "asset_price",
"acqQty", "acq_qty",
"acqDate", "acq_date",
"acqPrice", "acq_price"
); String logicalCol = (String) map.get("col");
String dbCol = colMap.get(logicalCol);
if (dbCol == null) {
throw new IllegalArgumentException("허용되지 않은 컬럼명입니다: " + logicalCol);
}
// DB에 사용할 컬럼명으로 치환
map.put("col", dbCol);
map.put("newValue", map.get("value")); // #{newValue}에 매핑
int result = service.updateColAsset(map);
System.out.println("서버로 전달된 매핑 후 파라미터: " + map);
return MainDto.builder().result(result).build();
} catch (Exception e) {
e.printStackTrace();
return MainDto.builder().result(-1).build();
}
}
1. public MainDto updateColAsset(@RequestBody Map<String, Object> map)
클라이언트에서 보내는 데이터 JSON을 map이라는 이름의 자바 Map으로 자동 변환해서 받는다.
ex)
{
"col": "acqPrice",
"value": "300000",
"assetCode": "KLOZAA00001"
}
** public MainDto updateColAsset(@RequestBody Map<string, object> map)
Response 응답 출력 Request 요청 입력
: 클라이언트가 보낸 JSON 을 Map으로 받아서 MainDto 로 응답하겠다
{
"col": "acqPrice",
"value": "300000",
"assetCode": "KLOZAA00001"
}
이렇게 보내면
map.get("col") → "acqPrice"
map.get("value") → "300000"
map.get("assetCode") → "KLOZAA00001"
서버에서 이렇게 받고
이걸 DB수정할 때 사용한 다음에
처리 결과를 MainDto.builder().result(1).build()로 응답
2. Map<String, String> colMap = Map.of( ... );
프론트에서 사용하는 컬럼명과 DB의 컬럼명이 다르기 때문에 (코딩 컨벤션) 연결해주는 사전 Map을 만들어서 colMap에 저장
3. String logicalCol = (String) map.get("col");
프론트에서 보내준 수정한 컬럼명 col을 logicalCol 에 저장
ex)
map.get("col") → "acqPrice"
4. String dbCol = colMap.get(logicalCol);
colMap 사전을 보고 logicalCol을 DB 컬럼명으로 변경
5. if (dbCol == null) {
throw new IllegalArgumentException("허용되지 않은 컬럼명입니다: " + logicalCol);
}
만약 colMap에 없는 컬럼명을 보내면 dbCol 이 null 이기 때문에 에러 던짐
(DB에 없는 컬럼명 저장 막을 목적)
6. map.put("col", dbCol);
map안의 "col"값을 DB용 컬럼명으로 덮어쓰기
col: "acqPrice" → col: "acq_price"로 바뀜
7. map.put("newValue", map.get("value"));
MaBatis XML 에서 사용할 #{newValue)에 대응되도록 value 도 저장
8. int result = service.updateColAsset(map);
service 메서드에 map 넣고 실행해서 실제로 값 업데이트하고 result 에 저장
성공하면 result 는 1, 실패하면 0 (성공적으로 1개가 처리되기 때문에 1 반환하면 성공이라는 의미)
9. return MainDto.builder().result(result).build();
Vue한테 빌더패턴 이용해서 응답
'웹 개발 > IBSheet8' 카테고리의 다른 글
| [IBSheet] 시트 내 이미지 삽입 / 반환타입과 파라미터요청, JSON요청(1) (3) | 2025.08.01 |
|---|---|
| [IBSheet] onClick(), onDblClick(), onAfterClick() 이벤트로 수정, 삭제 시 열이름 클릭 제외 (0) | 2025.06.30 |
| [IBSheet] Excel 내보내기 (1) | 2025.06.24 |
| [IBSheet] loader (0) | 2025.06.04 |
| [IBSheet] IBSheet8 활용 데이터 출력 (2) | 2025.06.04 |