ORACLE인 경우 다중 insert
일단 오라클에서는 INSERT ALL 구문으로 한 번에 여러 개의 데이터를 삽입할 수 있다.
관련된 내용은 이전에 올렸던 적이 있다.
https://smile-place.tistory.com/entry/ORACLE-INSERT-ALL-%EA%B5%AC%EB%AC%B8?category=999160
Mybatis에서도 INSERT ALL 구문을 활용하면 된다.
여기서 INSERT 해 줄 테이블은 LOGIN_INFO라는 아래의 컬럼을 가진 테이블이다.
* LOGIN_INFO
SITE | ID | PW |
아래와 같은 배열이 있는 json 데이터를 파라미터로 받았다고 가정하자.
{
"site": "main",
"login_data": [ { "id": "test1", "pw": "12345" },
{ "id": "test2", "pw": "67890" },
{ "id": "test3", "pw": "1234567890" } ]
}
위의 데이터를 Map에 담아주는데 배열의 경우 LIST에 담아서 Map에 다시 담아준다.
아래와 같이 Controller를 작성해주면 된다.
@RequestMapping(value="URL이 들어가는 자리")
public void MemberInfo( @RequestBody HashMap<String, Object> params ) throws Exception {
//데이터를 담아줄 map 생성
HashMap< String , Object > map = new HashMap< String , Object >();
//일반 파라미터는 map에 그대로
put map.put( "site" , params.get( "site" ) );
//배열 파라미터는 list에 put하고 그 list를 map에 put
List<Map<String,Object>> memberList = (List<Map<String, Object>>) params.get("login_data");
map.put( "memberList" , memberList); }
여기서 site 파라미터 값은 그대로, id와 pw 값은 각각 다르게 여러 번, 이 경우에는 배열의 길이가 3개이므로 3번 insert 해주는 경우 mapper에서 다음과 같이 쓸 수 있다.
<update id="insertLoginInfo" parameterType="java.util.HashMap">
<foreach collection="memberList" item="item" separator=" " open="INSERT ALL" close="SELECT * FROM DUAL">
INTO LOGIN_INFO(SITE, ID, PW) VALUES(
#{site}, #{item.id}, #{item.pw}
)
</foreach>
</update>
주의해야 하는 점은 실제로는 INSERT를 수행하지만 이 방법을 쓰는 경우 UPDATE 태그를 써야한다는 것이다.
간단하게 foreach 태그를 보면
collection : map에 담겨있는 list의 이름
item : 반복문 변수(자바 for문에서의 i같은 역할)
separator : 반복될 때 구분값
open : foreach문 안의 구문의 맨 앞에 붙는 것
close : foreach문 안의 구문의 맨 뒤에 붙는 것
foreach문 안에서 배열에서 반복되는 값 앞에 item에서 설정한 이름을 붙여준다.
INSERT ALL의 경우 서브쿼리가 필요하므로 close부분이 꼭 필요하다.
테이블에는 결과적으로 아래와 같이 데이터가 삽입된다.
SITE | ID | PW |
main | test1 | 12345 |
main | test2 | 67890 |
main | test3 | 1234567890 |
하지만 이 때 반복해서 삽입하는 테이블에 시퀀스가 있고 그 시퀀스가 PK거나 UNIQUE 제약조건이 있다면 이 방법은 사용할 수가 없다.
이럴 때는 INSERT ALL 대신 UNION ALL 구문을 사용해서 INSERT 해줘야 한다.
이번에 INSERT 해 줄 테이블은 시퀀스를 넣을 컬럼을 추가하여 아래와 같다고 가정하자.
* LOGIN_INFO
MEMBER_NUM | SITE | ID | PW |
시퀀스는 마이바티스에서 설정하면 되기 때문에 파라미터로 받은 json 데이터와 Controller는 위와 같이 작성해주면 된다.
시퀀스명은 MEMBER_NUM_SEQ이라고 가정하자.
mapper 부분은 아래와 같이 작성해준다.
<insert id="insertLoginInfo" parameterType="java.util.HashMap">
INSERT INTO LOGIN_INFO(MEMBER_NUM, SITE, ID, PW)
SELECT MEMBER_NUM_SEQ.NEXTVAL, A.*
FROM (
<foreach collection="memberList" item="item" separator="UNION ALL ">
SELECT #{site} AS SITE, #{item.id} AS ID, #{item.pw} AS PW FROM DUAL
</foreach>
) A
</insert>
아까 INSERT ALL 구문과는 다르게 UNION ALL의 경우 insert 태그를 사용해준다.
시퀀스 부분을 foreach문 바깥에 빼주고 작성해주는데
아까와는 다르게 foreach에는 collection, item, separator 항목만 써주면 된다.
한 개 이상이 반복될 수 있으므로 separator에는 UNION ALL을 써서 반복적으로 사용할 수 있게 한다.
ALL 뒤에 띄어쓰기가 있다는 것도 빼먹으면 안된다.
테이블에는 결과적으로 아래와 같이 데이터가 삽입된다.
MEMBER_NUM | SITE | ID | PW |
1 | main | test1 | 12345 |
2 | main | test2 | 67890 |
3 | main | test3 | 1234567890 |
MYSQL인 경우 다중 insert
MYSQL에서 다중 insert하는 경우에는 ORACLE과는 문법이 다르기 때문에 mapper 부분을 조금 다르게 작성해야 한다.
ORACLE보다는 MYSQL이 더 간단하게 해결할 수 있다.
json으로 받는 파라미터, Controller부분은 위의 정보와 동일하다는 전제하에 LOGIN_INFO라는 테이블에 insert를 해보자.
* LOGIN_INFO
SITE | ID | PW |
MYSQL에서는 INSERT INTO 테이블명(컬럼1, 컬럼2...) VALUES (값1, 값2...), (값1-1, 값2-1...) 의 방식으로 다중 INSERT가 가능하기 때문에 Mybatis 작성도 위와 같이 해주면 된다.
mapper 부분은 아래와 같은 형식으로 작성해준다.
<insert id="insertLoginInfo" parameterType="java.util.HashMap">
INSERT INTO LOGIN_INFO(SITE, ID, PW) VALUES
<foreach collection="memberList" item="item" separator=" , ">
(#{site}, #{item.id}, #{item.pw})
</foreach>
</insert>
결과적으로 테이블에는 아래와 같이 데이터가 삽입된다.
SITE | ID | PW |
main | test1 | 12345 |
main | test2 | 67890 |
main | test3 | 1234567890 |
'개발 > JAVA' 카테고리의 다른 글
[JAVA] 자바에서 OPEN API 연결하기 (0) | 2021.12.21 |
---|---|
JDOM(Java Document Object Model) 관련 (0) | 2021.11.18 |
[JAVA] indexOf() / lastIndexOf() (0) | 2021.11.16 |
[SPRING] 파라미터 속 json 배열 꺼내쓰기 (0) | 2021.10.08 |
[SPRING] Mybatis에서 insert할 때 null 처리하기 (0) | 2021.10.07 |