collection

반응형

시작하기에 앞서 참고 자료

 

*ibatis iterate문 지원 태그

 

property : 파라미터명

prepend : 쿼리로 쓰일 문자

open : 구문이 시작될때 삽입할 문자열

close : 구문이 종료될때 삽입할 문자열

conjunction : 반복되는 사이에 출력할 문자열

 


*ibatis : MyBatis  버전


MyBatis foreach문 지원 태그

 

collection : 전달받은 인자. List or Array 형태만 가능

item : 전달받은 인자 값을 alias 명으로 대체

open : 구문이 시작될때 삽입할 문자열

close : 구문이 종료될때 삽입할 문자열

separator : 반복 되는 사이에 출력할 문자열

index : 반복되는 구문 번호이다. 0부터 순차적으로 증가

 

즉, ibatis iterate -> MyBatis foreach로 변경됐습니다.

 

 

문법


<foreach collection="List or Array" item="alias" ></foreach>

 

사용 예시

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

-참고 자료 MyBatis 공식 사이트

 

 

1. 배열 예시

 

공통 배열 데이터 

String[] userArray = {"1","2","3"}

 

1-1. 배열 파라미터를 Map을 통해 넘겼을 경우

 

DAO

public List<Members> getAuthUserList(String[] userArray) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("userArray",userArray);
		return sqlSession.selectList("getAuthUserList", map);
}

user-Mapper.xml

<select id="getAuthUserList"  resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="userArray" item="arr" open="(" close=")" separator=",">
 #{arr}
</foreach>
ORDER BY m.authority;
</select>

 

※ 주의 : collection을 꼭! 넘겨주는 배열 변수 값과 동일하게 작성하셔야 합니다.


1-2. 배열 파라미터를 직접 넘겼을 경우

 

DAO

public List<Members> getAuthUserList(String[] userArray) {
		return sqlSession.selectList("getAuthUserList", userArray);
}

user-Mapper.xml

<select id="getAuthUserList"  resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="array" item="arr" open="(" close=")" separator=",">
 #{arr}
</foreach>
ORDER BY m.authority;
</select>

※ 주의 : collection을 꼭! "array"로 작성하셔야 합니다.

 

 

 

2. 리스트 예시

 

공통 리스트 데이터 

List<Members> chkList = userService.getUserList(); //SELECT * FROM members 결과값

 

2-1. 리스트 Map을 통해 넘겼을 경우

 

DAO

public List<Members> getListTest(List<Members> chkList) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("chkList",chkList);
		return sqlSession.selectList("getListTest", map);
}

user-Mapper.xml

<select id="getListTest" resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="chkList" item="item" open="(" close=")" separator=",">
 #{item.authority}
</foreach>
ORDER BY m.authority;
</select>

리스트 안에 뽑고 싶은 결괏값을 {key.value} 형태로 뽑으시면 됩니다.

※ 주의 : collection을 꼭! 넘겨주는 리스트 변수 값과 동일하게 작성하셔야 합니다.

 


2-2. 리스트 파라미터를 직접 넘겼을 경우

 

DAO

public List<Members> getListTest(List<Members> chkList) {
		return sqlSession.selectList("getListTest", chkList);
}

user-Mapper.xml

<select id="getListTest" resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="list" item="item" open="(" close=")" separator=",">
 #{item.authority}
</foreach>
ORDER BY m.authority;
</select>

리스트 안에 뽑고 싶은 결괏값을 {key.value} 형태로 뽑으시면 됩니다.

※ 주의 : collection을 꼭! "list"로 작성하셔야 합니다.

 

 

 

공통 설명

1. 먼저 리스트/배열 변수 값을 collection에 넣어주고, item이라는 설정으로 별칭 설정을 해준다.

2. 리스트/배열의 값이 시작하기 전 open="(" 이 설정돼있으므로'(' (열린 괄호)가 열리게 되고

3. 리스트/배열의 값이 한 번씩 반복문을 거칠 때마다 separator 옵션에 있는 ', '(콤마)가 찍히게 된다.

4. 반복이 끝나면 close=")" 설정이 있으므로 ')' (닫힌 괄호)가 쓰인다.


더욱 자세한 이해를 위해 실전 예시

 

문법에 들어가기 앞서, 공통 테이블 예시

예시 테이블

예시 테이블 02

 

[배열(array)] 예시 1. 멤버 테이블에서 체크박스에 따라 권한별 보여주는 기능 만들기

더보기

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> 
<meta charset="UTF-8">
<script type="text/javascript">
var chkArray = new Array;
$(document).ready(function(){

	getAuthUserList($("input[name=chk_authority]:checked").val());
	
$("input[name=chk_authority]").change(function(){

	var chk = "";
	chkArray = [];
	
	$("input[name=chk_authority]:checked").each(function() {
	
		chkArray.push($(this).val());

	});
	
		
	if(chkArray.length == 0){
		$("#userList").empty();
	} else {
		getAuthUserList(chkArray);
	}
	
	});

});

function getAuthUserList(chkArray){
	
$.ajax({
		
		url : "/user/getAuthUserList",
		data : { chkArray : chkArray },
		traditional : true,
		async: true,
		success : function(data){
			var html = '';
			
			for(key in data){
			html += '<tr>';
			html += '<td>'+data[key].userId+'</td>';
			html += '<td>'+data[key].nickname+'</td>';
			html += '<td>'+data[key].name+'</td>';
			html += '</tr>';
			}
			
			
			$("#userList").empty().append(html);
			
		}
	})
	
}

</script>
</head>
<body>

<div>
유저 등급별 보기<br>
<input type="checkbox" name="chk_authority" value="0" checked="checked">실버
<input type="checkbox" name="chk_authority" value="1">골드
<input type="checkbox" name="chk_authority" value="2">플래티넘
<input type="checkbox" name="chk_authority" value="3">다이아
<input type="checkbox" name="chk_authority" value="4">마스터
<input type="checkbox" name="chk_authority" value="5">그랜드마스터

<table>
<thead>
<tr>
<th>아이디</th>
<th>닉네임</th>
<th>권한</th>
</tr>
</thead>
<tbody id="userList">
</tbody>
</table>
</div>
</body>
</html>

Controller

@RequestMapping("user/getAuthUserList")
	public @ResponseBody List<Members> getAuthUserList(String[] chkArray) {
		List<Members> result = userService.getAuthUserList(chkArray);
		return result;
}

Service

List<Members> getAuthUserList(String[] chkArray);

Servicelmpl

@Override
public List<Members> getAuthUserList(String[] chkArray) {
		return userDAO.getAuthUserList(chkArray);
}

DAO

public List<Members> getAuthUserList(String[] chkArray) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("chkArray",chkArray);
		return sqlSession.selectList("getAuthUserList", map);
}

user-Mapper.xml

<select id="getAuthUserList"  resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="chkArray" item="item" open="(" close=")" separator=",">
 #{item}
</foreach>
ORDER BY m.authority;
</select>

쿼리 결과

SELECT m.*,a.name FROM members AS m  
JOIN authority AS a ON m.authority = a.authority 
WHERE m.authority IN

(체크박스 수에 따른 값)
#('1','2','3')
#('2','3')
ORDER BY m.authority;

쿼리 결과 설명

1. 먼저 배열 변수 값을 collection에 넣어주고, item이라는 설정으로 별칭 설정을 해준다.

2. 배열의 값이 시작하기 전 open="(" 이 설정돼있으므로'(' (열린 괄호)가 열리게 되고

3. 배열의 값이 한 번씩 반복문을 거칠 때마다 separator 옵션에 있는 ', '(콤마)가 찍히게 된다.

4. 반복이 끝나면 close=")" 설정이 있으므로 ')' (닫힌 괄호)가 쓰인다.

 

View

 

 


[리스트(List)] 예시 2. 멤버 테이블에서 데이터 넘겨받아 리스트로 반복문 돌리기

더보기

Controller

@RequestMapping("user/getUserList")
	public @ResponseBody List<Members> getUserList() {
		List<Members> result = userService.getUserOne();
		List<Members> foreachTest = userService.getListTest(result);
		System.out.println(foreachTest);
		return result;
}

Service

List<Members> getListTest(List<Members> result);

Servicelmpl

@Override
public List<Members> getListTest(List<Members> result) {
		return userDAO.getListTest(result);
}

DAO

public List<Members> getListTest(List<Members> chkList) {
		HashMap<String, Object> map = new HashMap<String, Object>();
		map.put("chkList",chkList);
		return sqlSession.selectList("getListTest", map);
}

user-Mapper.xml

<select id="getListTest" resultType="members">
SELECT m.*,a.name FROM members AS m 
JOIN authority AS a ON m.authority = a.authority
WHERE m.authority IN
<foreach collection="chkList" item="item" open="(" close=")" separator=",">
 #{item.authority}
</foreach>
ORDER BY m.authority;
</select>

쿼리 결과

SELECT m.*,a.name FROM members AS m  
JOIN authority AS a ON m.authority = a.authority 
WHERE m.authority IN

(체크박스 수에 따른 값)
#('1','2','3')
#('2','3')
ORDER BY m.authority;

쿼리 결과 설명

1. 먼저 리스트 변수 값을 collection에 넣어주고, item이라는 설정으로 별칭 설정을 해준다.

2. 리스트의 값이 시작하기 전 open="(" 이 설정돼있으므로'(' (열린 괄호)가 열리게 되고

3. 리스트의 값이 한 번씩 반복문을 거칠 때마다 separator 옵션에 있는 ', '(콤마)가 찍히게 된다.

4. 반복이 끝나면 close=")" 설정이 있으므로 ')' (닫힌 괄호)가 쓰인다.

 

예제 SQL 파일 제공


[MyBatis] foreach문 예제.sql
0.00MB

 

 

반응형
반응형

Java Collections Framework(JCF)

 

Java에서 컬렉션(Collection)이란 데이터의 집합, 그룹을 의미하며 

 

JCF(Java Collections Framework)는 이러한 데이터, 자료구조인 컬렌션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공한다.

 

다음은 Java 컬렌션 프레임워크의 상속구조를 나타낸다.

상위 인터페이스 크게 분류

List

Set

Queue

 

그리고 Map 같은 경우는 Collection 인터페이스를 상속 받고 있지 않지만 Collection 으로 분류됨

 

1. Set 인터페이스

 

순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.

  • HashSet
    - 가장빠른 임의 접근 속도
    - 순서를 예측할 수 없음

문법(복붙용)

import java.util.HashSet;

public class CollectionTemp {

	public static void main(String[] args) {
		
			HashSet<String> hs = new HashSet<String>(); // HashSet 선언
		
			hs.add("홍길동");
			hs.add("아기장수 우투리");
			hs.add("홍길동");
			hs.add("춘향");

			System.out.println(hs);

			
	}

}

//결과 [홍길동,춘향,아기장수 우투리]
// 홍길동을 두번 넣었음에도 한번만 값이 넣어져있다. (HashSet의 특성인 중복값 무시)
  • TreeSet
    - 정렬방법을 지정할 수 있음
import java.util.TreeSet;

public class CollectionTemp {

	public static void main(String[] args) {
		
			TreeSet<String> ts = new TreeSet<String>();
			
			   	ts.add("apple");
		        ts.add("airplane");
		        ts.add("alien");
		        ts.add("disc");
		        ts.add("dance");
		        
		        System.out.println(ts.headSet("b"));
		        System.out.println(ts.subSet("a", "al"));
		        System.out.println(ts.tailSet("c"));
			
	}

}
//결과 : [airplane,alien,apple] ts.headSet("b") 시작이 b 보다 작은 a로 시작하는 데이터들
//		 [airplane]  ts.subSet("a", "al") a ~ al 사이에 있는 데이터 from ~ to 
//		 [dance,disc] ts.tailSet("c") headSet의 반대 시작이 c 보다 큰 d부터 시작하는 데이터들

 

HashSet vs TreeSet 

 

HashSet과 TreeSet 모두 중복을 허용하지 않고 순서가 없는 컬렉션

1. 구현 방식
 - HashSet은 해싱을 이용하여 구현
 - TreeSet은 이진탐색트리를 이용하여 구현

2. 속도 비교
 - HashSet > TreeSet
 - 해싱이 이진탐색트리보다 빠르다

3. 정렬 기능
 - HashSet < TreeSet
 - 이진탐색트리를 이용했기 때문에 데이터 정렬이 가능 (Comparator 이용)

 

성능

HashSet > TreeSet > LinkedHashSet

 

예시) 이런 상황을 가정해보겠습니다.

어떤 웹 사이트에서 하루에 접속하는 사람들 수를 구하고자 합니다.

접속하는 IP를 세면 되겠죠.

근데 한사람이 여러번 접속하면 한 IP가 여러번 찍힐 것입니다.

이건 한번으로 카운트 해줘야 제대로 된 접속자 수를 구할 수 있습니다.

이럴 때 쓰는게 Set입니다.

그냥 수학에서 집합 이라고 보시면 됩니다.

 

2. List 인터페이스

 

순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.

  • LinkedList
    - 양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 데이터의 위치정보만 수정하면 되기에 유용
    - 스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임
  • Vector
    - 과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화처리가 일어나 비교적 성능이 좋지 않고 무거워 잘 쓰이지 않음
  • ArrayList
    - 단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어남

 

3. Map 인터페이스

 

키(Key), 값(Value)의 쌍으로 이루어진 데이터으 집합으로,

순서는 유지되지 않으며 키(Key)의 중복을 허용하지 않으나 값(Value)의 중복은 허용한다.

  • Hashtable
    - HashMap보다는 느리지만 동기화 지원
    - null불가
  • HashMap
    - 중복과 순서가 허용되지 않으며 null값이 올 수 있다.
  • TreeMap
    - 정렬된 순서대로 키(Key)와 값(Value)을 저장하여 검색이 빠름

 

 

반응형

+ Recent posts