본문 바로가기

JAVA/Struts2

Struts2 + Spring + iBatis 연동 및 설정하기

반응형


Struts2 + Spring + iBatis 연동 및 설정하기

:: 기존 Struts2 + iBatis 연동 프로젝트에서 Spring을 추가하였다. ::



1.Action(액션)

LoginAction.java

/**

 * 로그인/로그아웃 action

*/

@SuppressWarnings("serial")

public class LoginAction extends ActionSupport {

           static Logger logger = Logger.getLogger(LoginAction.class);

 

           private String id;                                        //아이디

           private String pwd;                                     //패스워드

           private DMManager manager;            //세션정보

           private String type;

          

            //-1 spring annotation 설정

           @Resource(name="loginDAO")

           private LoginDAO loginDAO;

 

           /**

            * 로그인

            */

           @SuppressWarnings("unchecked")

           public String loginForm() throws Exception {

                     return SUCCESS;

           }

 

           /**

            * 로그인

            */

           @SuppressWarnings("unchecked")

           public String login() throws Exception {

                     HttpServletRequest request = ServletActionContext.getRequest();

 

                     Map parameterMap = new HashMap();

                     parameterMap.put("adminid", id);

                     parameterMap.put("adminpwd", pwd);

 

//LoginDAO

manager = LoginDAO.login(parameterMap);

 

//-2 spring annotation 설정

                     manager = loginDAO.login(parameterMap);

                     if (manager == null) {

`                              logger.info("[wrong password!!!]");

                                type = "LOGIN_ERROR";

                                return LOGIN;

// 사용자아이디가 중지되었을때

                     }else if(manager.getAdminAuth().equals("9")){

                                type = "LOGIN_STOP";

                                return SUCCESS;

                     } else {

                                // login succes!

                                HttpSession session = request.getSession(false);

                                session.setAttribute("dmManager", manager);                                                        // 관리자 로그인 유무

                                session.setAttribute("adminid", manager.getAdminID());                                           // 관리자 로그인 아이디

                                session.setAttribute("adminname", manager.getAdminName());                                // 관리자 로그인 이름

                                session.setAttribute("auth", manager.getAdminAuth());                                 // 관리자 권한

session.setAttribute("admin", "admin");           // 관리자 //권한

                                request.setAttribute("url", "");

 

                                // 오늘 사용자 접속 카운터 초기화 쿼리 실행

                                LoginDAO.loginUpdate(parameterMap);

                                loginDAO.loginUpdate(parameterMap);

                               

                                type = "LOGIN_SUCCESS";

                                return SUCCESS;

                     }// end if

           }

 

           /**

            * 로그아웃

            */

           public String logout() throws Exception {

                     HttpServletRequest request = ServletActionContext.getRequest();

                     HttpSession session = request.getSession();

                    

                     logger.info(session.getAttribute("adminid") + "[logout!!!]");

                     session.invalidate();     // 세션연결 끊기

                     type = "LOGOUT_SUCCESS";

                     return SUCCESS;

           }

 

           }// setter, getter

           public String getType() {

                     return type;

           }

           public void setType(String type) {

                     this.type = type;

           }

           public static Logger getLogger() {

                     return logger;

           }

           public static void setLogger(Logger logger) {

                     LoginAction.logger = logger;

           }

           public String getId() {

                     return id;

           }

           public void setId(String id) {

                     this.id = id;

           }

           public String getPwd() {

                     return pwd;

           }

           public void setPwd(String pwd) {

                     this.pwd = pwd;

           }

           public DMManager getManager() {

                     return manager;

           }

           public void setManager(DMManager manager) {

                     this.manager = manager;

           }

}


관리자 로그인관련 부분입니다. 로그인 폼에서 아이디, 패스워드 입력하여 sumit 전송합니다.

①-1 Spring의 Annotation을 설정

①-2 loginDAO를 호출

②번과 다른점은 LoginDAO는 static 함수로 호출


2.DAO

LoginDAO.java

//-1 spring annotation 설정

@Repository("loginDAO")

public class LoginDAO{

    public LoginDAO() {

    }

 

    static Logger logger = Logger.getLogger(LoginDAO.class);

   

//-2 spring annotation 설정

       @Autowired

private IBatisDao dao;

   

    //로그인

@SuppressWarnings("unchecked")

public  DMManager login(Map parameterMap) throws SQLException {

if (logger.isDebugEnabled()) {

                     logger.debug("login(Map) - start"); //$NON-NLS-1$

           }

// SqlMapClient 호출

          SqlMapClient sqlMap = SQLMapManager.getSqlMapClient();     

         

// SqlMapClient 호출

          SqlMapClient sqlMap = SqlMapConfig.getSqlMapInstance();

         

          DMManager manager = new DMManager();

//②,  sqlMap.queryForObject

          manager = (DMManager) sqlMap.queryForObject("loginAdmin.adminLogin", parameterMap);

//-2 IBatisDao 호출

          manager = (DMManager) dao.selectOne("loginAdmin.adminLogin",       parameterMap);

         

          if (logger.isDebugEnabled()) {

                                logger.debug("login(Map) - end"); //$NON-NLS-1$

                     }

        return manager;

}

 

    /**

     * 로그인 접속 시간 업데이트

     * LoginDAO loginUpdate Proc

*/

    @SuppressWarnings("unchecked")

    public void loginUpdate(Map parameterMap) throws SQLException {    

          dao.update("loginAdmin.todayCntClearUpdate", parameterMap);

        return;

    }

}

DAO

①-1, ①-2 Spring의 Annotation을 설정

①-1 @Repository("loginDAO")를 통해 LoginDAO bean 인식 -> LoginAction에서 loginDAO와 맺여준다.

①-2 IBatisDao 객체를 Annotation 하여 자동으로 객체를 생성한다.  setter가 필요없다.


public static DMManager login  static 를 빼주었다.  -> 현재 public DMManager login 변경.

LoginAction에서 LoginDAO.login()로 호출 할 경우 static을 필요함. loginDao 객체로 호출하기때문에 static를 빼줬다.


 SqlMapClient 호출,  SqlMapClient 호출

Spring을 쓰기전에는 Struts2 + iBatis로 구성되어있어서 iBatis의 com.ibatis.sqlmap.client.SqlMapClient를 사용했었다.

② 와 ③의 차이점은 getInstance를 사용했느냐 차이인 듯 (싱글톤 호출)

-2 IBatisDao 공통 DAO를 호출로 변경했다.

Struts2 + Spring + iBatis로 구성하여 org.springframework.orm.ibatis.SqlMapClientTemplate를 이용


3.SqlMapClient 

SQLMapManager.java

public class SQLMapManager {

           private static Logger logger = Logger.getLogger(SQLMapManager.class);         

//iBatis의 sqlMapConfig를 파일로 읽어드려서 사용

           private static String resourceFile = "config/xml/sql/sqlMapMysqlConfig.xml"


           /**

            * SQLMapManager getSqlMapClient

            * @return

            */

           public static SqlMapClient getSqlMapClient() {

                     Reader reader = null;

                     SqlMapClient sqlmapclient = null;                    

                     try {

//                             if(sqlmapclient == null){

                                          reader = Resources.getResourceAsReader(resourceFile);

                                          sqlmapclient = SqlMapClientBuilder.buildSqlMapClient(reader);

                                          logger.info("sqlmapclient 생성");

//                             }

                     } catch (IOException ex) {

                                logger.error("[MAP READER EXCEPTION]", ex);

                     } finally {

                                try {

                                          reader.close();

                                          logger.info("sqlmapclient 종료");

                                } catch (IOException e) {

                                          logger.error("[READER CLOSE EXCEPTION]", e);

                                }

                                logger.info("[RESOURCE FILE]" + resourceFile);

                     }

                     return sqlmapclient;

           }


iBatis의 sqlMapConfig를 파일를 읽어드려서 SqlMapClient를 사용함.

 SqlMapClient 호출 사용시 db 조회할때마다 SqlMapClient를 계속 생성한다. 


SqlMapConfig.java

public class SqlMapConfig {

    private static final SqlMapClient sqlMap; 

    private static Logger logger = Logger.getLogger(SqlMapConfig.class);

    private static String resourceFile = "config/xml/sql/sqlMapMysqlConfig.xml";            //mysql


    static {

        try {           

                              Reader reader = Resources.getResourceAsReader(resourceFile);

                              sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);

                              logger.info("sqlMap 생성");

                    } catch (IOException e) {

                             logger.error("[MAP READER EXCEPTION]", e);

                             e.printStackTrace();

                             throw new RuntimeException("Error initializing class. Cause:" + e);

                    }

                   logger.info("sqlMap 종료");

                   logger.info("[RESOURCE FILE]" + resourceFile);

                    }

 

    public static SqlMapClient getSqlMapInstance() {

          logger.info("db연결테스트 시작1");

        return sqlMap;

    }

 SqlMapClient 호출 사용시 getSqlMapInstance()를 호출하여 메모리에 상주하여 SqlMapClient를 한번 호출하여 재사용한다.



IBatisDao.java

public class IBatisDao {

            private static Logger logger = Logger.getLogger(IBatisDao.class);

            private SqlMapClientTemplate sqlMapClientTemplate;


           // 설정파일에서 주입되어 객체를 받아오므로 setter 메소드가 필요하다.

           public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {

                     this.sqlMapClientTemplate = sqlMapClientTemplate;

           }

         

    public Object insert(String queryId, Object params){

        return sqlMapClientTemplate.insert(queryId, params);

    }

    

    public Object update(String queryId, Object params){

        return sqlMapClientTemplate.update(queryId, params);

    }

    

    public Object delete(String queryId, Object params){

        return sqlMapClientTemplate.delete(queryId, params);

    }

    

    public Object selectOne(String queryId){

        printQueryId(queryId);

        return sqlMapClientTemplate.queryForObject(queryId);

    }

    

    public Object selectOne(String queryId, Object params){

        return sqlMapClientTemplate.queryForObject(queryId, params);

    }

    

    @SuppressWarnings("rawtypes")

    public List selectList(String queryId){

        return sqlMapClientTemplate.queryForList(queryId);

    }

    

    @SuppressWarnings("rawtypes")

    public List selectList(String queryId, Object params){

        return sqlMapClientTemplate.queryForList(queryId,params);

    }

          

}

-2 IBatisDao 

SqlMapClientTemplate의 사용하여 공통적으로 사용할 SqlMapClient의 insert, update, delete, seleteList, selectOne 함수를 설정하였다.


4.sqlMapMysqlConfig.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"

           "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

 

<!-- Spring 사용전 -->

<properties resource="config/properties/dbconnectMysql.properties" />

           <settings cacheModelsEnabled="true"

                      enhancementEnabled="true"

                        lazyLoadingEnabled="true"

                        maxRequests="10000"

                        maxSessions="3500"

                        maxTransactions="1000"

                        useStatementNamespaces="true"

           />

 

<!-- Spring 사용전 -->

           <transactionManager type="JDBC" commitRequired="false">

        <dataSource type="DBCP">

            <property name="JDBC.Driver" value="${driver}" />

            <property name="JDBC.ConnectionURL" value="${url}" />

            <property name="JDBC.Username" value="${username}" />

            <property name="JDBC.Password" value="${password}" />

           

            <property name="initialSize" value="5"/>

            <property name="maxActive" value="200"/>

            <property name="maxIdle" value="20"/>

            <property name="maxWait" value="10000"/>

            

            <property name="Pool.MaximumActiveConnections" value="10" />

            <property name="Pool.MaximumIdleConnections" value="5" />

            <property name="Pool.MaximumWait" value="10000" />

            <property name="Pool.ValidationQuery" value="SELECT CURRENT_TIMESTAMP FROM dual" />

            <property name="Pool.testOnBorrow" value="true"/>

            <property name="Pool.LogAbandoned" value="false"/>

              <property name="Pool.RemoveAbandoned" value="true"/>

              <property name="Pool.RemoveAbandonedTimeout" value="300"/>

        </dataSource>

    </transactionManager>

                   

           <!-- 관리자 로그인   -->

           <sqlMap resource="config/xml/sql/mysql/common/login/loginAdminSQL.xml"/>

 

</sqlMapConfig>


① Spring 사용전에는 iBatis sqlMapConfig에서 db연결 설정해주었다.

Spring 사용후에는 sqlMap 관리만 한다. db관련부분은 주석으로 처리!!



4.applicationContext.xml

Spring 설정파일

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

                     xmlns:p="http://www.springframework.org/schema/p"

                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                     xmlns:context="http://www.springframework.org/schema/context"

                     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" >

<!--               default-autowire="byName"> -->


<!-- ① annotation 설정 auto scan -->

<context:annotation-config/>

<context:component-scan base-package="com" />

 

 

 <!--  db정보 properties -->

<bean id="propertyConfigurer"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="locations">

        <list>

                    <value>classpath:config/properties/dbconnectMysql.properties</value>

        </list>

        </property>

        <property name="fileEncoding">

        <value>UTF-8</value>

        </property>

</bean>                             

                               

                               

<!-- ③ DataSource JDBC설정 -->

  <bean id="dataSource"

        class="org.apache.commons.dbcp.BasicDataSource"

        p:driverClassName="${driver}"

        p:url="${url}"

        p:username="${username}"

        p:password="${password}" />


<!--  SqlMapClient 설정 -->

  <bean id="sqlMapClient"

        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"

        p:dataSource-ref="dataSource"

        p:configLocation="classpath:config/xml/sql/sqlMapMysqlConfig.xml" />

       

<!-- ⑤ 트랜젝션 관리를 spring에서 담당 -->       

<bean id="txManager"

                     class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

        <property name="dataSource">

        <ref local="dataSource"/>

        </property>

</bean>       


<!-- ⑥ SqlMapClientTemplate 설정 -->       

<bean id="sqlMapClientTemplate"

      class="org.springframework.orm.ibatis.SqlMapClientTemplate"

      p:sqlMapClient-ref="sqlMapClient"/>                 

 

<!--  iBatisDAO 공통 dao 설정 --> 

<bean id="dao" class="com.kbid.common.db.IBatisDao">

      <property name="sqlMapClientTemplate"

             ref="sqlMapClientTemplate"/>          

</bean>


<!-- <bean id="loginDAO" class="com.common.login.dao.LoginDAO"/> -->                  

</beans>


①~⑦ 까지 spring 설정이다.

① Spring annotation 설정으로 

LoginAction에서 annotation을 자동으로 세팅해준다.

@Resource(name="loginDAO")

           private LoginDAO loginDAO;


@Repository("loginDAO")

public class LoginDAO{

① 설정안할시 일일이 setter로 설정해줘야한다.

이렇게 -->  <bean id="loginDAO" class="com.common.login.dao.LoginDAO"/>


② DB정보 properties 파일을 읽어서 db정보를 매칭시킨다.

③ DataSource JDBC설정으로 spring 사용전 sqlMapMysqlConfig.xml에서 DB설정정보를 applicationContext.xml에서 한다.

 SqlMapClient 설정 iBatis의 sqlMapMysqlConfig.xml 설정의 sqlMap들을 세팅

⑤ 트랜젝션 관리를 spring에서 담당 트랜젝션관리한다.

⑥ SqlMapClientTemplate 설정

SqlMapClient를 SqlMapClientTemplate 주입시켜준다.

 iBatisDAO 공통 dao 설정

IBatisDao.java의 

public class IBatisDao {

            private SqlMapClientTemplate sqlMapClientTemplate;

sqlMapClientTemplate 바로 주입시켜준다.



5. web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_ID" 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">

           <display-name>project</display-name>

 

<!-- Spring 환경설정 정의 -->   

           <context-param>

                     <param-name>contextConfigLoaction</param-name>

                     <param-value>WEB-INF/applicationContext.xml</param-value>

                     <!--

                     <param-value>classpath:context/applicationContext.xml</param-value>

                      -->

           </context-param>

           <listener>

                     <listener-class>

                                org.springframework.web.context.ContextLoaderListener

                     </listener-class>

           </listener>

 <!-- Spring 환경설정 정의 끝 -->

    <filter> 

        <filter-name>struts</filter-name> 

        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> 

        <init-param>

                    <param-name>struts.action.extension</param-name>

                    <param-value>action,mdo</param-value>

                     </init-param>

    </filter>

    <session-config>

        <session-timeout>60</session-timeout>

    </session-config>  

    <filter-mapping> 

        <filter-name>struts</filter-name> 

        <url-pattern>/*</url-pattern> 

    </filter-mapping> 

           <listener>

             <listener-class>

              org.apache.struts2.tiles.StrutsTilesListener

             </listener-class>

            </listener>     


    <welcome-file-list> 

        <welcome-file>index.html</welcome-file> 

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

    </welcome-file-list>

  <error-page>

          <error-code>404</error-code>

          <location>/error/error.jsp</location>

  </error-page>

  <error-page>

          <error-code>500</error-code>

          <location>/error/error.jsp</location>

  </error-page>                   

</web-app>


Spring 환경설정 정의 

web.xml에서 Spring 환경설정 한다.


6. Struts2 + Spring 연계 jar 파일


struts2-spring-plugin-2.0.14.jar

spring-2.5.5.jar


기존 Struts2 lib에 2개파일만 넣어줬다.


7. 결과

확실히 db 커넥션 부분에서 속도가 빨라졌다.

DAO 부분에서  SqlMapClient 호출해서 계속 SqlMapClient를 생성하면서 느려진듯 하다.

DB에서도 db커넥션 맺고 끊음이 번번이 일어나 재사용을 못하는 부분도 있었다.

그런데 ③ SqlMapClient 호출시에는 db커넥션을 재사용한다.

Spring framework를 사용하는게 효율적인지  SqlMapClient으로 사용하는게 효율적인지...

아시는분 답변 달아주세요ㅠㅠ




반응형

'JAVA > Struts2' 카테고리의 다른 글

Struts2 파일 다운로드  (0) 2016.03.16
Struts2 파일 업로드  (0) 2016.03.16