개요
사용자가 보는 데이터베이스 조회결과는
- 여러 건일 경우
List<DataObject>
- 한 건일 경우
DataObject
로 전달한다.
조회조건은
- 파라미터가 많지 않을 경우 해당 파라미터를 직접 메소드에 명시하고
- 여럿일 경우 QueryRequest를 상속받는 value object 클래스를 정의하여
주고 받는다.
조회결과를 페이징하여 제공하려면, 조회조건에
- 파라미터 'pageNum'(페이지 번호)에 0보다 큰 값
- 파라미터 'fetchSize'(한 번에 가져올 데이터 갯수)에 0보다 큰 값
을 지정한다. 그렇지 않으면 조회결과 전체를 반환한다.
다음은 조회결과를 페이징하여 제공하는 방법을 사용자 정보(User)를 예로 설명하는 것이다.
BusinessRequest
public class UserQuery extends QueryRequest {
private String[] userIDs;
public String[] getUserIDs() {
return ifEmpty(userIDs, () -> null);
}
public void setUserIDs(String... userIDs) {
this.userIDs = userIDs;
}
}
UserQuery는 QueryRequest에서 상속받는 다음 공통 파라미터와
- by - 조회 필드 이름
- term - 조회 조건값
- orderBy - 정렬 필드
- pageNum - 페이징 시 페이지 번호
- fetchSize - 페이징 시 데이터 갯수
- download - 다운로드 여부(예: 'xls')
userIDs라는 사용자 정보를 위한 파라미터를 정의한다.
주의: 파라미터 'by'와 'orderBy'에는
- 테이블 컬럼이름을 직접 명시하지 않는다. 대신,
- 임의로 정한 값을 받아 BusinessBean에서 컬럼이름으로 치환한다.
business-mapper.xml
<select id="getUserList" parameterType="map" resultType="dataobject">/* 사용자 목록 조회(userMapper.getUserList) */
<include refid="utility.paging-prefix" />
SELECT ...
FROM TB_USER
<where><if test="by != null and term != null">AND ${by} LIKE CONCAT('%', #{term}, '%')</if>
<if test="userIDs != null">USER_ID IN (<foreach collection="userIDs" item="userID" separator=",">#{userID}</foreach>)</if>
</where>
<include refid="utility.orderBy" />
<include refid="utility.paging-suffix" />
</select>
- parameterType은 map으로 한다.
- resultType은 dataobject로 한다.
페이징을 위해
- SELECT문 앞에
<include refid="utility.paging-prefix" />
을 삽입한다. - SELECT문 뒤에
<include refid="utility.paging-suffix" />
를 삽입한다.
BusinessMapper
@Mapper("userMapper")
public interface UserMapper extends AbstractMapper {
List<DataObject> getUserList(UserQuery req);
...
}
업무별 매퍼는 AbstractMapper를 상속하여 정의한다.
BusinessBean
@Component("userBean")
public class UserBean extends AbstractBean {
@Resource(name = "userMapper")
private UserMapper userMapper;
public List<DataObject> getUserList(UserQuery req) {
switch (blankIfEmpty(req.getBy())) {
case "userAccount": req.setBy("USER_ACNT"); break;
default: req.setBy("USER_NM"); break;
}
req.setOrderBy(req.getBy());
return userMapper.getUserList(req);
}
...
}
업무별 Bean은 AbstractBean를 상속하여 정의한다.
파라미터 by의 값을 컬럼이름으로 치환한다.
파라미터 orderBy의 값을 by에 설정된 컬럼으로 설정한다.
BusinessServiceBean
public interface UserService {
List<DataObject> getUserList(UserQuery req);
...
}
@Service("userService")
public class UserServiceBean extends AbstractServiceBean implements UserService {
@Resource(name = "userBean")
private UserBean userBean;
public List<DataObject> getUserList(UserQuery req) {
return userBean.getUserList(req);
}
...
}
업무별 ServiceBean은 AbstractServiceBean를 상속하여 정의한다.
BusinessController
@Controller
@RequestMapping(name = "사용자", value = "/user")
public class UserController extends AbstractController {
@Resource(name = "userService")
private UserService userService;
@GetMapping(name = "사용자 조회", value = "/list.do")
public ModelAndView getUserList(UserQuery req) {
List<DataObject> userList = userService.getUserList(req);
// JSP로 전달, 또는
// jsonView로 전달
// 아래 참고
}
}
업무별 Controller는 AbstractController를 상속하여 정의한다.
기능 메소드의 url 매핑은
- @GetMapping이나 @PostMapping으로 한다.
- 애트리뷰트 name과 value를 명시한다.
- url은
**/*.do
의 패턴으로 한다.
조회결과는 'setCollectionInfo(ModelAndView mav, Collection collection, String prefix)' 메소드로 응답을 설정한다. 이 메소드는 mav에
- 'infoPrefix' 키에 prefix를 설정
- 조회결과 collection을 prefix + 'List'를 키로 하여 설정
- prefix + 'Start'를 키로 하여 조회결과 시작 인덱스를 설정
- prefix + 'Fetch'를 키로 하여 한 번에 가져오는 데이터 갯수를 설정
- prefix + 'Total'를 키로 하여 조회결과 데이터 전체 갯수를 설정
한다.
위 예의 경우
- 'infoPrefix' 키에 'user'를 설정
- 조회결과 userList를 'userList'를 키로 하여 설정
- 'userStart'를 키로 하여 조회결과 시작 인덱스를 설정
- 'userFetch'를 키로 하여 한 번에 가져오는 데이터 갯수를 설정
- 'userTotal'를 키로 하여 조회결과 데이터 전체 갯수를 설정 한다.
조회결과 데이터는 JSON 포맷으로 전달해야 한다.
조회결과 데이터를 지정하는 경로의 JSP에 JSON 포맷으로 전달하려면 다음과 같이 한다.
ModelAndView mav = setCollectionInfo(
new ModelAndView("JSP 경로"),
userList,
"user"
);
return mav.addObject("userList", toJson(mav.getModel().remove("userList")));
조회결과 데이터를 jsonView로 전달하려면 다음과 같이 한다.
return setCollectionInfo(
new ModelAndView("jsonView"),
userList,
"user"
);