일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- usb 포맷시스템
- programmers
- 신고결과받기
- on conflict
- 특정ip접근
- 방화벽정책
- Linux
- db
- 폴더압축 권한문제
- 특정ip차단
- 파일이 너무 커서 안들어감
- 도커
- java
- c드라이브에서 압축
- LV1
- 2022 KAKAO BLIND RECRUITMENT
- ipv6->ipv4
- 데이터넘기기
- Docker
- usb 공간있는데
- mybatis
- 팰린드롬개수
- 관리자권한 문제
- 6tunnel
- 프로그래머스
- 압축권한
- c드라이브에서 압축 안될때
- maven-install
- 로또의 최고 순위와 처저 순위
- PostgreSQL
- Today
- Total
개발 기록일지
[Mybatis/postgresql] foreach 를 통해 다중 insert/update 하기 본문
- INSERT
xml부분
<insert id="insertDev" parameterType="map">
INSERT INTO
CH_DEV_INF(DEV_SEQ, CH_DEV_SEQ, DEV_MODEL_SEQ, MODL_CNT, CRETR, CRET_DT)
VALUES
<foreach collection="list" item="item" separator=",">
(
#{dev_seq}::NUMERIC
,#{item.ch_dev_seq}
,#{item.dev_model_seq}
,#{item.combox_modl_cnt}::NUMERIC
,#{cretr}
,NOW()
)
</foreach>
</insert>
controller 부분
@RequestMapping(value = "/equipmentRegister.do", method= RequestMethod.GET)
public Map<String, Object> insertEquipmentInfo(@RequestParam Map<String, Object> param, DevComboxChModuleVO vo) throws Exception {
param.put("list", vo.getList());
System.out.println(param);
return equipmentManageService.insertDev(param);
}
insert 구문은 <insert></insert> 로 끝나게되고 controller 에서 지정한 반환형이 Map 이기때문에
parameterType="map" 으로 지정한다
이때 foreach 를 써서 list형태의 데이터를 받아 다중 insert 할때가 있는데
VALUES() 에 들어가는 부분을 위와같이 foreach 를 써서 처리해주면 된다.
이때 중요한부분은 collection="list" 처럼 설정하면 parameter 안에 "list"라는 key가 있어야한다.
그리고 foreach 구문에서 separator가 있는데 이부분은 foreach가 끝나는 부분마지막에 들어가는 구분자이다.
insert가 여러번 수행되므로
아래와 같이 구분자가 들어가서 다중 insert가 수행되는것이다.
INSERT INTO
CH_DEV_INF(DEV_SEQ, CH_DEV_SEQ, DEV_MODEL_SEQ, MODL_CNT, CRETR, CRET_DT)
VALUES(111,'123','123',5,'admin',NOW()),
VALUES(112,'1234','5123',5,'admin',NOW()),
VALUES(113,'1234','4123',5,'admin',NOW())
- UPSERT
<insert id="updateDev" parameterType="map">
<foreach collection="list" item="item" open="" separator=";" close="">
INSERT INTO
CH_DEV_INF(DEV_SEQ, CH_DEV_SEQ, DEV_MODEL_SEQ, MODL_CNT, CRETR, CRET_DT)
VALUES
(
#{prev_dev_seq}::NUMERIC
,#{item.ch_dev_seq}
,#{item.dev_model_seq}
,#{item.combox_modl_cnt}::NUMERIC
,#{updtr}
,NOW()
)
ON CONFLICT(DEV_SEQ,CH_DEV_SEQ)
DO UPDATE SET
DEV_MODEL_SEQ=#{item.dev_model_seq}
,MODL_CNT=#{item.combox_modl_cnt}::NUMERIC
,CRET_DT=NOW()
</foreach>
</insert>
이것도 기능적으로는 insert 부분인데 차이가 있다면
insert 할때 어떠한 조건에 의해 insert 가 안되는 상황이면 UPDATE를 하는 것이다.
MySQL 에서는 ON DUPLICATE KEY 를 사용하지만
POSTGRESQL 에서는 ON CONFLICT / DO UPDATE SET 을 사용한다.
처음에 upsert 찾아보다가 on duplicate key가 있길래 그거 적용하는데 왜 안되나 해서 봤는데
자신이 사용하는 DB를 잘봐야한다...거기서 거기인줄 알았는데 차이가 있다 ㅠ
전체를 foreach로 묶었고 separator 구분자는 " ; " 설정해서 마지막에 ; 이 들어가서 쿼리가 동작하도록 해야한다.
ON CONFLICT() 부분에는
ON CONFLICT column_name : 특정 컬럼명을 기준으로 체크함(pk기준)
ON CONFLICT ON CONSTRAINT ~ : 테이블 생성시 만든 constraint명을 기준으로 체크
ON CONFLICT WHERE predicate : UNIQUE INDEX 생성 시 사용
위의 confilct 부분에서 충돌할경우 , 뭔가 조건에 안맞는경우 아래와 같은 동작을 수행하도록 할 수 있다.
DO UPDATE SET : UPDATE 동작
DO NOTHING : 아무것도 동작안하기
나같은 경우는 위와 같이 2개의 pk가 중복되면
해당 테이블의 3개의 컬럼을 list에 있는 값으로 update하도록 설정했다.
이렇게 하면 pk가 없으면 그냥 insert 하고 중복되면 update하도록 할 수 있다.
등록과정을 거치고 추후에 수정할때(사용자가 기존 값을 변경하거나 새로운 값을 추가할경우) upsert 를 사용한다.
아 그리고 찾아보니까 postgresql 9.5 이상부터 사용가능하다고 하니 버젼확인 잘해야한다.
'프로그래밍 > Web 개발' 카테고리의 다른 글
Eclipse - maven project 배포 (0) | 2022.03.02 |
---|---|
[JS] Modal 사용하기 (0) | 2022.03.02 |
[Mybatis/postgresql] VO 활용하여 파라미터 가져와서 DB 처리하기 (0) | 2022.02.03 |