You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
296 lines
9.3 KiB
296 lines
9.3 KiB
/* |
|
* 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()); |
|
// } |
|
// } |
|
|
|
} |
|
} |
|
}
|
|
|