SimpleJdbcTemplate 클래스는

JdbcTemplate 과 NamedParameterJdbcTemplate 을 합쳐 놓은 템플릿 클래스로서

이름 기반의 파라미터 설정인덱스 기반의 파라미터 설정을 모두 지원한다.

이름 기반의 파라미터를 설정할 때에는 Map과 SqlParameterSource 두 가지 방법을 모두 사용할 수 있다.

SimpleJdbcTemplate 클래스가 제공하는 주요메소드는 아래와 같다. 



Method Summary

<T> List<T> 
query(String sql, RowMapper<T> rm, Map<String,?> args)
<T> List<T>
query(String sql, RowMapper<T> rm, Object... args) 
<T> List<T>
query(String sql, RowMapper<T> rm, SqlParameterSource args) 




int queryForInt(String sql, Object... args) 
int queryForInt(String sql, SqlParameterSource args) 



List<Map<String,Object>> queryForList(String sql, Object... args)
List<Map<String,Object>> queryForList(String sql, SqlParameterSource args) 



<T> T
queryForObject(String sql, RowMapper<T> rm, Object... args) 
<T> T
queryForObject(String sql, RowMapper<T> rm, SqlParameterSource args)  



int update(String sql, Object... args)
int update(String sql, SqlParameterSource args) 



이렇게 받은 template을 처리해야될 방법에 따라 잘 만들어진 메소드를 고르기만 하면 된다.

가장 기본인 DB 에서 모든 글을 긁어온다음 list 를 만들어서 보여주는 걸 해보자.
나는  List query(String sql, RowMapper<T> rm, Object... args) 이놈을 골랐다!

그럼이제 리스트 를 보여주기위한 작업을 해보자.


1.  servlet.xml 에 SimpleJdbcTemplate 을 등록한다. (http://winmargo.tistory.com/116 참고)


2. 처리를 수행하는 구현클래스에서 SimpleJdbcTemplate 을 이용해서 Statement 작업을 구현하면 끝이다.
  


구현클래스를 보자
     private SimpleJdbcTemplate template = null;
	
   
	
	
	//모든글을 몽땅 가져온다.
	@Override
	public List getArticles(int index) {
		
						
		sql =  "SELECT * FROM (SELECT ROWNUM rnum,A.* FROM " +
				"(SELECT * FROM margo ORDER BY article_num DESC) A ) "
				+ "WHERE rnum BETWEEN ? AND ?";
	
					
			
		return template.query( sql, 
				
				   				   new ItemBeanRowMapper(),
								   new Object[]{ index, (index + 10)});
		
	}
	
 

코드를 보면 17 라인에 return 값에 simpleJdbcTemplate을 줬다. 리턴값이 List


첫 번째 인자에 sql쿼리를 넣고,

두번째에 3라인에 선언한 ItemBeanRowMapper() 를 넣어주고 있다.(아래에서 자세히)

세 번째 인자에는 쿼리문 안에 있는 '?' 에 대응되어 들어갈 값 2개가 있다. ? 순서와 개수에 맞게 넣어주면 된다.(이것이 인덱스 방식이다)
  
  - 쿼리에 값을 넣는 방법은 두가지가 있는데, 인덱스 파라미터 방식과, 네임드 파라미터(이름 기반) 방식이 있다.
     
     ? 에 순서대로 대입하는 방식은 Index 기반 파라미터 방식이고,
     
      넣어줄 값을 들고있는 맵이나, 빈클래스의 변수을 ':' 콜론과 같이 쓰면 값이 들어가는데
     이 방식이 이름 기반의 파라미터 방식이다.  




기본적인 동작 방식은 template 이 sql쿼리문에 값을 넣고, Statement 처리를 한후

19라인에 있는 ItemBeanRowMapper()  클래스를 이용해서 ResultSet 을 처리한후

리턴되어오는 어떤 클래스(여기서는 Bean파일이다) 를  List 에 자동으로 담은후

그 List 를 리턴해준다.


여기서 중요한건 19라인에 ItemBeanRowMapper()  클래스 이다.

이 클래스는 위설명과 같이 쿼리수행후 리턴된 다수개의 레코드들을 모은 ResultSet에서

레코드컬럼과, 자바빈 변수를 Mapping 시켜

한 개의 레코드를 하나의 자바빈 으로 만들어서 return 시켜주면

Template 이 자동으로 List 에 담아서 Template 수행후 마지막으로 리턴 시킨다.

ItemBeanRowMapper() 클래스는 RowMapper<T> 를 구현해야한다.


ItemBeanRowMapper 클래스를 보자


package Spring;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

public class ItemBeanRowMapper implements RowMapper {

	
	
	@Override
	public ItemBean mapRow(ResultSet rs, int rowNum) throws SQLException {
		
		ItemBean itemBean = new ItemBean();
		
		String str ="";
				
		itemBean.setArticle_num(rs.getInt("article_num"));
		itemBean.setId(rs.getString("id"));
		itemBean.setTitle(rs.getString("title"));
		itemBean.setCount(rs.getInt("hit"));
		itemBean.setDepth(rs.getInt("depth"));
		itemBean.setWrite_date(rs.getTimestamp("write_date"));
		itemBean.setFileName(rs.getString("filename"));
		
		int cnt = itemBean.getDepth();
		
		while( cnt > 0){
			
			str += "    ";
			cnt--;
		}

		itemBean.setSpace(str);
		
		return itemBean;
	}

}

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
메소드 코드를 대충보면 딱 알수 있을만큼 간단하다.  

mapRow(ResultSet rs, int rowNum)

메소드를 오버라이딩 하면서 인자로  ResultSet 과 정수하나를 주는데

뒤에정수는 레코드 개수이다.

사용할 일이 있을때 사용하면된다.

빈파일에 컬럼을 매핑시킨후, 빈파일을 리턴하면

template 이 자동으로 List 에 쑥쑥 넣는다.


수가지의 방식이 있는데, 일단은 제일 요긴하고 잘쓰일 방법으로 구현해보았다.


다음편에는 다른 여러가지 구현방식을 알아보겠음



YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


mysql-인덱스를 생성하는 방법]

 

인덱스 만들기

1. 추가하여 만들기

    CREATE INDEX <인덱스명> ON <테이블명> ( 칼럼명1, 칼럼명2, ... );

 

2. 테이블 생성시 만들기

    끝에....

    INDEX <인덱스명> ( 칼럼명1, 칼럼명2 )

    UNIQUE INDEX <인덱스명> ( 칼럼명 )  --> 항상 유일해야 함.

 

3. 이렇게도 생성한다

    ALTER TABLE <테이블명> ADD INDEX <인덱스명> ( 칼럼명1, 칼럼명2, ... );

 

4. 인덱스 보기

    SHOW INDEX FROM <테이블명>;

 

5. 인덱스 삭제

    ALTER TABLE <테이블명> DROP INDEX <인덱스명>;

 

///////////////////////////////////////////////////////////////////

 

인덱스 파일은 "테이블명.MYI"파일로 DB 디렉토리 아래 저장..

 

mysql> create table test1( 
    -> var1 int not null auto_increment primary key,
    -> var2 int not null,
    -> var3 char(30) not null,
    -> index idx1(var1) <-- 인덱스지정
    -> );
Query OK, 0 rows affected (0.06 sec)

 

mysql> desc test1 <-- index는 MUL로 표시된다.

mysql> show keys from test1; <-- key 볼 수 있다.
====================================================

 

mysql> CREATE INDEX idx1 ON test1(var1);
Query OK, 0 rows affected (0.25 sec)
Records: 0  Duplicates: 0  Warnings: 0

 

제거는..DROP INDEX or Alter table

 

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


많은 분들이 mysql 테이블을 생성할 때 index를 주는데, 실제로 보니까 index를 잘못주는 경우가 많더군요. 

1. 인덱스를 검사하는 법. 
explain select * from Table_Name where A='a' and B='b' order by C,D,E ; 
해당 쿼리문이 인덱스를 타는지 안타는지 알기 위해서는 쿼리문 앞에 explain을 붙여주면 인덱스를 타는지 안타는지 알 수 있습니다. 
type의 결과값이 ALL일 경우 인덱스를 타지 않고 있습니다. range,index등일 때 인덱스를 타고 있습니다.(system,const,eq_ref,range,index,ALL,fulltext) 
key의 값이 해당 쿼리문이 타고 있는 인덱스입니다. 

2. 경우의 수가 작은 것은 인덱스를 타지 않습니다. 
가령 특정 테이블에서 성별을 구분하는 테이블이 있고, 이 테이블에서 성별로 구분해서 보여주는 경우가 많다고 해서 성별을 나타내는 필드에 인덱스를 걸어주어도 인덱스를 타지 않습니다. 
인덱스는 결과값이 1/3미만일 경우에만 인덱스를 탑니다. 그러므로 성별같은 경우에는 인덱스를 걸어주는 것이 테이블의 용량만 키우는 결과이기 때문에 인덱스를 걸어주지 않는 것이 좋습니다. 
이것은 PRIMARY KEY에도 적용이 됩니다. 
Table_Name 테이블에서 No 필드가 Primary Key, A 필드에 Index가 걸려있고, 데이타수가 30000개일 경우. 
select * from Table_Name where No>0 and A>0; // 인덱스 안탐. 
select * from Table_Name where No>20000 and A>0; // Primary 인덱스를 탐. 
select * from Table_Name where No>0 and A>20000; // A 인덱스를 탐. 

3. 인덱스는 하나만 탑니다. 
오라클등에서는 인덱스를 여러개 걸어주면 그것을 다 타지만 mysql에서는 인덱스를 하나밖에 타지 않습니다. 
가령 Table_Name 에서 A필드와 B필드, C필드에 인덱스를 걸어주고, 아래와 같은 쿼리문을 날립니다. 
select * from Table_Name where A='a' and B='b' and C='c'; 
이럴경우 세개의 인덱스중 하나의 인덱스만 탑니다. 

4. 결합인덱스 사용법. 
특정 테이블에서 동일한 쿼리문을 주로 사용하고 그 쿼리문이 아래와 같을 경우... 
select * from Table_Name where A='a' and B='b' and C='c'; 
이경우 이 세개의 인덱스를 전부 타기 위해서는 결합인덱스를 걸어줘야 됩니다. 
ALTER TABLE Table_Name ADD INDEX (A,B,C); 
이렇게 인덱스를 줄 경우에 세개의 필드를 정렬해서 하나의 인덱스를 생성하기 때문에 해당인덱스를 탈 수 있습니다. 

5. order by 에서 사용하는 인덱스. 
select * from Table_Name order by A; -> 이경우에 A인덱스를 탑니다. 
select * from Table_Name where B='b' order by A; -> 이경우 B인덱스만 탑니다. 
이경우에 두개의 인덱스를 다 타게 하려면 결합인덱스로 (A,B)를 생성시키고, A의 조건을 where 문에 지정을 해줍니다.(이부분은 사실 저도 조금 헷갈리는 부분입니다. 어쨌든 며칠동안 인덱스를 살펴본 결과 이렇게 해줘야 될거 같아서 일단 적습니다. ㅠ.ㅠ) 

6. 검색에서 사용하는 인덱스. 
보통 본문검색을 할 때 [where A like '%a%' ]와 같은 방식으로 조건을 주는데, 이경우 인덱스를 타지 않습니다. 가끔보면 검색에 주로 사용되는 필드에 인덱스를 거는 경우를 볼 수 있는데, 쓸데없는 짓입니다. 
단, [where A like 'a%']와 같이 검색을 하는 경우에는 인덱스를 탑니다. 

7. join문에서의 인덱스. 
개인적으로 join문을 잘 사용하지 않는데, 그 이유가 join문을 사용할 경우 속도문제 때문이었습니다. 지금은 join문에서 인덱스를 타는 경우에 대해서 테스트해보고, 이것은 나중에 결과를 보고 글을 올려보도록 하겠습니다.

 

www.nuno21.net


YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST