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 |