Jam's story

[Spring] NamedParameterJdbcTemplate 본문

Spring

[Spring] NamedParameterJdbcTemplate

애플쩀 2022. 7. 18. 11:35

springMVCJDBC2 프로젝트 사용

 

📌여러 개의 파라미터가 있는 쿼리를 실행할 때는 JdbcTemplate보다 NamedParameterJdbcTemplate

📌NamedParameterJdbcTemplate은 DataSource 객체를 필요

📌JdbcTemplate클래스와 동일한 이름의 메소드를 제공하지만,

 

차이점은 인덱스기반의 파라미터가 아니라 이름기반의 파라미터 값을 설정하기 위해

Map이나 SqlParameterSource를 전달받는다는 것이다.

 

SqlParameterSource는 인터페이스이기 때문에
구현클래스인 BeanPropertySqlParameter 와 MapSqlParameterSource를 사용한다.

MapSqlParameterSource 클래스는 addValue()메소드를 이용하여 파라미터의 이름과 값을 설정해준다.

 

 

1️⃣dispatcher-service.xml

<!-- NamedParameterJddbcTemplate 템플릿 클래스 사용 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

 

2️⃣

NoticeDao.java 와 MemberDao.java 를 복사해서  NLNoticeDao.java ,  NLMemberDao.java 생성 

NoticeDao.java 와 MemberDao.java 를 인터페이스 생성 

 

3️⃣-1️⃣

 

 NamedParameterJdbcTemplate사용해보기

@Repository    
public class NLMemberDao implements MemberDao{
	
	   @Autowired
	   private NamedParameterJdbcTemplate jdbcTemplate;

3️⃣-2️⃣

 

String sql = "SELECT * " + "FROM MEMBER" + " WHERE ID=:id ";
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("id", id); //이곳의 이름으로 sql의 ?대신 이곳의 :이름으로
✔️queryForObject()
SQL의 DML 중 SELECT를 실행했을 때 하나의 객체(Object) 결과 값이 나올 때 사용하는 메소드이다.

✔️RowMapper
JDBC의 인터페이스인 ResultSet에서 원하는 객체로 타입을 변환하는 역할

✔️BeanPropertyRowMapper
DB의 컬럼명과 bean 객체의 속성명이 일치하다면 BeanPropertyRowMapper를 이용하여 자동으로 객체변환을 할 수 있습니다.
JdbcTemplate는 DAO객체에서 DB와 연동하기 위해 SQL 연산들을 수행 할 수 있도록 도와주는 기술인데,

update()는 SQL 연산을 통해 데이터베이스를 갱신시켜줄 때(INSERT, DELETE, UPDATE) 사용하는 메소드이다.
SQL과 함께 가변인자로 선언된 파라미터를 제공해주면 된다.
쿼리 실행결과로 변경된 행의 개수를 리턴한다.
package newlecture.dao;

import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.stereotype.Repository;

import newlecture.vo.Member;
@Repository    
public class NLMemberDao implements MemberDao{
	
	   @Autowired
	   private NamedParameterJdbcTemplate jdbcTemplate;
	
	   @Override
	public Member getMember(String id) throws ClassNotFoundException, SQLException
	{
		String sql = "SELECT * "
				+ "FROM MEMBER"
				+ " WHERE ID=:id ";
		  MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		  parameterSource.addValue("id", id); //이곳의 이름으로 sql의 ?대신 이곳의 이름으로 
		
		  //이렇게 한번에 쓸 수 있다. 
		 // MapSqlParameterSource parameterSource = new MapSqlParameterSource("id", id);

	        return jdbcTemplate.queryForObject(sql
	        		, parameterSource
	        , ParameterizedBeanPropertyRowMapper.newInstance(Member.class));
	}
	
	//회원가입메소드
	@Override
	public int insert(Member member) throws ClassNotFoundException, SQLException
	{
		String sql = "INSERT INTO MEMBER"
				+ "(ID, PWD, NAME, GENDER, BIRTH, IS_LUNAR, CPHONE, EMAIL, HABIT, REGDATE) "
				+ "VALUES(:id, :pwd, :name, :gender, :birth, :is_lunar, :cphone, :email, :habit ,SYSDATE)";
		 MapSqlParameterSource parameterSource = new MapSqlParameterSource();
		  parameterSource.addValue("id", member.getId()); 
		  parameterSource.addValue("pwd", member.getPwd()); 
		  parameterSource.addValue("name", member.getName()); 
		  parameterSource.addValue("gender", member.getGender()); 
		  parameterSource.addValue("birth", member.getBirth()); 
		  parameterSource.addValue("is_lunar", member.getIs_lunar()); 
		  parameterSource.addValue("cphone", member.getCphone()); 
		  parameterSource.addValue("email", member.getEmail());
		  parameterSource.addValue("habit", member.getHabit()); 
		
		     return jdbcTemplate.update (sql
		        		, parameterSource
		 );
		  
		
	}
}

 

3️⃣-3️⃣ 바로위의 NLMember.java의 insert() 부분을  BeanPropertySqlParameterSource를 사용하여 간편하게 바꿔보기

 

	@Override
	public int insert(Member member) throws ClassNotFoundException, SQLException
	{
		String sql = "INSERT INTO MEMBER"
				+ "(ID, PWD, NAME, GENDER, BIRTH, IS_LUNAR, CPHONE, EMAIL, HABIT, REGDATE) "
				+ "VALUES(:id, :pwd, :name, :gender, :birth, :is_lunar, :cphone, :email, :habit ,SYSDATE)";
	
		
		   SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(member);
		  return jdbcTemplate.update (sql
	        		, parameterSource );
}

 

 

 

4️⃣

NLNoticeDao.java

package newlecture.dao;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.stereotype.Repository;

import newlecture.vo.Notice;


//@Component
@Repository //noticeDao
public class NLNoticeDao implements NoticeDao {
   @Autowired
   private NamedParameterJdbcTemplate jdbcTemplate;
   
   
   //검색한 겨로가의 총 레코드 수를 반환하는 메서드
   @Override
   public int getCount(String field, String query) throws ClassNotFoundException, SQLException
   {
      String sql = "SELECT COUNT(*) CNT "
            + "FROM NOTICES "
            + "WHERE "+field+" LIKE :query";
      
      MapSqlParameterSource parameterSource = new MapSqlParameterSource();
      parameterSource.addValue("query",query);
      
        return  this.jdbcTemplate.queryForInt(
                  sql
                 , parameterSource    
                    );


   }
   
   //페이징처리
   @Override
   public List<Notice> getNotices(int page, String field, String query) throws ClassNotFoundException, SQLException
   {               
      
      int srow = 1 + (page-1)*15; // 1, 16, 31, 46, 61, ... an = a1 + (n-1)*d
      int erow = 15 + (page-1)*15; //15, 30, 45, 60, 75, ...
      
      String sql = "SELECT * "
            + " FROM("
            + "         SELECT ROWNUM NUM, N.* "
            + "         FROM ( "
            + "               SELECT * FROM NOTICES "
            + "               WHERE "+field+" LIKE ? ORDER BY REGDATE DESC"
            + "             ) N"
            + "      )"
            + "WHERE NUM BETWEEN ? AND ?";
      //테이블 컬럼명 == Notice DTO의 필드명 반드시 일치필수
      //RowMpper 구현 클래스
      //ResultSet
      Map<String, Object> paramMap = new HashMap<String,Object>();
      paramMap.put("query","%"+query+"%");
      paramMap.put("srow", srow);
      paramMap.put("erow",erow);
      
      List<Notice> list=this.jdbcTemplate.query(sql
                        ,paramMap
                        //,new BeanPropertyRowMapper<Notice>(Notice.class)
                        ,ParameterizedBeanPropertyRowMapper.newInstance(Notice.class)
                        );
      return list;
   }
   
   //공지사항 삭제
   @Override
   public int delete(String seq) throws ClassNotFoundException, SQLException
   {
      
      String sql = "DELETE NOTICES "
               + "WHERE SEQ= :seq";
      MapSqlParameterSource paramSource = new MapSqlParameterSource();
      paramSource.addValue("seq",seq);
      
      return this.jdbcTemplate.update(sql, paramSource);
   }
   
   //공지사항 수정
   @Override
   public int update(Notice notice) throws ClassNotFoundException, SQLException{
      
      String sql = "UPDATE NOTICES SET TITLE=:title, CONTENT=:content, FILESRC=:filesrc "
               + "WHERE SEQ=:seq";
      
      SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(notice);
      
      return this.jdbcTemplate.update(sql, parameterSource);
   }
   //공지사항 글보기
   @Override
   public Notice getNotice(String seq) throws ClassNotFoundException, SQLException
   {
      String sql = "SELECT * FROM NOTICES "
               + "WHERE SEQ= :seq";
      
      MapSqlParameterSource paramSource = new MapSqlParameterSource();
      paramSource.addValue("seq",seq);
      
      Notice notice = this.jdbcTemplate.queryForObject(
            sql
            ,paramSource
            ,ParameterizedBeanPropertyRowMapper.newInstance(Notice.class));
      
      return notice;
   }
   //공지사항 쓰기
   @Override
   public int insert(Notice notice) throws ClassNotFoundException, SQLException {

      String sql = "INSERT INTO NOTICES(SEQ, TITLE, CONTENT, WRITER, REGDATE, HIT, FILESRC) "
            + "VALUES( (SELECT MAX(TO_NUMBER(SEQ))+1 FROM NOTICES), :title, :content, :writer, SYSDATE, 0, :filesrc)";
      
      SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(notice);
      
      return this.jdbcTemplate.update(sql, parameterSource);
   }
}

 

 

 

 

'Spring' 카테고리의 다른 글

[Spring] 스프링 트랜잭션 격리성  (0) 2022.07.19
[Spring] 트랜잭션  (0) 2022.07.18
[Spring] JDBC  (0) 2022.07.17
[Spring] 파일업로드  (0) 2022.07.15
[Spring] 스프링 파일 업로드  (0) 2022.07.14
Comments