반응형

아래와 같은 jsp 소스가 있습니다.


<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>taglib</title>
</head>
<body>

</body>
</html>


네... 스프링 커스텀 태그를 사용하려고 합니다.


이 페이지를 불르면 톰켓 7에서는 아래와 같은 로그가 출력되고 정상적으로 작동됩니다. (다른 WAS는 모르겠슴 -_-/)


정보: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.


뭐... 알아서 TLD 파일 찾았다는 거죠 ㄷㄷ;;;


하지만 웹로직 환경에서 페이지를 불르면 에러가 나게 됩니다.


index.jsp:2:5: No tag library could be found with this URI. Possible causes could be that the URI is incorrect, or that there were errors during parsing of the .tld file. 


<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

        ^----^


이런 경우 tld 파일을 추출해서 적당한 곳에 넣은 후 web.xml 에 등록을 해줘야 합니다.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="taglib" version="2.5">

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<!-- 여기 -->
	<jsp-config>
		<taglib>
			<taglib-uri>http://www.springframework.org/tags/form</taglib-uri>
			<taglib-location>/WEB-INF/tlds/spring-form.tld</taglib-location>
		</taglib>
	</jsp-config>

</web-app>


꼭 웹로직 환경이 아니라도  tld 를 찾지 못한다고 하면 web.xml 에 위와 같이 추가해 주면 됩니다.


<taglib-location> 값에 jar 안의 경로를 직접 지정해줄 수 있으면 더 깔끔할텐데....


반응형
//

web.xml 서블릿 버전별 DTD

Posted at 2013. 3. 3. 21:53 | Posted in Java+
반응형

이클립스에서 메이블 프로젝트로 를 생성하면 web.xml 이 서블릿 2.3 버전으로 정의가 되더군요...


서블릿 2.5 버전으로 바꿔서 사용 했었는데 이참에 DTD[각주:1] 선언 정리합니다




Servlet 2.2


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>

</web-app>



Servlet 2.3


servlet-2_3-fcs-spec.pdf


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

</web-app>



Servlet 2.4


DTD 에서 스키마로 바뀌었습니다.


servlet-2_4-fr-spec.pdf


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="servlet-2_4" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

</web-app>



Servlet 2.5


servlet-2_5-mrel2-spec.pdf

 

web.xml.pdf

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="servlet-2_5" version="2.5"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

</web-app>


Servlet 3.0


servlet-3_0-final-spec.pdf


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	version="3.0">

</web-app>


Servlet 3.1


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

</web-app>


  1. Document Type Definition [본문으로]
반응형

'Java+' 카테고리의 다른 글

Find class in jar files  (0) 2018.02.19
Maven Repository for Oracle Library  (0) 2012.12.18
<jsp:forward page="url" /><jsp:include /> <%@ include %>  (0) 2010.04.25
TortoiseSVN 사용하기  (2) 2009.11.16
썸네일(Thumbnail) 만들기  (1) 2009.08.09
Java2Html  (0) 2009.07.19
Jad + JadClipse  (6) 2009.07.11
Java with SQLite  (1) 2009.06.29
Java Database Connectivity  (0) 2009.02.25
//

Spring Message Source from Database

Posted at 2013. 3. 3. 05:19 | Posted in Java+/Example
반응형

스프링을 이용한 다국어 처리를 데이터베이스를 이용해 어떻게 할까 이것저것 고민하다가 구현해 봤습니다.


개발 환경

 - Eclipse Indigo + Maven Integration (Sonatype, Inc.)

 - WebLogic 12c (Tomcat 7)


테이블은 아래와 같이 구성하였습니다.




특별한 것은 없고 여느 책에서나 나오는 스프링에서 MessageSource를 사용하여 다국어 메세지를 가져오는데 AbstractMessageSource 클래스를 상속 받아 따로 클래스를 만들어 봤습니다. (com.tistory.antop.framework.support.DatabaseMessageResource)




구동해 볼 수 있는 샘플을 만들어 봤습니다.


실제 메세지 리소스 부분만 구현하는 시간은 금방인데 하나의 완성품을 만들면서 더 많이 배우는군요~


Spring Framework 3.2.1

Mybatis 3.2 + Ehcache 2.6.3

Tiles 2.2.2 + Dynamic Tiles 1.2.1

HSQLDB 2.2.9

 

http://antop.nerv.kr/multi-lang/

 

데이터를 제외한 모든 부분을 다국어 처리 해봤습니다영어(기본), 한국어, 일어 데이터를 만들어 놨습니다. 구글 번역!


언어를 한글로 했을 때의 화면입니다.




아래는 언어를 영문으로 했을 때




자바스크립트 메세지 부분도 다국어 처리 해봤습니다. (/js/locale.js)






이클립스 프로젝트 파일입니다. 모든 파일 인코딩은 UTF-8 입니다.


multi-lang.zip


war 파일입니다. 16메가의 용량이 다 라이브러리군요... -_-/


multi-lang.zip.001

multi-lang.zip.002



반응형

'Java+ > Example' 카테고리의 다른 글

LOGBack Configurator with JMX  (0) 2014.07.20
현지어로 언어명 보여주기  (0) 2014.02.09
2014년 도로명 주소 사용에 따른 우편번호 준비  (2) 2013.12.22
JSTL Custom Tag using Spring Beans  (0) 2013.12.01
Infinite Routing DataSource  (1) 2013.01.13
Mybatis Type Handler  (1) 2012.09.30
Using AUTO_INCREMENT keys  (0) 2011.03.01
//

Infinite Routing DataSource

Posted at 2013. 1. 13. 18:54 | Posted in Java+/Example
반응형

스프링을 이용하여 몇개의 데이터소스를 정해놓고 라우팅을 하는 경우 AbstractRoutingDataSource를 이용할 수 있었습니다.


하지만 경우에 따라 접속해야하는 데이터베이스가 무한대일 경우?



그래서 이것저것 생각해 봤는데 -_-.... 


로그인시에 [고객 코드], [아이디], [비밀번호] 3가지를 입력 받습니다.


[고객코드]로 고객을 찾은 후 고객의 정보로 디비 정보를 만든 후 ThreadLocal에 저장합니다.


그 후 로그인 처리를 합니다.


로그인 시에 데이터소스를 사용할 때 ThreadLocal에 있는 디비 정보(DbInfo 객체)로 데이터소스를 만들거나 캐쉬에서 가져오게 합니다.


로그인 때에 처음 그 데이터베이스에 접속을 하게 되니까 RoutingDataSource 부분에서 데이터소스를 처음 만들게 될 것입니다.



로그인 처리 이후에는 인터셉터를 이용하여 세션에 있는 디비 정보를 ThreadLocal에 넣고 사용하면 되겠습니다.



이렇게 하면 똑같은 쿼리를 사용하면서 [코객코드]에 따라 다른 디비에 붙어서 사용할 수 있겠네요 ㅠ_ㅠ




Spring + Spring Security + Mybatis + SQLite 를 이용해서 샘플을 만들어 봤습니다.


아래와 같이 3개의 고객 스키마가 있습니다.



아래 테이블은 manager 스키마의 고객 관리 테이블 입니다.



비밀번호는 SALT 와의 조합으로 ARIA 알고리즘으로 저장됩니다.


SQLite는 파일 디비라서 직접적으로 아이디와 비밀번호는 사용하지 않습니다.




아래 테이블은 각각 고개 스키마에 있는 사용자 관리 테이블입니다. 암호는 MySQL 의 password() 알고리즘으로 저장됩니다.



계정은 각각 아래와 같이 들어 있습니다. 스키마명은 고객코드와 동일하게 했습니다.


cust001 (비밀번호: 12345 , welcome1!)



cust002 (비밀번호: jsnot)



cust003 (비밀번호: 11111)





핵심 소스 부분 몇 개 살펴보면...


package com.tistory.antop.service.common.impl;


public class LoginSoImpl implements LoginSo {


private AccountMapper accountMapper;


@Override

public Authentication login(String accountId, String username,

String password) {

// 고객 정보 조회

Account account = accountMapper.selectById(accountId);


// 없거나 사용 중지인 경우 예외

if (account == null || account.isUse() == false) {

throw new AccountNotFoundException();

}


// 디비 정보를 만듬

DbInfo dbInfo = new DbInfo();

dbInfo.setUsername(account.getId());

dbInfo.setEncPass(account.getEncPass());

dbInfo.setSalt(account.getSalt());


// ThreadLocal 에 저장

DbInfoContextHolder.set(dbInfo);


// Spring Security 인증

UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(

username, password);

token.setDetails(account);


Authentication auth = authenticationManager.authenticate(token);


return auth;

}

}



아래 소스는 o.s.jdbc.datasource.lookup.AbstraceRoutingDataSource 클래스를 상속받아 구현한 RoutingDataSource 입니다.


캐쉬 역할을 하는 객체는 동기화를 위해 Hashtable을 사용하였습니다.


package com.tistory.antop.framework.datasource;


abstract public class RoutingDataSource extends AbstractRoutingDataSource {


private String url;

private String driverClassName;

private PasswordDecoder passwordDecoder;


private Map<DbInfo, DataSource> dataSources = new Hashtable<DbInfo, DataSource>();


@Override

protected DbInfo determineCurrentLookupKey() {

return DbInfoContextHolder.get();

}


@Override

protected DataSource determineTargetDataSource() {


DbInfo dbInfo = determineCurrentLookupKey();


if (dbInfo == null) {

throw new RoutingDataSourceException("데이터베이스 정보가 없습니다.");

}


try {

// 데이터소스가 없으면 생성

if (!contains(dbInfo)) {

// 비밀번호 복호화

String password = passwordDecoder.decodePassword(

dbInfo.getEncPass(), dbInfo.getSalt());

DataSource ds = createDataSource(dbInfo.getUsername(), password);

add(dbInfo, ds);

}


// 데이터소스 리턴

return get(dbInfo);

} catch (Exception e) {

throw new RoutingDataSourceException(e);

}


}


// 데이터 소스를 만드는 부분은 상속받은 객체가 함

abstract public DataSource createDataSource(String username, String password);

)




WAR 파일


바로 배치 가능한 WAR 파일입니다.


routing_datasource.zip.001


routing_datasource.zip.002



소스 ZIP 파일


이클립스 메이븐 구조의 프로젝트 소스입니다.


routing_datasource.zip



개발 테스트 : 톰켓 7, 웹로직 12c


배포 테스트 : 웹로직 12c




※ 질문!!!


웹로직에서 사용할 때 컨텍스트루트 다음에 "/" 가 붙느냐 안붙느냐에 따라서 스프링 시큐리티 필터를 타고 안타고 다른 결과가 나옵니다...


 URL  정상 처리 여부

 http://localhost:7001/routing_datasource/

 정상 처리 됨
 http://localhost:7001/routing_datasource

 스프링 시큐리티 필터를 타지 못하고 그냥 넘어가서 에러


톰켓에서는 "/" 상관없이 정상적으로 됨.... 이 부분 해결법 아시는분.. ㅠㅠ



반응형
//

Maven Repository for Oracle Library

Posted at 2012. 12. 18. 20:43 | Posted in Java+
반응형

메이븐 pom.xml 에서 오라클 라이브러리를 사용하기 위한 설정입니다.


메이븐 구조의 프로젝트에서 오라클 라이브러를 쉽게 사용하기 위해서 이것저것 찾아보다가 현재 아래의 저장소 URL 이 제일 적당한 것 같습니다.


<project ...>

...


<repositories>

<repository>

<id>codelds</id>

<url>https://code.lds.org/nexus/content/groups/main-repo</url>

</repository>

</repositories>


<dependencies>

...

<!-- oracle -->

<dependency>

<groupId>com.oracle</groupId>

<artifactId>ojdbc6</artifactId>

<version>11.2.0.3</version>

<scope>compile</scope>

</dependency>

<dependency>

<groupId>com.oracle</groupId>

<artifactId>ucp</artifactId>

<version>11.2.0.3</version>

<scope>compile</scope>

</dependency>

</dependencies>


</project>



각 버전을 확인 하는 방법은 브라우저에서 위 저장소 URL 을 입력하면 [groupId / artifactId / version] 순으로 디렉토리 구조로 되어 있습니다.


목록을 보면 오라클 이외에도 많은 라이브러리가 있는 것을 볼 수 있습니다.


자기가 필요로하는 라이브러리를 찾아봅시다 -_-;;


ojdbc6.jar 를 찾아보면 아래와 같은 구조로 되어 있습니다.



딱 보면 감이 오시겠지면


1 = groupId

2 = artifactId

3 = version


반응형

'Java+' 카테고리의 다른 글

Find class in jar files  (0) 2018.02.19
web.xml 서블릿 버전별 DTD  (1) 2013.03.03
<jsp:forward page="url" /><jsp:include /> <%@ include %>  (0) 2010.04.25
TortoiseSVN 사용하기  (2) 2009.11.16
썸네일(Thumbnail) 만들기  (1) 2009.08.09
Java2Html  (0) 2009.07.19
Jad + JadClipse  (6) 2009.07.11
Java with SQLite  (1) 2009.06.29
Java Database Connectivity  (0) 2009.02.25
//

Mybatis Type Handler

Posted at 2012. 9. 30. 12:49 | Posted in Java+/Example
반응형

마이바티스를 이용하여 자바 객체와 데이터베이스 테이블을 매핑할 때 서로 완전히 다른 타입의 것들을 사용할 때가 있습니다.

 

그 예로 대표적인 예가 자바의 Boolean 과 데이터베이스의 플래그 문자입니다.

 

 

오라클 같은경우 boolean 타입이 없기 때문에 보통 CHAR(1) 잡고 Y/N 값을 많이 사용합니다.

 

다른 경우는 1 or 0 을 사용하여 참/거짓, 사용/미사용, 차단/허용 같은 on/off 플래그 값을 사용합니다.

 

자바 

데이터베이스 

boolean

CHAR(1)

INTEGER  

참 / 사용

true

Y

 1 

거짓 / 미사용

false

N

 0 

 

org.apache.ibatis.type.TypeHandler 인터페이스를 이용해서 서로 다른 타입을 연결할 수 있습니다.

 

package com.tistory.antop.mybatis.handler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.ibatis.exceptions.PersistenceException;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.apache.log4j.Logger;

public class StringYnTypeHandler implements TypeHandler<Boolean> {

    private Logger logger = Logger.getLogger(getClass());

    public Boolean getResult(ResultSet rs, String columnName) throws SQLException {
        String s = rs.getString(columnName);

        return parseBoolean(s);
    }

    public Boolean getResult(ResultSet rs, int columnIndex) throws SQLException {
        String s = rs.getString(columnIndex);

        return parseBoolean(s);
    }

    public Boolean getResult(CallableStatement cs, int columnIndex)
        throws SQLException {
        String s = cs.getString(columnIndex);

        return parseBoolean(s);
    }

    public void setParameter(PreparedStatement ps, int i, Boolean bool,
        JdbcType jdbcType) throws SQLException {

        ps.setString(i, parseString(bool));
    }

    // "Y" or "N" -> true or false
    private boolean parseBoolean(String s) {
        boolean bool = false;

        if (s == null) {
            return false;
        }

        s = s.trim().toUpperCase();

        if (s.length() == 0) {
            return false;
        }

        // allow "Y" or "N"
        if ("Y".equals(s) == false && "N".equals(s) == false) {
            throw new PersistenceException("value must be \"Y\" or \"N\".");
        }

        bool = "Y".equals(s);

        if (logger.isDebugEnabled()) {
            logger.debug("\"" + s + "\" -> " + bool);
        }

        return bool;
    }

    // true or false -> "Y" or "N"
    private String parseString(Boolean bool) {
        String s = (bool != null && bool == true) ? "Y" : "N";

        if (logger.isDebugEnabled()) {
            logger.debug(bool + " -> " + "\"" + s + "\"");
        }

        return s;
    }
}

 

이 클래스를 이용하면 자바에서는 boolean 타입을 사용하면 데이터베이스에서는 Y or N 값이 들어가게 됩니다.

 

mybatis.typehandler.zip

 

위 샘플은 메이븐 프로젝트 구조입니다.

 

샘플을 만드는 도중에 sqlite3 는 이상한게 TIMESTAMP 타입을 java.util.Date 클래스와 매핑 하면 들어갈 때는 그대로 들어가는데 조회할 때는 java.util.String 이 나오는군요....

 

그래서 TIMESTAMP 에 대한 핸들러 하나 더 만들었습니다.

 

테스트는 com.tistory.antop.mybatis.TypeHandlerTest 클래스 입니다. JUnit 입니다.

 

실행시 Run Configurations 중 VM 옵션에 이래와 같이 "-Dlog4j.configuration=config/properties/log4j.properties" 를 추가해 줘야 로그를 볼 수 있습니다.

 

 

 

반응형
//

Using AUTO_INCREMENT keys

Posted at 2011. 3. 1. 16:02 | Posted in Java+/Example
반응형

http://dev.mysql.com/tech-resources/articles/autoincrement-with-connectorj.html

http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/jdbc.html

MySQL 에는 AUTO_INCREMENT(이하 AI)라는 것이 있습니다. 오라클 디비의 시퀀스와 같이 자동으로 값이 증가하게 됩니다.

AI를 적용하려는 칼럼은 기본키K(Primary Key)여야 합니다.



Before JDBC API 3.0

JDBC API 3.0 이전에서는 INSERT 이후에 "select last_insert_id()" 쿼리를 날려서 추가된 AI 값을 가져와야 합니다.

Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; // auto increment value int generatedKey = -1; try { conn = dataSource.getConnection(); // query String sql = "insert into sample_user (name, age) values (?, ?)"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, user.getName()); pstmt.setInt(2, user.getAge()); // execute query pstmt.executeUpdate(); // query sql = "select last_insert_id()"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); if(rs.next()) { // auto increment value generatedKey = rs.getInt(1); } return generatedKey; } catch (Exception e) { throw e; } finally { // release rs, pstmt, conn }



After JDBC API 3.0

3.0 부터서는 "getGeneratedKeys()" 메소드를 이용하면 됩니다.

Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; int generatedKey = -1; try { conn = dataSource.getConnection(); // query String sql = "insert into sample_user (name, age) values (?, ?)"; pstmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); pstmt.setString(1, user.getName()); pstmt.setInt(2, user.getAge()); // execute query pstmt.executeUpdate(); rs = pstmt.getGeneratedKeys(); if (rs.next()) { generatedKey = rs.getInt(1); } return generatedKey; } catch (Exception e) { throw e; } finally { // release rs, pstmt, conn; }



Spring + JdbcDaoSupport

스프링과 연동하여 사용할 때에는 KeyHolder 인터페이스를 이용하면 됩니다.

@Override
public int create(User user) throws Exception {
	// query
	String sql = "insert into sample_user (name, age) values (:name, :age)";
	// parameter
	SqlParameterSource paramSource = new BeanPropertySqlParameterSource(user);
	// key holder
	KeyHolder generatedKeyHolder = new GeneratedKeyHolder();
	// execute query
	getNamedParameterJdbcTemplate().update(sql, paramSource, generatedKeyHolder);
	// auto increment
	return generatedKeyHolder.getKey().intValue();
}
※ KeyHolder 기능을 사용하려면 JDBC 드라이버가 JDBC 3.0을 지원해야 합니다.



샘플 소스입니다. (이클립스 Java Project 폴더 통째로 압축했씁니다. Buil Path 설정 해줘야 할지도...)

Spring 3.0 으로 되어있습니다. 간단한 DI만 이용...

kr/nerv/antop/config/spring.xml 파일에서 디비 설정 해줘야합니다.

테스트 클래스는 app.TestUserDao 입니다.

sample_mysql_ai.zip


반응형
//
반응형
Spring + JDBC[각주:1]를 이용하여 개발 시에 queryForObject(...) 메소드를 사용하여 하나의 객체만 가져올 경우 해당 데이터가 없으면 org.springframework.dao.EmptyResultDataAccessException 예외가 발생하게 된다.

package kr.nerv.dao.impl;
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
 
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
 
import kr.nerv.dao.UserInfoDao;
import kr.nerv.vo.UserInfoVo;
 
public class UserInfoDaoJdbc extends NamedParameterJdbcDaoSupport implements UserInfoDao {
    // row mapper
    private UserInfoRowMapper rowMapper = new UserInfoRowMapper();
    // find by id query
    private String findById = "select * from sample_user_info where id = :id";
 
    @Override
    public UserInfoVo findById(Integer id) throws Exception {
        Map param = new HashMap();
        param.put("id", id);
 
        // select 데이터가 없으면 EmptyResultDataAccessException 예외 발생!!
        return (UserInfoVo) getNamedParameterJdbcTemplate().queryForObject(findById, param,
                rowMapper);
    }
 
    private class UserInfoRowMapper implements RowMapper {
        @Override
        public UserInfoVo mapRow(ResultSet rs, int rowNum) throws SQLException {
            UserInfoVo userInfo = new UserInfoVo();
            userInfo.setId(rs.getInt("id"));
            userInfo.setName(rs.getString("name"));
            userInfo.setTel(rs.getString("tel"));
 
            return userInfo;
        }
    }
}

아래 소스를 보면 findById(Integer id) 메소드에서 PK로 하나의 데이터를 셀렉트 하게 되어 있다. 만약 데이터가 없으면 null이나 빈 VO[각주:2]를 리턴해주겠거니 하겠지만 예외를 발생하게 된다.이럴 때에는 예외 처리를 해주면 된다.

    @Override
    public UserInfoVo findById(Integer id) throws Exception {
        Map param = new HashMap();
        param.put("id", id);
 
        try {
            return (UserInfoVo) getNamedParameterJdbcTemplate().queryForObject(findById, param,
                    rowMapper);
        } catch (EmptyResultDataAccessException e) {
            // EmptyResultDataAccessException 예외 발생시 null 리턴
            return null;
        }
    }

예제 파일입니다.

EmptyResultDataAccessException.war



  1. 자바 프로그래밍 언어로 만들어진 클래스와 인터페이스로 이루어진 API로 SQL문을 실행 할 수 있는 함수 호출 인터페이스 이다. [본문으로]
  2. Value Object는 Presentation, Data 각 Layer 간의 데이터 전달을 위해 사용된다. 맴버변수와 맴버변수의 값을 설정하고 가져오기 위한 setter, getter 메소드만 존재한다. [본문으로]
반응형
//