2013년 4월 26일 금요일

Spring과 MongoDB


이마 다 알고 있는 사실이겠지만, 대용량 Data 입력 작업에 탁월한 mongoDB을 실제 프로젝트에 적용하는 사례가 많아 지고 있다.
이번 글에서는 국민 대표 프래임워크 Spring에 mongoDB을 사용하는 방법을 살펴보도록 하겠다.

Spring-Data-MongoDB
Spring에서는 MongoDB와 연동을 위한 Connector을 제공한다. Dependency을 추가하면 mogo-java-driver도 같이 추가된다.
<!-- MongoDB for Spring -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.2.1.RELEASE</version>
</dependency>


Spring Framework
여기서 설명하는 예제는 Spring webmvc을 기반으로 RESTFul API을 만들어봤다.

jdbc.properties
mongoDB 설치 정보를 포함하는 환경설정 파일(파일 이름을 다른 걸로 할 것을...)
mongo.host = localhost
mongo.port = 27017
mongo.db.name = expense

Spring Config
mongoDB관련 Namespace을 추가 해준다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd">

<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
</list>
</property>
</bean>


dataSource 설정 처럼 mongoDB Connection 설정 부분이다. 각 항목은 딱 보면 딱 알겠죠?
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
<mongo:options connections-per-host="8"
threads-allowed-to-block-for-connection-multiplier="4"
connect-timeout="1000"
max-wait-time="1500"
auto-connect-retry="true"
socket-keep-alive="true"
socket-timeout="1500"
slave-ok="true"
write-number="1"
write-timeout="0"
write-fsync="true"/>
</mongo:mongo>

SQLTemplate와 유사한 mongoTemplate 설정 부분입니다.
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<constructor-arg name="databaseName" value="${mongo.db.name}" />
</bean>

코드 살펴 보기
Data VO = User, "만인의 예제" 사용자 관리에 사용되는 Value Object 입니다.
mongoDB의 Document와 매핑되는 VO입니다.

public class User {

private long id;
private String userName;
private String password;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}


UserDAO
  • 위에서 설정한 “mongoTemplate”을 사용하게 됩니다.
  • User Document가 저장될 Collection을 지정하게 됩니다.

@Repository
public class UserDAOImpl implements UserDAO  {

@Autowired
MongoTemplate mongoTemplate;

private static String COLLECTION_NAME = "testcollect";

@Override
public User insert(User user) {
mongoTemplate.insert(user, COLLECTION_NAME);
return user;
}

@Override
public User getUser(User user) {
return mongoTemplate.findById(user.getId(), User.class, COLLECTION_NAME);
}

@Override
public List<User> getUsers() {
return (List<User>) mongoTemplate.findAll(User.class, COLLECTION_NAME);
}

@Override
public void deleteUser(User user) {
Query query = new Query(new Criteria("id").is(user.getId()));
mongoTemplate.remove(query, COLLECTION_NAME);
}

@Override
public User updateUser(User user) {
Query query = new Query(new Criteria("id").is(user.getId()));

Update update = new Update();
update.set("userName", user.getUserName());
update.set("password", user.getPassword());

mongoTemplate.updateFirst(query, update, COLLECTION_NAME);

return user;
}
}


UserService
이 부분 부터는 MongoDB 특성이 없는 코드 입니다.
@Service
@Transactional
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);

@Autowired
private UserDAO userDAO;

public void insertUser(User user) {
logger.info("userServiceImple.insertUser >>>" + user);
userDAO.insert(user);
}

public List<User> getUsers() throws Exception {
return userDAO.getUsers();
}


public User getUser(User user) throws Exception {
logger.info("userServiceImple.getUser >>>" + user);
return (User) userDAO.getUser(user);
}


public boolean deleteUser(User user) throws Exception {
logger.info("userServiceImple.delUser >>>" + user);
try {
userDAO.deleteUser(user);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}

public User updateUser(User user) throws Exception {
logger.info("userServiceImple.updateUser >>>" + user);

return userDAO.updateUser(user);

}
}

MongoController
RESTFul Controller 부분입니다.

@Controller
public class MongoController {

@Autowired
private UserService userService;

@RequestMapping(value = "/mongo/addUser",method = RequestMethod.POST)
public @ResponseBody ResponseVO addUser(HttpServletRequest request) {
ResponseVO response = null;
Map<String, String> params = getParameterMap(request);
long id = 0;
try {
id = Long.parseLong(params.get("id"));
} catch (NumberFormatException e1) {
response = new ResponseVO(ResponseHeadVO.INVALID_REQUEST,"'ID'는 null이거나 문자형일수 없습니다.",null);
return response;
}
String userName = params.get("username");
String password = params.get("password");

if(userName == null || password == null || userName.equals("") || password.equals("")) {
response = new ResponseVO(ResponseHeadVO.INVALID_REQUEST,"전송된 파라미터 중 하나 이상이 공백이거나 null 입니다.",null);
return response;
}
try {
printParams(request, params);
User user = new User();
user.setId(id);
user.setUserName(userName);
user.setPassword(password);
userService.insertUser(user);
BooleanVO isOK = new BooleanVO();
isOK.setOK(true);

response = new ResponseVO(ResponseHeadVO.SUCCESS, "", isOK);
} catch (Exception e) {
logger.error(this.getClass().getSimpleName(), e);
response = new ResponseVO(ResponseHeadVO.SERVER_ERROR,e.getMessage(),null);
}
return response;
}
@RequestMapping(value = "/mongo/getUsers",method = RequestMethod.POST)
public @ResponseBody ResponseVO getUsers(HttpServletRequest request) {
ResponseVO response = null;
Map<String, String> params = getParameterMap(request);
try {
printParams(request, params);
List<User> users = userService.getUsers();
ListVO<User> userList = new ListVO<User>();
userList.setDataList(users);
userList.setTotalCount(users.size());;

response = new ResponseVO(ResponseHeadVO.SUCCESS, "", userList);
} catch (Exception e) {
logger.error(this.getClass().getSimpleName(), e);
response = new ResponseVO(ResponseHeadVO.SERVER_ERROR,e.getMessage(),null);
}
return response;
}

}

설명보다는 코드를 직접 보시는게 더 도움이 될 것 같습니다. 소스는 아래에.

댓글 없음:

댓글 쓰기

블록체인 개요 및 오픈소스 동향

블록체인(block chain) 블록체인은 공공 거래장부이며 가상 화폐로 거래할때 발생할때 발생할 수 있는 해킹을 막는 기술. 분산 데이터베이스의 한 형태로, 지속적으로 성장하는 데이터 기록 리스트로서 분산 노드의 운영자에 의한 임의 조작이 불가...