/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package kr.co.kihyun.service; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.List; import java.util.Map; import javax.jdo.PersistenceManager; import javax.jdo.Query; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Kts */ public class BaseService { private static final Logger LOG = LoggerFactory.getLogger(BaseService.class); int recordCount = 0; protected StringBuilder countQuery; protected StringBuilder searchQuery; protected Map params; protected PersistenceManager pm; /** * 기본생성자 */ public BaseService() { } /** * 생성자 * @param pm PersistenceManager */ public BaseService(PersistenceManager pm) { this.pm = pm; } /** * PersistenceManager객체를 저장한다. * @param pm PersistenceManager */ public void setPm(PersistenceManager pm) { this.pm = pm; } /** * 조건을 만족하는 레코드갯수를 반환한다. * @return int */ public int getCount() { return getCount(null); } /** * 쿼리를 파리미터로 받고 조건을 만족하는 레코드갯수를 반환한다. * @param sb StringBuilder * @return int */ public int getCount(StringBuilder sb) { StringBuilder sql = sb; if( sb == null ) { sql = countQuery; } return getResultCount(sql); } /** * Main Query로 부터 쿼리를 생성하고 조건을 만족하는 레코드갯수를 반환한다. * @return int */ public int getCountFromMainQuery() { return getCountFromMainQuery(null); } /** * Main Query로 부터 쿼리를 생성하고 조건을 만족하는 레코드갯수를 반환한다. * @param sb StringBuilder * @return int */ public int getCountFromMainQuery(StringBuilder sb) { StringBuilder sql = sb; if( sb == null ) { sql = countQuery; sql.insert(0, "SELECT COUNT(*) AS CNT FROM (\n"); sql.append(") "); } return getResultCount(sql); } /** * 레코드갯수를 반환하는 쿼리를 실행하는 메소드 * @param sql * @return int */ private int getResultCount(StringBuilder sql) { Query query = pm.newQuery("javax.jdo.query.SQL",sql.toString()); //LOG.debug("count query={}", sql.toString()); if( params != null && params.size() > 0 ) { List list = (List)query.executeWithMap(params); return ((BigDecimal)list.get(0)).intValue(); } return -1; } /** * Main Query로 부터 Paginating Query를 생성한다. * 쿼리성능을 위해서 마지막레코드 위치를 파라미터로 넘겨준다. * DB2에 최적화된 쿼리이므로 다른 DBMS에 적용 시 변경 필요. * @param sb StringBuilder * @param endNo int - 마지막레코드 위치 * @return int */ protected StringBuilder procPagenatingQuery(StringBuilder sb, int endNo) { StringBuilder pagenatingQuery = new StringBuilder(); pagenatingQuery.append(sb); pagenatingQuery.insert(0, "SELECT * FROM (\n"); //변수를 설정할 수 없음 //sb.append("FETCH FIRST :endNo ROW ONLY\n"); pagenatingQuery.append("FETCH FIRST "); pagenatingQuery.append(endNo); pagenatingQuery.append(" ROW ONLY\n"); pagenatingQuery.append(")R WHERE R.ROWNO BETWEEN :startNo AND :endNo with UR \n"); return pagenatingQuery; } /** * Main Query로 부터 Paginating Query를 생성한다. * 쿼리성능을 위해서 마지막레코드 위치를 파라미터로 넘겨준다. * DB2에 최적화된 쿼리이므로 다른 DBMS에 적용 시 변경 필요. * @param sb StringBuilder * @return int */ public StringBuilder procPagenatingQuery(StringBuilder sb) { return procPagenatingQuery(sb, (Integer)this.getParams().get("endNo")); } /** * 메인검색쿼리를 페이징처리하는 쿼리로 변경하는 메소드 */ public void convertToPagenatingQuery() { // searchQuery.insert(0, "SELECT * FROM (\n"); // searchQuery.append("FETCH FIRST "); // searchQuery.append((Integer)this.getParams().get("endNo") == 0 ? 1 : (Integer)this.getParams().get("endNo") ); // searchQuery.append(" ROW ONLY\n"); // searchQuery.append(")R WHERE R.ROWNO BETWEEN :startNo AND :endNo \n"); searchQuery.insert(0, "SELECT * FROM (SELECT ROWNUM AS ROWNO, R.* FROM( \n"); searchQuery.append(")R)S WHERE S.ROWNO BETWEEN :startNo AND :endNo \n"); if( LOG.isDebugEnabled() ) { LOG.debug("paginating query={}", searchQuery.toString()); LOG.debug("params={}", params); } } /** * 멤버변수 searchQuery에 저장된 쿼리를 실행한 결과를 반환하는 메소드 * @param cls - VO객체에 대한 클래스객체 * @return List - 검색결과목록 */ public List executeQuery(Class cls) { return executeQuery(null, null, cls); } /** * 쿼리를 실행한 결과를 반환하는 메소드 * @param sbQuery - 쿼리객체 * @param params - 검색조건맵 * @param cls - VO객체에 대한 클래스객체 * @return List - 검색결과목록 */ public List executeQuery(final StringBuilder sbQuery, final Map params, final Class cls) { StringBuilder sql = sbQuery; if( sql == null || sql.length() == 0 ) sql = searchQuery; Query query = pm.newQuery("javax.jdo.query.SQL", sql.toString()); if( cls != null ) { query.setResultClass(cls); } Map parameters = params; if( parameters == null || parameters.isEmpty() ) parameters = this.params; List list = (List)query.executeWithMap(parameters); return list; } /** * 멤버변수 searchQuery에 저장된 쿼리를 실행한 결과를 반환하는 메소드 * @return List - 검색결과목록 */ public List executeQuery() { return executeQuery(null); } /** * 레코드갯수조회 쿼리를 반환하는 멤버메소드 * @return */ public StringBuilder getCountQuery() { return countQuery; } /** * 레코드갯수조회 쿼리를 설정하는 멤버메소드 * @param countQuery - 레코드갯수조회 쿼리 */ public void setCountQuery(StringBuilder countQuery) { this.countQuery = new StringBuilder(countQuery); } /** * 검색조회 쿼리를 반환하는 멤버메소드 * @return */ public StringBuilder getSearchQuery() { return searchQuery; } /** * 검색조회 쿼리를 설정하는 멤버메소드 * @param searchQuery */ public void setSearchQuery(StringBuilder searchQuery) { this.searchQuery = searchQuery; } /** * 검색조건파라미터맵을 반환하는 멤버메소드 * @return */ public Map getParams() { return params; } /** * 검색조건파라미터맵을 설정하는 멤버메소드 * @param params */ public void setParams(Map params) { this.params = params; } /** * List에 존재하는 객체의 멤버변수에 대한 로그출력 메소드 * @param list - 동일한 객체가 존재해야 한다. */ public void logResultList(List list) { //Method[] methods = list.get(0).getClass().getDeclaredMethods(); int size = list.size(); if( size == 0 ) return; for( int i = 0; i < size; i++ ) { Object obj = list.get(i); Field[] fields = obj.getClass().getDeclaredFields(); for( Field field : fields ) { try { field.setAccessible(true); Object fObj = field.get(obj); if( fObj == null ) continue; if( LOG.isDebugEnabled() ) { LOG.debug("Row {}:{}={}", new Object[]{(i+ 1),field.getName(), fObj}); } }catch(IllegalAccessException ex) { if( LOG.isErrorEnabled() ) LOG.debug("field error1={}", ex.getMessage()); } catch (IllegalArgumentException ex) { if( LOG.isErrorEnabled() ) LOG.debug("field error2={}", ex.getMessage()); } catch (SecurityException ex) { if( LOG.isErrorEnabled() ) LOG.debug("field error3={}", ex.getMessage()); } } // for( Method method : methods ) { // String methodName = method.getName(); // if( !methodName.startsWith("get") ) continue; // // try { // Object rtnObj = method.invoke(obj, new Object[]{}); // if( rtnObj == null ) continue; // LOG.debug("{}={}",methodName, rtnObj); // // }catch(Exception ex) { // LOG.debug("error={}", ex.getMessage()); // } // } } } }