Compare commits

...

2 Commits

@ -0,0 +1,75 @@
package com.xit.core.mybatis;
import java.lang.reflect.*;
import java.util.*;
import org.apache.ibatis.executor.parameter.*;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.parsing.*;
import org.apache.ibatis.scripting.xmltags.*;
import org.apache.ibatis.session.*;
import lombok.*;
import lombok.extern.slf4j.*;
/**
* <pre>
* Mybatis sql logging
* mybatis.configuration.default-scripting-language=com.xit.core.support.mybatis.MybatisLanguageDriver
* </pre>
*/
@Slf4j
public class MybatisLanguageDriver extends XMLLanguageDriver {
public MybatisLanguageDriver() {
}
@Override
public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
addDebuggingComment(boundSql);
return super.createParameterHandler(mappedStatement, parameterObject, boundSql);
}
@Override
public SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType) {
return super.createSqlSource(configuration, script, parameterType);
}
@Override
public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
return super.createSqlSource(configuration, script, parameterType);
}
@SneakyThrows
private void addDebuggingComment(BoundSql boundSql) {
Field sqlField = BoundSql.class.getDeclaredField("sql");
sqlField.setAccessible(true);
String sql = (String) sqlField.get(boundSql);
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
sql = addParameterComment(sql, parameterMappings);
sqlField.set(boundSql, sql);
}
private String addParameterComment(String sql, List<ParameterMapping> parameters) {
StringBuilder sqlInternalStringBuilder = new StringBuilder(sql);
int paramReverseIndex = parameters.size() - 1;
for (int idx = sql.length() - 1; idx > 0; idx--) {
char c = sql.charAt(idx);
if (c == '?') {
String commentedString = toCommentString(parameters.get(paramReverseIndex).getProperty());
sqlInternalStringBuilder.insert(idx + 1, commentedString);
paramReverseIndex = paramReverseIndex - 1;
}
}
return sqlInternalStringBuilder.toString();
}
private String toCommentString(String comment) {
return " /*" + comment + "*/ ";
}
}

@ -0,0 +1,40 @@
package com.xit.core.mybatis;
import java.util.*;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.*;
import org.springframework.context.annotation.*;
import com.xit.core.mybatis.paging.util.*;
/**
* <pre>
* description : For Pagination Tag
* packageName : com.xit.core.mybatis
* fileName : MybatisPagiRenderConfig
* author : limju
* date : 2024 12 31
* ======================================================================
*
* ----------------------------------------------------------------------
* 2024 12 31 limju
*
* </pre>
*/
@Configuration
public class MybatisPagiRenderConfig {
@Bean
public XitPaginationRenderer xitPaginationRenderer(){
return new XitPaginationRenderer();
}
@Bean
public PaginationManager xitPaginationManager(){
Map<String, PaginationRenderer> rendererType = new HashMap<>();
rendererType.put("user", xitPaginationRenderer());
DefaultPaginationManager paginationManager = new DefaultPaginationManager();
paginationManager.setRendererType(rendererType);
return paginationManager;
}
}

@ -0,0 +1,77 @@
package com.xit.core.mybatis;
import java.sql.*;
import java.util.Date;
import org.apache.ibatis.type.*;
public class ObjectTypeHandler extends BaseTypeHandler<Object> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException {
ps.setObject(i, parameter);
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
Object value = "";
Object object = rs.getObject(columnName);
value = object;
if(object instanceof Clob) {
Clob clob = (Clob) object;
if (clob != null) {
try {
int size = (int) clob.length();
value = clob.getSubString(1, size);
} catch (Exception e) {
e.printStackTrace();
}
}
}
else if (object instanceof java.sql.Date ) {
Timestamp sqlTimestamp = rs.getTimestamp(columnName);
if (sqlTimestamp != null) {
value = new Date(sqlTimestamp.getTime());
}
}
return value;
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
Object value = "";
Object object = rs.getObject(columnIndex);
value = object;
if(object instanceof Clob) {
Clob clob = (Clob) object;
if (clob != null) {
try {
int size = (int) clob.length();
value = clob.getSubString(1, size);
} catch (Exception e) {
e.printStackTrace();
}
}
}
else if (object instanceof java.sql.Date ) {
Timestamp sqlTimestamp = rs.getTimestamp(columnIndex);
if (sqlTimestamp != null) {
value = new Date(sqlTimestamp.getTime());
}
}
return value;
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getObject(columnIndex);
}
}

@ -0,0 +1,208 @@
package com.xit.core.mybatis;
import java.nio.charset.*;
import org.apache.ibatis.plugin.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
public class PagingConstants {
public static final String KEY_OP_MODE = "spring.profiles.active";
public static final String OP_MODE_DEFAULT = "local";
// RestTemplate 상수
public static final int CONNECT_TIMEOUT = 30 * 1000; // 30초
public static final int READ_TIMEOUT = 60 * 1000 * 3; // 3분
public static final Charset CHARSET = StandardCharsets.UTF_8;
public static final String DEFAULT_VIEW = ViewName.JSON_VIEW.getCode();
/**
* CustomCommonsRequestLoggingFilter url
*/
public static final String EXCLUDE_LOGGING_URL_PATTERN = "^(/webjars/|/swagger-ui/|/swagger-resources|/v2/api-docs|/h2-console)"; // "^(/webjars/|/sample/|/web/)"
public enum ActiveProfile {
LOCAL("local"),
DEV("dev"),
STG("stg"),
PROD("prod"),
TEST("test");
private final String code;
ActiveProfile(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
/**
*
*
*/
public enum AuthSaveType {
SECURITY("security"), // SessionCreationPolicy.STATELESS인 경우는 SecurityContext 사용불가
SESSION("session"), // TOKEN도 사용 가능은 하지만...
HEADER("header"); // TOKEN
private final String code;
AuthSaveType(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
public enum JwtToken {
// 토큰헤더명,
HEADER_NAME("Authorization"),
GRANT_TYPE("Bearer"),
ACCESS_TOKEN_NAME("accessToken"),
REFRESH_TOKEN_NAME("refreshToken"),
AUTHORITIES_KEY("role"),
TOKEN_USER_NAME("userName"),
TOKEN_USER_MAIL("userEmail"),
TOKEN_USER_ID("userId");
private final String code;
JwtToken(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
/**
* JWT Token
* COOKIE : accessToken - header, refreshToken - cookie
* HEADER : accessToken - header, refreshToken - DTO
* DTO : accessToken - header, refreshToken - DTO
*/
public enum JwtTokenParamType {
COOKIE,
HEADER,
DTO
}
public enum ViewName{
JSON_VIEW("mappingJackson2JsonView")
;
private String code;
ViewName(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
/**
* mybatis paging return list root attribute name
* @see PageListJsonSerializer#serialize(PageList, JsonGenerator, SerializerProvider)
*/
public static final String RSLT_ATTR_NAME = "_item_";
/**
* Maybatis / jpa
* @see OffsetLimitInterceptor#intercept(Invocation)
* @see Paginator#setSessionPagination(Paginator)
* @see kr.xit.fims.framework.support.jpa.Paginator#setSessionPagination(com.xit.core.support.jpa.Paginator)
*/
public enum Session {
PAGE_INFO("_pageInfo_"),
// DATASET_NAME("gds_pageInfo"),
/** 세션에 저장되는 인증유저 객체 attribute name */
AuthentSessionObject("AUTH_SS_OBJECT"),
/** 세션에 저장되는 인증유저 권한종류 attribute name */
AuthentSessionAuthority("AUTH_SS_AUTHORITY"),
;
private String code;
Session( String code ) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
public enum LoginType {
SSO,
Login,
Unknown
}
public enum CharsetType {
Default("default"),
Utf8( "UTF-8" ),
EucKr( "EUC-KR" ),
Iso8859("8859_1");
private String code;
CharsetType( String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
public Charset getCharset() {
if ( this == Default )
return Charset.defaultCharset();
return Charset.forName( this.code);
}
public byte[] getBytes( String str ) {
return str.getBytes( this.getCharset() );
}
public String getString( byte[] bytes ) {
return new String( bytes, this.getCharset() );
}
}
/**
* String pad
* @ : PadType
*/
public enum PadType {
/** 문자열 왼쪽 */
Left,
/** 문자열 오른쪽 */
Right
}
public enum PageNavigator {
DIV_ID("pager"),
CLASS_NAME("pager"),
FIRST_SYMBOLIC(" ◀ "),
PREV_SYMBOLIC(" ◁ "),
NEXT_SYMBOLIC(" ▷ "),
LAST_SYMBOLIC(" ▶ ");
private String code;
PageNavigator(String code) {
this.code = code;
}
public String getCode() {
return this.code;
}
}
}

@ -0,0 +1,167 @@
package com.xit.core.mybatis;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.locks.*;
import org.apache.commons.logging.*;
import org.apache.ibatis.session.*;
import org.mybatis.spring.*;
import org.springframework.beans.factory.*;
import org.springframework.core.io.*;
/**
* mybatis mapper
*/
public class RefreshableSqlSessionFactoryBean extends SqlSessionFactoryBean implements DisposableBean {
private static final Log log = LogFactory.getLog(RefreshableSqlSessionFactoryBean.class);
private SqlSessionFactory proxy;
private int interval = 500;
private Timer timer;
private TimerTask task;
private Resource[] mapperLocations;
/**
* .
*/
private boolean running = false;
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public void setMapperLocations(Resource[] mapperLocations) {
super.setMapperLocations(mapperLocations);
this.mapperLocations = mapperLocations;
}
public void setInterval(int interval) {
this.interval = interval;
}
/**
* @throws Exception
*/
public void refresh() throws Exception {
if (log.isInfoEnabled()) {
log.info("refreshing sqlMapClient.");
}
w.lock();
try {
super.afterPropertiesSet();
} finally {
w.unlock();
}
}
/**
* SqlMapClient .
*/
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
setRefreshable();
}
private void setRefreshable() {
proxy = (SqlSessionFactory) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] { SqlSessionFactory.class }, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// log.debug("method.getName() : " + method.getName());
return method.invoke(getParentObject(), args);
}
});
task = new TimerTask() {
private final Map<Resource, Long> map = new HashMap<>();
public void run() {
if (isModified()) {
try {
refresh();
} catch (Exception e) {
log.error("caught exception", e);
}
}
}
private boolean isModified() {
boolean retVal = false;
if (mapperLocations != null) {
for (int i = 0; i < mapperLocations.length; i++) {
Resource mappingLocation = mapperLocations[i];
retVal |= findModifiedResource(mappingLocation);
}
}
return retVal;
}
private boolean findModifiedResource(Resource resource) {
boolean retVal = false;
List<String> modifiedResources = new ArrayList<String>();
try {
long modified = resource.lastModified();
if (map.containsKey(resource)) {
long lastModified = (Long) map.get(resource);
if (lastModified != modified) {
map.put(resource, modified);
modifiedResources.add(resource.getDescription());
retVal = true;
}
} else {
map.put(resource, modified);
}
} catch (IOException e) {
log.error("caught exception", e);
}
if (retVal) {
if (log.isInfoEnabled()) {
log.info("modified files : " + modifiedResources);
}
}
return retVal;
}
};
timer = new Timer(true);
resetInterval();
}
private Object getParentObject() throws Exception {
r.lock();
try {
return super.getObject();
} finally {
r.unlock();
}
}
public SqlSessionFactory getObject() {
return this.proxy;
}
public Class<? extends SqlSessionFactory> getObjectType() {
return (this.proxy != null ? this.proxy.getClass() : SqlSessionFactory.class);
}
public boolean isSingleton() {
return true;
}
public void setCheckInterval(int ms) {
interval = ms;
if (timer != null) {
resetInterval();
}
}
private void resetInterval() {
if (running) {
timer.cancel();
running = false;
}
if (interval > 0) {
timer.schedule(task, 0, interval);
running = true;
}
}
public void destroy() throws Exception {
timer.cancel();
}
}

@ -0,0 +1,13 @@
package com.xit.core.mybatis.paging;
import javax.servlet.*;
public class CleanupMybatisPaginatorListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
OffsetLimitInterceptor.Pool.shutdownNow();
}
}

@ -0,0 +1,210 @@
package com.xit.core.mybatis.paging;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
import org.apache.commons.lang3.*;
import org.apache.ibatis.cache.*;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.mapping.MappedStatement.*;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.*;
import org.slf4j.*;
import org.springframework.web.context.request.*;
import com.xit.core.mybatis.*;
import com.xit.core.mybatis.paging.dialect.*;
import com.xit.core.mybatis.paging.domain.*;
import com.xit.core.mybatis.paging.support.*;
import lombok.extern.slf4j.*;
/**
* Paging - Paginator(page, limit, totalcount)- ,
*/
@Slf4j
@Intercepts({ @Signature(type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })
public class OffsetLimitInterceptor implements Interceptor {
//private final Logger log = LoggerHelper.getLogger();
static int MAPPED_STATEMENT_INDEX = 0;
static int PARAMETER_INDEX = 1;
static int ROWBOUNDS_INDEX = 2;
//static int RESULT_HANDLER_INDEX = 3;
static ExecutorService Pool;
String dialectClass;
boolean asyncTotalCount = false;
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object intercept(final Invocation invocation) throws Throwable {
final Executor executor = (Executor) invocation.getTarget();
final Object[] queryArgs = invocation.getArgs();
final MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
final Object parameter = queryArgs[PARAMETER_INDEX];
final RowBounds rowBounds = (RowBounds) queryArgs[ROWBOUNDS_INDEX];
final PageBounds pageBounds = new PageBounds(rowBounds);
if (pageBounds.getOffset() == RowBounds.NO_ROW_OFFSET && pageBounds.getLimit() == RowBounds.NO_ROW_LIMIT && pageBounds.getOrders().isEmpty()) {
return invocation.proceed();
}
final Dialect dialect;
try {
Class clazz = Class.forName(dialectClass);
Constructor constructor = clazz.getConstructor(MappedStatement.class, Object.class, PageBounds.class);
dialect = (Dialect) constructor.newInstance(new Object[] { ms, parameter, pageBounds });
} catch (Exception e) {
throw new ClassNotFoundException("Cannot create dialect instance: " + dialectClass, e);
}
final BoundSql boundSql = ms.getBoundSql(parameter);
queryArgs[MAPPED_STATEMENT_INDEX] = copyFromNewSql(ms, boundSql, dialect.getPageSQL(), dialect.getParameterMappings(), dialect.getParameterObject());
queryArgs[PARAMETER_INDEX] = dialect.getParameterObject();
queryArgs[ROWBOUNDS_INDEX] = new RowBounds(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);
boolean async = pageBounds.getAsyncTotalCount() == null ? asyncTotalCount : pageBounds.getAsyncTotalCount();
Future<List> listFuture = call((Callable<List>) () -> (List) invocation.proceed(), async);
if (pageBounds.isContainsTotalCount()) {
Callable<Paginator> countTask = (Callable) () -> {
Paginator paginator;
Integer count;
Cache cache = ms.getCache();
if (cache != null && ms.isUseCache() && ms.getConfiguration().isCacheEnabled()) {
CacheKey cacheKey = executor.createCacheKey(
ms,
parameter,
new PageBounds(),
copyFromBoundSql(ms, boundSql, dialect.getCountSQL(), boundSql.getParameterMappings(), boundSql.getParameterObject()));
count = (Integer) cache.getObject(cacheKey);
if (count == null) {
count = SQLHelp.getCount(ms, parameter, boundSql, dialect);
cache.putObject(cacheKey, count);
}
} else {
count = SQLHelp.getCount(ms, parameter, boundSql, dialect);
}
paginator = new Paginator(pageBounds.getPage(), pageBounds.getLimit(), count);
return paginator;
};
Future<Paginator> countFutrue = call(countTask, async);
// PageList pageList = new PageList(listFuture.get(), countFutrue.get());
// log.debug("###################################################################################");
// log.debug("OffsetLimitInterceptor Page information ThreadLocal save::{} - {}", FEnum.Session.PAGE_INFO.getValue(), countFutrue.get());
// log.debug("###################################################################################");
RequestContextHolder.currentRequestAttributes().setAttribute(PagingConstants.Session.PAGE_INFO.getCode(), countFutrue.get(), RequestAttributes.SCOPE_REQUEST);
// ContextThreadLocalHolder.setPageListThreadLocal(pageList);
// return pageList; return new PageList(listFuture.get(), countFutrue.get());
}
return listFuture.get();
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private <T> Future<T> call(Callable callable, boolean async) {
if (async) {
return Pool.submit(callable);
} else {
FutureTask<T> future = new FutureTask(callable);
future.run();
return future;
}
}
private MappedStatement copyFromNewSql(MappedStatement ms, BoundSql boundSql, String sql, List<ParameterMapping> parameterMappings, Object parameter) {
BoundSql newBoundSql = copyFromBoundSql(ms, boundSql, sql, parameterMappings, parameter);
return copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
}
private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql, List<ParameterMapping> parameterMappings, Object parameter) {
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, parameterMappings, parameter);
for (ParameterMapping mapping : boundSql.getParameterMappings()) {
String prop = mapping.getProperty();
if (boundSql.hasAdditionalParameter(prop)) {
newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
}
}
return newBoundSql;
}
// see: MapperBuilderAssistant
private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
Builder builder = new Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
if (ObjectUtils.isNotEmpty(ms.getKeyProperties())) {
StringBuilder keyProperties = new StringBuilder();
for (String keyProperty : ms.getKeyProperties()) {
keyProperties.append(keyProperty).append(",");
}
keyProperties.delete(keyProperties.length() - 1, keyProperties.length());
builder.keyProperty(keyProperties.toString());
}
// setStatementTimeout()
builder.timeout(ms.getTimeout());
// setStatementResultMap()
builder.parameterMap(ms.getParameterMap());
// setStatementResultMap()
builder.resultMaps(ms.getResultMaps());
builder.resultSetType(ms.getResultSetType());
// setStatementCache()
builder.cache(ms.getCache());
builder.flushCacheRequired(ms.isFlushCacheRequired());
builder.useCache(ms.isUseCache());
return builder.build();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
PropertiesHelper propertiesHelper = new PropertiesHelper(properties);
String dialectClass = propertiesHelper.getRequiredString("dialectClass");
setDialectClass(dialectClass);
setAsyncTotalCount(propertiesHelper.getBoolean("asyncTotalCount", false));
setPoolMaxSize(propertiesHelper.getInt("poolMaxSize", 0));
}
public static class BoundSqlSqlSource implements SqlSource {
BoundSql boundSql;
public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}
public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}
public void setDialectClass(String dialectClass) {
//logger.debug("dialectClass: {} ", dialectClass);
this.dialectClass = dialectClass;
}
public void setAsyncTotalCount(boolean asyncTotalCount) {
//logger.debug("asyncTotalCount: {} ", asyncTotalCount);
this.asyncTotalCount = asyncTotalCount;
}
public void setPoolMaxSize(int poolMaxSize) {
if (poolMaxSize > 0) {
log.debug("poolMaxSize: {} ", poolMaxSize);
Pool = Executors.newFixedThreadPool(poolMaxSize);
} else {
Pool = Executors.newCachedThreadPool();
}
}
}

@ -0,0 +1,68 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class DB2Dialect extends Dialect {
public DB2Dialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
private static String getRowNumber(String sql) {
StringBuilder rownumber = new StringBuilder(50)
.append("rownumber() over(");
int orderByIndex = sql.toLowerCase().indexOf("order by");
if (orderByIndex > 0 && !hasDistinct(sql)) {
rownumber.append(sql.substring(orderByIndex));
}
rownumber.append(") as rownumber_,");
return rownumber.toString();
}
private static boolean hasDistinct(String sql) {
return sql.toLowerCase().contains("select distinct");
}
protected String getLimitString(String sql, String offsetName, int offset,
String limitName, int limit) {
int startOfSelect = sql.toLowerCase().indexOf("select");
StringBuilder pagingSelect = new StringBuilder(sql.length() + 100)
.append(sql, 0, startOfSelect) // add the comment
.append("select * from ( select ") // nest the main query in an
// outer select
.append(getRowNumber(sql)); // add the rownnumber bit into the
// outer query select list
if (hasDistinct(sql)) {
pagingSelect.append(" row_.* from ( ") // add another (inner) nested
// select
.append(sql.substring(startOfSelect)) // add the main query
.append(" ) as row_"); // close off the inner nested select
} else {
pagingSelect.append(sql.substring(startOfSelect + 6)); // add the
// main
// query
}
pagingSelect.append(" ) as temp_ where rownumber_ ");
// add the restriction to the outer select
if (offset > 0) {
pagingSelect.append("between ?+1 and ?");
setPageParameter(offsetName, offset, Integer.class);
setPageParameter("__offsetEnd", offset + limit, Integer.class);
} else {
pagingSelect.append("<= ?");
setPageParameter(limitName, limit, Integer.class);
}
return pagingSelect.toString();
}
}

@ -0,0 +1,31 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class DerbyDialect extends Dialect {
public DerbyDialect(MappedStatement mappedStatement,
Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
public boolean supportsLimit() {
return true;
}
public boolean supportsLimitOffset() {
return true;
}
public String getLimitString(String sql, int offset,
String offsetPlaceholder, int limit, String limitPlaceholder) {
return sql +
" offset " + offsetPlaceholder + " rows fetch next "
+ limitPlaceholder + " rows only";
}
}

@ -0,0 +1,123 @@
package com.xit.core.mybatis.paging.dialect;
import java.util.*;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.session.*;
import com.xit.core.mybatis.paging.domain.*;
public class Dialect {
protected MappedStatement mappedStatement;
protected PageBounds pageBounds;
protected Object parameterObject;
protected BoundSql boundSql;
protected List<ParameterMapping> parameterMappings;
protected Map<String, Object> pageParameters = new HashMap<String, Object>();
private String pageSQL;
private String countSQL;
public Dialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
this.mappedStatement = mappedStatement;
this.parameterObject = parameterObject;
this.pageBounds = pageBounds;
init();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
protected void init() {
boundSql = mappedStatement.getBoundSql(parameterObject);
parameterMappings = new ArrayList(boundSql.getParameterMappings());
if (parameterObject instanceof Map) {
pageParameters.putAll((Map) parameterObject);
} else {
for (ParameterMapping parameterMapping : parameterMappings) {
pageParameters.put(parameterMapping.getProperty(), parameterObject);
}
}
StringBuilder bufferSql = new StringBuilder(boundSql.getSql().trim());
if (bufferSql.lastIndexOf(";") == bufferSql.length() - 1) {
bufferSql.deleteCharAt(bufferSql.length() - 1);
}
String sql = bufferSql.toString();
pageSQL = sql;
if (pageBounds.getOrders() != null && !pageBounds.getOrders().isEmpty()) {
pageSQL = getSortString(sql, pageBounds.getOrders());
}
if (pageBounds.getOffset() != RowBounds.NO_ROW_OFFSET || pageBounds.getLimit() != RowBounds.NO_ROW_LIMIT) {
pageSQL = getLimitString(pageSQL, "__offset", pageBounds.getOffset(), "__limit", pageBounds.getLimit());
}
countSQL = getCountString(sql);
}
public List<ParameterMapping> getParameterMappings() {
return parameterMappings;
}
public Object getParameterObject() {
return pageParameters;
}
public String getPageSQL() {
return pageSQL;
}
@SuppressWarnings("rawtypes")
protected void setPageParameter(String name, Object value, Class type) {
ParameterMapping parameterMapping = new ParameterMapping.Builder(mappedStatement.getConfiguration(), name, type).build();
parameterMappings.add(parameterMapping);
pageParameters.put(name, value);
}
public String getCountSQL() {
return countSQL;
}
/**
* page query make
*
* @param sql sql
* @param offsetName offsetName
* @param offset offset
* @param limitName limitName
* @param limit limit
* @return String query
*/
protected String getLimitString(String sql, String offsetName, int offset, String limitName, int limit) {
throw new UnsupportedOperationException("paged queries not supported");
}
/**
* get total count SQL
*
* @param sql SQL
* @return String count sql
*/
protected String getCountString(String sql) {
return "select count(1) from (\n" + sql + "\n) tmp_count";
}
/**
* ordered sql
*
* @param sql SQL
* @param orders ordered field List
* @return sql
*/
protected String getSortString(String sql, List<Order> orders) {
if (orders == null || orders.isEmpty()) {
return sql;
}
StringBuilder buffer = new StringBuilder("select * from (\n").append(sql).append("\n) temp_order order by ");
for (Order order : orders) {
if (order != null) {
buffer.append(order.toString()).append(", ");
}
}
buffer.delete(buffer.length() - 2, buffer.length());
return buffer.toString();
}
}

@ -0,0 +1,19 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class H2Dialect extends Dialect {
public H2Dialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName,int offset, String limitName, int limit) {
return sql +
((offset > 0) ? " limit " + String.valueOf(limit) + " offset " + String.valueOf(offset) : " limit " + String.valueOf(limit));
}
}

@ -0,0 +1,19 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class HSQLDialect extends Dialect {
public HSQLDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName, int offset, String limitName, int limit) {
boolean hasOffset = offset > 0;
return new StringBuffer(sql.length() + 10)
.append(sql)
.insert(sql.toLowerCase().indexOf("select") + 6,
hasOffset ? " limit " + String.valueOf(offset) + " " + String.valueOf(limit) : " top " + String.valueOf(limit)).toString();
}
}

@ -0,0 +1,26 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class MariaDbDialect extends Dialect {
public MariaDbDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName, int offset, String limitName, int limit) {
StringBuilder buffer = new StringBuilder(sql.length() + 20).append(sql);
if (offset > 0) {
buffer.append("\n limit ?, ?");
setPageParameter(offsetName, offset, Integer.class);
setPageParameter(limitName, limit, Integer.class);
} else {
buffer.append("\n limit ?");
setPageParameter(limitName, limit, Integer.class);
}
return buffer.toString();
}
}

@ -0,0 +1,26 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class MySQLDialect extends Dialect {
public MySQLDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName, int offset, String limitName, int limit) {
StringBuilder buffer = new StringBuilder(sql.length() + 20).append(sql);
if (offset > 0) {
buffer.append("\n limit ?, ?");
setPageParameter(offsetName, offset, Integer.class);
setPageParameter(limitName, limit, Integer.class);
} else {
buffer.append("\n limit ?");
setPageParameter(limitName, limit, Integer.class);
}
return buffer.toString();
}
}

@ -0,0 +1,44 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class OracleDialect extends Dialect {
public OracleDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName, int offset, String limitName, int limit) {
sql = sql.trim();
boolean isForUpdate = false;
if (sql.toLowerCase().endsWith(" for update")) {
sql = sql.substring(0, sql.length() - 11);
isForUpdate = true;
}
StringBuilder pagingSelect = new StringBuilder(sql.length() + 100);
if (offset > 0) {
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
} else {
pagingSelect.append("select * from ( ");
}
pagingSelect.append(sql);
if (offset > 0) {
pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
setPageParameter("__offsetEnd", offset + limit, Integer.class);
setPageParameter(offsetName, offset, Integer.class);
} else {
pagingSelect.append(" ) where rownum <= ?");
setPageParameter(limitName, limit, Integer.class);
}
if (isForUpdate) {
pagingSelect.append(" for update");
}
return pagingSelect.toString();
}
}

@ -0,0 +1,30 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
/**
* @author badqiu
* @author miemiedev
*/
public class PostgreSQLDialect extends Dialect {
public PostgreSQLDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName,int offset, String limitName, int limit) {
StringBuilder buffer = new StringBuilder( sql.length()+20 ).append(sql);
if(offset > 0){
buffer.append(" limit ? offset ?");
setPageParameter(limitName, limit, Integer.class);
setPageParameter(offsetName, offset, Integer.class);
}else{
buffer.append(" limit ?");
setPageParameter(limitName, limit, Integer.class);
}
return buffer.toString();
}
}

@ -0,0 +1,73 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class SQLServer2005Dialect extends Dialect {
public SQLServer2005Dialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
/**
* Add a LIMIT clause to the given SQL SELECT
* The LIMIT SQL will look like:
* WITH query AS (SELECT TOP 100 percent ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __row_number__, * from table_name)
* SELECT * FROM query WHERE __row_number__ BETWEEN :offset and :lastRows ORDER BY __row_number__
*
* @param sql The SQL statement to base the limit query off of.
* @param offset Offset of the first row to be returned by the query (zero-based)
* @param limit Maximum number of rows to be returned by the query
* @return A new SQL statement with the LIMIT clause applied.
*/
protected String getLimitString(String sql, String offsetName,int offset, String limitName, int limit) {
StringBuilder pagingBuilder = new StringBuilder();
String orderby = getOrderByPart(sql);
String distinctStr = "";
String loweredString = sql.toLowerCase();
String sqlPartString = sql;
if (loweredString.trim().startsWith("select")) {
int index = 6;
if (loweredString.startsWith("select distinct")) {
distinctStr = "DISTINCT ";
index = 15;
}
sqlPartString = sqlPartString.substring(index);
}
pagingBuilder.append(sqlPartString);
// if no ORDER BY is specified use fake ORDER BY field to avoid errors
if (orderby.isEmpty()) {
orderby = "ORDER BY CURRENT_TIMESTAMP";
}
StringBuilder result = new StringBuilder();
result.append("WITH query AS (SELECT ")
.append(distinctStr)
.append("TOP 100 PERCENT ")
.append(" ROW_NUMBER() OVER (")
.append(orderby)
.append(") as __row_number__, ")
.append(pagingBuilder)
.append(") SELECT * FROM query WHERE __row_number__ > ? AND __row_number__ <= ?")
.append(" ORDER BY __row_number__");
setPageParameter(offsetName,offset,Integer.class);
setPageParameter("__offsetEnd",offset+limit,Integer.class);
return result.toString();
}
static String getOrderByPart(String sql) {
String loweredString = sql.toLowerCase();
int orderByIndex = loweredString.indexOf("order by");
if (orderByIndex != -1) {
// if we find a new "order by" then we need to ignore
// the previous one since it was probably used for a subquery
return sql.substring(orderByIndex);
} else {
return "";
}
}
}

@ -0,0 +1,28 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class SQLServerDialect extends Dialect {
public SQLServerDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
static int getAfterSelectInsertPoint(String sql) {
int selectIndex = sql.toLowerCase().indexOf( "select" );
final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
return selectIndex + ( selectDistinctIndex == selectIndex ? 15 : 6 );
}
protected String getLimitString(String sql, String offsetName,int offset, String limitName, int limit) {
if ( offset > 0 ) {
throw new UnsupportedOperationException( "sql server has no offset" );
}
setPageParameter(limitName, limit, Integer.class);
return new StringBuffer( sql.length() + 8 ).append( sql ).insert( getAfterSelectInsertPoint( sql ), " top " + limit ).toString();
}
}

@ -0,0 +1,18 @@
package com.xit.core.mybatis.paging.dialect;
import org.apache.ibatis.mapping.*;
import com.xit.core.mybatis.paging.domain.*;
public class SybaseDialect extends Dialect {
public SybaseDialect(MappedStatement mappedStatement, Object parameterObject, PageBounds pageBounds) {
super(mappedStatement, parameterObject, pageBounds);
}
protected String getLimitString(String sql, String offsetName,int offset, String limitName, int limit) {
throw new UnsupportedOperationException( "paged queries not supported" );
}
}

@ -0,0 +1,138 @@
package com.xit.core.mybatis.paging.domain;//import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.xit.*;
import lombok.Getter;
import lombok.Setter;
import org.springframework.web.servlet.ModelAndView;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@Getter @Setter
public class ModelAndViewResponse<T> { //implements IResponse, Serializable {
private final static String SUCCESS = "200";
private final static String NOT_FOUND = "400";
private final static String FAILED = "500";
private final static String SUCCESS_MESSAGE = "정상 처리 되었습니다.";
private final static String NOT_FOUND_MESSAGE = "NOT FOUND";
private final static String FAILED_MESSAGE = "서버에서 오류가 발생하였습니다.";
private ModelAndViewResponse() {
}
private ModelAndViewResponse(T data) {
ModelAndView mav = new ModelAndView(XitConstants.DEFAULT_VIEW);
mav.addObject("result", true);
mav.addObject("message", SUCCESS_MESSAGE);
mav.addObject("data", data);
if(data == null){
mav.addObject("count", 0);
}else {
// Pageing 처리
if (Collection.class.isAssignableFrom(data.getClass())) {
mav.addObject("count", (((Collection<?>) data).size()));
} else {
mav.addObject("count", 1);
}
}
}
/**
* <pre>
* return ModelAndView (Grid data)
* {
* result - true / false
* message
* data: {
* contents -
* pagination -
* }
* count - ( )
* }
* </pre>
* @param data
* @return
* @param <T>
*/
public static <T> ModelAndView of(T data){
ModelAndView mav = new ModelAndView(XitConstants.DEFAULT_VIEW);
mav.addObject("result", true);
mav.addObject("message", SUCCESS_MESSAGE);
Map<String, Object> map = new HashMap<>();
map.put("contents", data);
mav.addObject("data", map);
if(data == null){
mav.addObject("count", 0);
}else {
// Pageing 처리
if (Collection.class.isAssignableFrom(data.getClass())) {
mav.addObject("count", (((Collection<?>) data).size()));
} else {
mav.addObject("count", 1);
}
}
return mav;
}
public static <T> ModelAndView of(T data, String viewName){
ModelAndView mav = new ModelAndView(viewName);
mav.addObject("result", true);
mav.addObject("message", SUCCESS_MESSAGE);
Map<String, Object> map = new HashMap<>();
map.put("contents", data);
mav.addObject("data", map);
if(data == null){
mav.addObject("count", 0);
}else {
// Pageing 처리
if (Collection.class.isAssignableFrom(data.getClass())) {
mav.addObject("count", (((Collection<?>) data).size()));
} else {
mav.addObject("count", 1);
}
}
return mav;
}
public static <T> ModelAndView of(String attName, T data){
ModelAndView mav = new ModelAndView(XitConstants.DEFAULT_VIEW);
mav.addObject("result", true);
mav.addObject("message", SUCCESS_MESSAGE);
mav.addObject(attName, data);
if(data == null){
mav.addObject("count", 0);
}else {
// Pageing 처리
if (Collection.class.isAssignableFrom(data.getClass())) {
mav.addObject("count", (((Collection<?>) data).size()));
} else {
mav.addObject("count", 1);
}
}
return mav;
}
}

@ -0,0 +1,149 @@
package com.xit.core.mybatis.paging.domain;
import java.io.*;
import java.util.*;
import java.util.regex.*;
import org.apache.commons.lang3.*;
public class Order implements Serializable {
private static final long serialVersionUID = 1L;
private Direction direction;
private String property;
private String orderExpr;
public Order(String property, Direction direction, String orderExpr) {
this.direction = direction;
this.property = property;
this.orderExpr = orderExpr;
}
public Direction getDirection() {
return direction;
}
public String getProperty() {
return property;
}
public String getOrderExpr() {
return orderExpr;
}
public void setDirection(Direction direction) {
this.direction = direction;
}
public void setProperty(String property) {
this.property = property;
}
public void setOrderExpr(String orderExpr) {
this.orderExpr = orderExpr;
}
public static boolean isSQLInjection(String str) {
String INJECTION_REGEX = "[A-Za-z0-9\\_\\-\\+\\.]+";
return !Pattern.matches(INJECTION_REGEX, str);
}
@Override
public String toString() {
if (isSQLInjection(property)) {
throw new IllegalArgumentException("SQLInjection property: " + property);
}
if (orderExpr != null && orderExpr.contains("?")) {
String[] exprs = orderExpr.split("\\?");
if (exprs.length == 2) {
return String.format(orderExpr.replaceAll("\\?", "%s"), property) + (direction == null ? "" : " " + direction.name());
}
return String.format(orderExpr.replaceAll("\\?", "%s"), property, direction == null ? "" : " " + direction.name());
}
return property + (direction == null ? "" : " " + direction.name());
}
public static List<Order> formString(String orderSegment) {
return formString(orderSegment, null);
}
/**
* @param orderSegment String
* ex: "id.asc,code.desc" or "code.desc"
* @param orderExpr String
* @return List<Order> List
*/
public static List<Order> formString(String orderSegment, String orderExpr) {
if (Objects.isNull(orderSegment) || Objects.equals(StringUtils.EMPTY, orderSegment.trim())) {
return new ArrayList<Order>(0);
}
List<Order> results = new ArrayList<Order>();
String[] orderSegments = orderSegment.trim().split(",");
for (int i = 0; i < orderSegments.length; i++) {
String sortSegment = orderSegments[i];
Order order = _formString(sortSegment, orderExpr);
if (order != null) {
results.add(order);
}
}
return results;
}
private static Order _formString(String orderSegment, String orderExpr) {
if (Objects.isNull(orderSegment) || Objects.equals(StringUtils.EMPTY, orderSegment.trim())
|| orderSegment.startsWith("null.")
|| orderSegment.startsWith(".")) {
return null;
}
String[] array = orderSegment.trim().split("\\.");
if (array.length != 1 && array.length != 2) {
throw new IllegalArgumentException(
"orderSegment pattern must be {property}.{direction}, input is: " + orderSegment);
}
return create(array[0], array.length == 2 ? array[1] : "asc", orderExpr);
}
public static Order create(String property, String direction) {
return create(property, direction, null);
}
/**
*<pre>
* @param property property
* @param direction direction
* @param orderExpr
* Oracle query column (case-insensitive sort)
* placeholder is "?", in oracle like:
* "nlssort( ? ,'NLS_SORT=SCHINESE_PINYIN_M')". Warning: you must
* prevent orderExpr SQL injection.
* Oracle session level "nls_sort" "nlssort" .
* SQL: alter session set nls_sort=generic_m_ai;
* Session altered.
* @return Order Order
* </pre>
*/
public static Order create(String property, String direction, String orderExpr) {
return new Order(property, Direction.fromString(direction), orderExpr);
}
/**
* PropertyPath implements the pairing of an {@link Direction} and a
* property. It is used to provide input for
*
* @author Oliver Gierke
*/
public static enum Direction {
ASC, DESC;
public static Direction fromString(String value) {
try {
return Direction.valueOf(value.toUpperCase(Locale.US));
} catch (Exception e) {
return ASC;
}
}
}
}

@ -0,0 +1,157 @@
package com.xit.core.mybatis.paging.domain;
import java.io.*;
import java.util.*;
import org.apache.ibatis.session.*;
/**
*
* <pre>
* TODO define
* new PageBounds(limit)
* new PageBounds(page, limit)
* new PageBounds("field, field")
* new PageBounds(page, limit, "field, field.desc")
* new PageBounds(page, limit, "field.asc, filed.desc")
* @author minuk
* </pre>
*
*/
public class PageBounds extends RowBounds implements Serializable {
private static final long serialVersionUID = 1L;
public final static int NO_PAGE = 1;
protected int page = NO_PAGE;
protected int limit = NO_ROW_LIMIT;
protected List<Order> orders = new ArrayList<Order>();
protected boolean containsTotalCount;
protected Boolean asyncTotalCount;
public PageBounds() {
containsTotalCount = false;
}
public PageBounds(RowBounds rowBounds) {
if (rowBounds instanceof PageBounds) {
PageBounds pageBounds = (PageBounds) rowBounds;
this.page = pageBounds.page;
this.limit = pageBounds.limit;
this.orders = pageBounds.orders;
this.containsTotalCount = pageBounds.containsTotalCount;
this.asyncTotalCount = pageBounds.asyncTotalCount;
} else {
this.page = (rowBounds.getOffset() / rowBounds.getLimit()) + 1;
this.limit = rowBounds.getLimit();
}
}
/**
* Query TOP N, default containsTotalCount = false
* @param limit limit
*/
public PageBounds(int limit) {
this.limit = limit;
this.containsTotalCount = false;
}
public PageBounds(int page, int limit) {
this(page, limit, new ArrayList<Order>(), true);
}
public PageBounds(int page, int limit, boolean containsTotalCount) {
this(page, limit, new ArrayList<Order>(), containsTotalCount);
}
/**
* Just sorting, default containsTotalCount = false
* @param orders orders
*/
public PageBounds(List<Order> orders) {
this(NO_PAGE, NO_ROW_LIMIT, orders, false);
}
/**
* Just sorting, default containsTotalCount = false
* @param order order
*/
public PageBounds(Order... order) {
this(NO_PAGE, NO_ROW_LIMIT, order);
this.containsTotalCount = false;
}
public PageBounds(int page, int limit, Order... order) {
this(page, limit, Arrays.asList(order), true);
}
public PageBounds(int page, int limit, List<Order> orders) {
this(page, limit, orders, true);
}
public PageBounds(int page, int limit, List<Order> orders,
boolean containsTotalCount) {
this.page = page;
this.limit = limit;
this.orders = orders;
this.containsTotalCount = containsTotalCount;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public boolean isContainsTotalCount() {
return containsTotalCount;
}
public void setContainsTotalCount(boolean containsTotalCount) {
this.containsTotalCount = containsTotalCount;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public Boolean getAsyncTotalCount() {
return asyncTotalCount;
}
public void setAsyncTotalCount(Boolean asyncTotalCount) {
this.asyncTotalCount = asyncTotalCount;
}
@Override
public int getOffset() {
if (page >= 1) {
return (page - 1) * limit;
}
return 0;
}
@Override
public String toString() {
return "PageBounds{" + "page=" + page +
", limit=" + limit +
", orders=" + orders +
", containsTotalCount=" + containsTotalCount +
", asyncTotalCount=" + asyncTotalCount +
'}';
}
}

@ -0,0 +1,30 @@
package com.xit.core.mybatis.paging.domain;
import java.util.*;
public class PageList<E> extends ArrayList<E> {
private static final long serialVersionUID = 1412759446332294208L;
private Paginator paginator;
public PageList() {
}
public PageList(Collection<? extends E> c) {
super(c);
}
public PageList(Collection<? extends E> c, Paginator p) {
super(c);
this.paginator = p;
}
public PageList(Paginator p) {
this.paginator = p;
}
public Paginator getPaginator() {
return paginator;
}
}

@ -0,0 +1,142 @@
package com.xit.core.mybatis.paging.domain;
import java.io.*;
import org.springframework.web.context.request.*;
import com.xit.core.mybatis.*;
public class Paginator implements Serializable {
private static final long serialVersionUID = 1L;
private final int limit;
private int page = 1;
private final int totalCount;
public Paginator(int page, int limit, int totalCount) {
super();
this.limit = limit;
this.totalCount = totalCount;
this.page = computePageNo(page);
}
public void setSessionPagination(Paginator paginator){
RequestContextHolder.currentRequestAttributes().setAttribute(PagingConstants.Session.PAGE_INFO.getCode(), paginator, RequestAttributes.SCOPE_REQUEST);
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getLimit() {
return limit;
}
public int getTotalCount() {
return totalCount;
}
public boolean isFirstPage() {
return page <= 1;
}
public boolean isLastPage() {
return page >= getTotalPages();
}
public int getPrePage() {
if (isHasPrePage()) {
return page - 1;
} else {
return page;
}
}
public int getNextPage() {
if (isHasNextPage()) {
return page + 1;
} else {
return page;
}
}
public boolean isDisabledPage(int page) {
return ((page < 1) || (page > getTotalPages()) || (page == this.page));
}
public boolean isHasPrePage() {
return (page - 1 >= 1);
}
public boolean isHasNextPage() {
return (page + 1 <= getTotalPages());
}
public int getStartRow() {
if (getLimit() <= 0 || totalCount <= 0)
return 0;
return page > 0 ? (page - 1) * getLimit() + 1 : 0;
}
public int getEndRow() {
return page > 0 ? Math.min(limit * page, getTotalCount()) : 0;
}
public int getOffset() {
return page > 0 ? (page - 1) * getLimit() : 0;
}
public int getTotalPages() {
if (totalCount <= 0) {
return 0;
}
if (limit <= 0) {
return 0;
}
int count = totalCount / limit;
if (totalCount % limit > 0) {
count++;
}
return count;
}
protected int computePageNo(int page) {
return computePageNumber(page, limit, totalCount);
}
private static int computeLastPageNumber(int totalItems, int pageSize) {
if (pageSize <= 0)
return 1;
int result = (int) (totalItems % pageSize == 0 ? totalItems / pageSize
: totalItems / pageSize + 1);
if (result <= 1)
result = 1;
return result;
}
private static int computePageNumber(int page, int pageSize, int totalItems) {
if (page <= 1) {
return 1;
}
if (Integer.MAX_VALUE == page
|| page > computeLastPageNumber(totalItems, pageSize)) { // last
// page
return computeLastPageNumber(totalItems, pageSize);
}
return page;
}
@Override
public String toString() {
return "Paginator" +
"{page=" + page +
", limit=" + limit +
", totalCount=" + totalCount +
'}';
}
}

@ -0,0 +1,30 @@
package com.xit.core.mybatis.paging.jackson2;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.*;
import com.xit.core.mybatis.paging.domain.*;
/**
* <pre>
* Converter ObjectMapper
* ResponseBody
* Converter Paging return
* page, limit(row/page), totalCount, offset(row), startRow, prePage, nextPage, endRow, totalPages
* boolean : firstPage, lastPage, hasPrePage, hasNextPage
* </pre>
* @author minuk
*
*/
@SuppressWarnings("serial")
public class PageListJsonMapper extends ObjectMapper{
public PageListJsonMapper() {
//JSON data pretty 정렬
enable(SerializationFeature.INDENT_OUTPUT);
SimpleModule module = new SimpleModule("PageListJSONModule", new Version(1, 0, 0, null, null, null));
//module.addSerializer(PageList.class, new PageListJsonSerializer(this));
module.addSerializer(PageList.class, new PageListJsonSerializer());
registerModule(module);
}
}

@ -0,0 +1,51 @@
package com.xit.core.mybatis.paging.jackson2;
import java.io.*;
import java.util.*;
import org.slf4j.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.xit.core.mybatis.*;
import com.xit.core.mybatis.paging.domain.*;
import lombok.extern.slf4j.*;
//TODO PageListJsonSerializer - Converting시 data attribute name 정의 - property에서 읽어 온다
@SuppressWarnings("rawtypes")
@Slf4j
public class PageListJsonSerializer extends JsonSerializer<PageList>{
@SuppressWarnings("unchecked")
@Override
public void serialize(PageList value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
Paginator paginator = value.getPaginator();
Map<String, Object> map = new HashMap<>();
map.put("totalCount", paginator.getTotalCount());
map.put("totalPages", paginator.getTotalPages());
map.put("page", paginator.getPage());
map.put("limit", paginator.getLimit());
// Query Data
map.put(PagingConstants.RSLT_ATTR_NAME, new ArrayList(value));
// map.put(DEFAULT_RESPONSE_BODY_DATA_NAME, new ArrayList(value));
map.put("startRow", paginator.getStartRow());
map.put("endRow", paginator.getEndRow());
map.put("offset", paginator.getOffset());
// map.put("slider", paginator.getSlider());
map.put("prePage", paginator.getPrePage());
map.put("nextPage", paginator.getNextPage());
map.put("firstPage", paginator.isFirstPage());
map.put("hasNextPage", paginator.isHasNextPage());
map.put("hasPrePage", paginator.isHasPrePage());
map.put("lastPage", paginator.isLastPage());
// mapper.writeValue(jgen, map);
jgen.writeObject(map);
log.debug("#########################################Paging infomation##########################################################");
log.debug("{}", map);
log.debug("###################################################################################################");
}
}

@ -0,0 +1,74 @@
package com.xit.core.mybatis.paging.springmvc;
import java.util.*;
import javax.servlet.http.*;
import org.slf4j.*;
import org.springframework.web.context.request.*;
import org.springframework.web.servlet.*;
import org.springframework.web.servlet.handler.*;
import com.xit.core.mybatis.*;
import com.xit.core.mybatis.paging.domain.*;
/**
* <pre>
* name+Paginator
* ex) ModelAndView.addObject("data", Object) ==&gt; dataPaginator
* ResponseBody call Paging return
* TODO PageListAttrHandlerInterceptor - @ResponseBody call -
* TODO PageListAttrHandlerInterceptor - setting name - - property
* </pre>
*/
public class PageListAttrHandlerInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request,
HttpServletResponse httpServletResponse, Object o) throws Exception {
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse httpServletResponse, Object handler, ModelAndView mav) throws Exception {
Object pageObject = RequestContextHolder.getRequestAttributes().getAttribute(PagingConstants.Session.PAGE_INFO.getCode(), RequestAttributes.SCOPE_REQUEST);
if(pageObject != null){
Paginator paginator = (Paginator)pageObject;
if(mav == null) {
request.setAttribute(PagingConstants.Session.PAGE_INFO.getCode(), getPageInfoMap(paginator));
return;
}else{
mav.addObject(PagingConstants.Session.PAGE_INFO.getCode(), getPageInfoMap(paginator));
return;
}
}
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse httpServletResponse, Object o, Exception e)
throws Exception {
}
private Map<String,Object> getPageInfoMap(Paginator paginator){
Map<String, Object> map = new HashMap<String, Object>();
map.put("totalCount", paginator.getTotalCount());
map.put("totalPages", paginator.getTotalPages());
map.put("page", paginator.getPage());
map.put("limit", paginator.getLimit());
// Query Data : Paging 정보만 set 하면 되므로 필요 없다
//map.put(FwConstants.DEFAULT_RESPONSE_BODY_DATA_NAME, new ArrayList<PageList>(pageList));
map.put("startRow", paginator.getStartRow());
map.put("endRow", paginator.getEndRow());
map.put("offset", paginator.getOffset());
//map.put("slider", paginator.getSlider());
map.put("prePage", paginator.getPrePage());
map.put("nextPage", paginator.getNextPage());
map.put("firstPage", paginator.isFirstPage());
map.put("hasNextPage", paginator.isHasNextPage());
map.put("hasPrePage", paginator.isHasPrePage());
map.put("lastPage", paginator.isLastPage());
return map;
}
}

@ -0,0 +1,85 @@
/*
* Copyright 2009-2012 The MyBatis Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.xit.core.mybatis.paging.support;
import java.sql.*;
import java.util.*;
import org.apache.ibatis.executor.*;
import org.apache.ibatis.executor.parameter.*;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.reflection.*;
import org.apache.ibatis.session.*;
import org.apache.ibatis.type.*;
public class DefaultParameterHandler implements ParameterHandler {
private final TypeHandlerRegistry typeHandlerRegistry;
private final MappedStatement mappedStatement;
private final Object parameterObject;
private BoundSql boundSql;
private Configuration configuration;
public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
this.mappedStatement = mappedStatement;
this.configuration = mappedStatement.getConfiguration();
this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
this.parameterObject = parameterObject;
this.boundSql = boundSql;
}
public Object getParameterObject() {
return parameterObject;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void setParameters(PreparedStatement ps) throws SQLException {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
if (typeHandler == null) {
throw new ExecutorException(
"There was no TypeHandler found for parameter "
+ propertyName + " of statement "
+ mappedStatement.getId());
}
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null)
jdbcType = configuration.getJdbcTypeForNull();
typeHandler.setParameter(ps, i + 1, value, jdbcType);
}
}
}
}
}

@ -0,0 +1,408 @@
package com.xit.core.mybatis.paging.support;
import java.io.*;
import java.util.*;
import java.util.Map.*;
import org.apache.commons.lang3.*;
/**
* <pre>
* used :
* public class ConnectionUtils {
* static Properties properties = new Properties();
* // ... do load properties
*
* // delegate to properties
* static PropertiesHelper props = new PropertiesHelper(properties);
* public static Connection getConnection() {
* // use getRequiredProperty()
* DriverManager.getConnection(props.getRequiredString("jdbc.url"));
* }
* }
* new PropertiesHelper(properties,PropertiesHelper.SYSTEM_PROPERTIES_MODE_OVERRIDE)
* </pre>
*/
public class PropertiesHelper {
/** Never check system properties. */
public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0;
/**
* Check system properties if not resolvable in the specified properties.
* This is the default.
*/
public static final int SYSTEM_PROPERTIES_MODE_FALLBACK = 1;
/**
* Check system properties first, before trying the specified properties.
* This allows system properties to override any other property source.
*/
public static final int SYSTEM_PROPERTIES_MODE_OVERRIDE = 2;
private int systemPropertiesMode = SYSTEM_PROPERTIES_MODE_NEVER;
private Properties p;
public PropertiesHelper(Properties p) {
setProperties(p);
}
public PropertiesHelper(Properties p, int systemPropertiesMode) {
setProperties(p);
if(systemPropertiesMode != SYSTEM_PROPERTIES_MODE_NEVER && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_FALLBACK && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_OVERRIDE) {
throw new IllegalArgumentException("error systemPropertiesMode mode:"+systemPropertiesMode);
}
this.systemPropertiesMode = systemPropertiesMode;
}
public Properties getProperties() {
return p;
}
public void setProperties(Properties props) {
if(props == null) throw new IllegalArgumentException("properties must be not null");
this.p = props;
}
public String getRequiredString(String key) {
String value = getProperty(key);
if(isBlankString(value)) {
throw new IllegalStateException("required property is blank by key="+key);
}
return value;
}
public String getNullIfBlank(String key) {
String value = getProperty(key);
if(isBlankString(value)) {
return null;
}
return value;
}
public String getNullIfEmpty(String key) {
String value = getProperty(key);
if(StringUtils.isEmpty(value)) {
return null;
}
return value;
}
/**
* System.getProperty(key) System.getenv(key)
* @param key key
* @return String
*/
public String getAndTryFromSystem(String key) {
String value = getProperty(key);
if(isBlankString(value)) {
value = getSystemProperty(key);
}
return value;
}
private String getSystemProperty(String key) {
String value;
value = System.getProperty(key);
if(isBlankString(value)) {
value = System.getenv(key);
}
return value;
}
public Integer getInteger(String key) {
String v = getProperty(key);
if(v == null){
return null;
}
return Integer.parseInt(v);
}
public int getInt(String key,int defaultValue) {
if(getProperty(key) == null) {
return defaultValue;
}
return Integer.parseInt(getRequiredString(key));
}
public int getRequiredInt(String key) {
return Integer.parseInt(getRequiredString(key));
}
public Long getLong(String key) {
if(getProperty(key) == null) {
return null;
}
return Long.parseLong(getRequiredString(key));
}
public long getLong(String key,long defaultValue) {
if(getProperty(key) == null) {
return defaultValue;
}
return Long.parseLong(getRequiredString(key));
}
public Long getRequiredLong(String key) {
return Long.parseLong(getRequiredString(key));
}
public Boolean getBoolean(String key) {
if(getProperty(key) == null) {
return null;
}
return Boolean.parseBoolean(getRequiredString(key));
}
public boolean getBoolean(String key,boolean defaultValue) {
if(getProperty(key) == null) {
return defaultValue;
}
return Boolean.parseBoolean(getRequiredString(key));
}
public boolean getRequiredBoolean(String key) {
return Boolean.parseBoolean(getRequiredString(key));
}
public Float getFloat(String key) {
if(getProperty(key) == null) {
return null;
}
return Float.parseFloat(getRequiredString(key));
}
public float getFloat(String key,float defaultValue) {
if(getProperty(key) == null) {
return defaultValue;
}
return Float.parseFloat(getRequiredString(key));
}
public Float getRequiredFloat(String key) {
return Float.parseFloat(getRequiredString(key));
}
public Double getDouble(String key) {
if(getProperty(key) == null) {
return null;
}
return Double.parseDouble(getRequiredString(key));
}
public double getDouble(String key,double defaultValue) {
if(getProperty(key) == null) {
return defaultValue;
}
return Double.parseDouble(getRequiredString(key));
}
public Double getRequiredDouble(String key) {
return Double.parseDouble(getRequiredString(key));
}
//---------- setProperty(String key,int value) ... start ---------------//
public Object setProperty(String key,int value) {
return setProperty(key, String.valueOf(value));
}
public Object setProperty(String key,long value) {
return setProperty(key, String.valueOf(value));
}
public Object setProperty(String key,float value) {
return setProperty(key, String.valueOf(value));
}
public Object setProperty(String key,double value) {
return setProperty(key, String.valueOf(value));
}
public Object setProperty(String key,boolean value) {
return setProperty(key, String.valueOf(value));
}
public String[] getStringArray(String key) {
String v = getProperty(key);
if(v == null) {
return new String[0];
}else {
return tokenizeToStringArray(v, ", \t\n\r\f");
}
}
public int[] getIntArray(String key) {
return toIntArray(getStringArray(key));
}
public Properties getStartsWithProperties(String prefix) {
if(prefix == null) throw new IllegalArgumentException("'prefix' must be not null");
Properties props = getProperties();
Properties result = new Properties();
for(Entry<Object, Object> entry : props.entrySet()) {
String key = (String)entry.getKey();
if(key != null && key.startsWith(prefix)) {
result.put(key.substring(prefix.length()), entry.getValue());
}
}
return result;
}
//--------- delegate method start ---//
public String getProperty(String key, String defaultValue) {
String value = getProperty(key);
if(isBlankString(value)) {
return defaultValue;
}
return value;
}
public String getProperty(String key) {
String propVal = null;
if (systemPropertiesMode == SYSTEM_PROPERTIES_MODE_OVERRIDE) {
propVal = getSystemProperty(key);
}
if (propVal == null) {
propVal = p.getProperty(key);
}
if (propVal == null && systemPropertiesMode == SYSTEM_PROPERTIES_MODE_FALLBACK) {
propVal = getSystemProperty(key);
}
return propVal;
}
public Object setProperty(String key,String value) {
return p.setProperty(key, value);
}
public void clear() {
p.clear();
}
public Set<Entry<Object, Object>> entrySet() {
return p.entrySet();
}
public Enumeration<?> propertyNames() {
return p.propertyNames();
}
public boolean contains(Object value) {
return p.contains(value);
}
public boolean containsKey(Object key) {
return p.containsKey(key);
}
public boolean containsValue(Object value) {
return p.containsValue(value);
}
public Enumeration<Object> elements() {
return p.elements();
}
public Object get(Object key) {
return p.get(key);
}
public boolean isEmpty() {
return p.isEmpty();
}
public Enumeration<Object> keys() {
return p.keys();
}
public Set<Object> keySet() {
return p.keySet();
}
public void list(PrintStream out) {
p.list(out);
}
public void list(PrintWriter out) {
p.list(out);
}
public void load(InputStream inStream) throws IOException {
p.load(inStream);
}
public void loadFromXML(InputStream in) throws IOException,
InvalidPropertiesFormatException {
p.loadFromXML(in);
}
public Object put(Object key, Object value) {
return p.put(key, value);
}
public void putAll(Map<? extends Object, ? extends Object> t) {
p.putAll(t);
}
public Object remove(Object key) {
return p.remove(key);
}
/**@deprecated
* @param out out
* @param comments comments
*/
@Deprecated
public void save(OutputStream out, String comments) {
p.save(out, comments);
}
public int size() {
return p.size();
}
public void store(OutputStream out, String comments) throws IOException {
p.store(out, comments);
}
public void storeToXML(OutputStream os, String comment, String encoding)
throws IOException {
p.storeToXML(os, comment, encoding);
}
public void storeToXML(OutputStream os, String comment) throws IOException {
p.storeToXML(os, comment);
}
public Collection<Object> values() {
return p.values();
}
public String toString() {
return p.toString();
}
private static boolean isBlankString(String value) {
return Objects.isNull(value) || Objects.equals(StringUtils.EMPTY, value.trim());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private static String[] tokenizeToStringArray(String str, String sep) {
StringTokenizer st = new StringTokenizer(str, sep);
List result = new ArrayList();
while(st.hasMoreElements()) {
Object o = st.nextElement();
result.add(o);
}
return (String[])result.toArray(new String[result.size()]);
}
private static int[] toIntArray(String[] array) {
int[] result = new int[array.length];
for(int i = 0; i < array.length; i++) {
result[i] = Integer.parseInt(array[i]);
}
return result;
}
}

@ -0,0 +1,69 @@
/*
* Copyright (c) 2012-2013, Poplar Yfyang (poplar1123@gmail.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.xit.core.mybatis.paging.support;
import java.sql.*;
import org.apache.ibatis.mapping.*;
import org.slf4j.*;
import com.xit.core.mybatis.paging.dialect.*;
public class SQLHelp {
/**
* query record total count
*
* @param mappedStatement mapped
* @param parameterObject parameter
* @param boundSql boundSql
* @param dialect database dialect
* @return int
* @throws SQLException SQLException
*/
public static int getCount(final MappedStatement mappedStatement, final Object parameterObject, final BoundSql boundSql, Dialect dialect) throws SQLException {
final String count_sql = dialect.getCountSQL();
Connection connection = null;
PreparedStatement countStmt = null;
ResultSet rs = null;
try {
connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();
countStmt = connection.prepareStatement(count_sql);
DefaultParameterHandler handler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
handler.setParameters(countStmt);
rs = countStmt.executeQuery();
int count = 0;
if (rs.next()) count = rs.getInt(1);
// log.debug("Total count:{}, SQL:{}, parameters:{}", count, count_sql, parameterObject);
return count;
} finally {
try {
if (rs != null) rs.close();
} finally {
try {
if (countStmt != null) countStmt.close();
} finally {
if (connection != null && !connection.isClosed()) connection.close();
}
}
}
}
}

@ -0,0 +1,66 @@
package com.xit.core.mybatis.paging.util;
import java.lang.reflect.*;
import java.util.*;
import org.apache.commons.lang3.*;
import org.apache.ibatis.session.*;
import com.xit.core.mybatis.paging.domain.*;
import egovframework.com.cmm.*;
public class MybatisUtils {
public static <T> RowBounds getPagingInfo(Map<String,Object> map){
if(ObjectUtils.isEmpty(map)){
return new PageBounds(1, 10);
}
int page = ObjectUtils.isEmpty(map.get("page")) || Integer.parseInt(String.valueOf(map.get("page"))) < 0? 1: Integer.parseInt(String.valueOf(map.get("page")));
int limit = ObjectUtils.isEmpty(map.get("perPage")) || Integer.parseInt(String.valueOf(map.get("perPage"))) < 0? 20: Integer.parseInt(String.valueOf(map.get("perPage")));
// 정렬필드명.direction,정렬필드명.direction,... 형태(정렬필드,정렬필드.desc)
String sort = ObjectUtils.isEmpty(map.get("sidx"))? "": String.valueOf(map.get("sidx"));
return new PageBounds(page, limit , Order.formString(sort));
}
public static <T> RowBounds getPagingInfo(Object cls){
int page = 0;
int limit = 0;
if(ObjectUtils.isEmpty(cls)){
return new PageBounds(1, 10);
}
try {
Method pageMethod = cls.getClass().getMethod("getPage");
if(ObjectUtils.isNotEmpty(pageMethod)) page = (Integer)pageMethod.invoke(cls, null);
Method limitMethod = cls.getClass().getMethod("getPerPage");
if(ObjectUtils.isNotEmpty(limitMethod)) limit = (Integer)limitMethod.invoke(cls, null);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
page = page == 0? 1: page;
limit = limit == 0? 20: limit;
// 정렬필드명.direction,정렬필드명.direction,... 형태(정렬필드,정렬필드.desc)
//String sort = Checks.isEmpty(map.get("sidx"))? "": String.valueOf(map.get("sidx"));
//return new RowBounds(page == 1? 1: (page-1)*limit, limit);
return new PageBounds(page, limit);
}
// 전자정부 프레임워크 파라메터 적용 추가
public static <T> RowBounds getPagingInfo(ComDefaultVO comDefaultVO) {
return new PageBounds(comDefaultVO.getPageIndex(), comDefaultVO.getRecordCountPerPage());
}
public static RowBounds getPagingInfo(final int page, final int limit){
return new PageBounds(page, limit);
}
public static RowBounds getPagingInfo(int page, int row, String sort){
return new PageBounds(page, row, Order.formString(sort));
}
}

@ -0,0 +1,51 @@
package com.xit.core.mybatis.paging.util;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.*;
/**
*
* @: paging VO
* @: Grid PaginationInfo .
* @: 2020. 5. 26. 9:11:58
* @:
* @author ()
* @since 2002. 2. 2.
* @version 1.0 Copyright(c) XIT All rights reserved.
*/
public class XitPaginationInfo extends PaginationInfo{
/* *************************
* tui Grid Paging
************************* */
/** 현재 페이지 */
private int page = -1;
/** 모든 로우들의 개수(=조회 총 건수) */
private int totalCount = -1;
/* *************************
* //tui Grid Paging 필드
************************* */
/** [tui Grid] 현재 페이지를 반환 한다. */
public int getPage() {
return page;
}
/** [tui Grid] 현재 페이지를 설정 한다. */
public void setPage(int page) {
this.page = page;
super.setCurrentPageNo(page);
}
/** [tui Grid] 조회 총 건수를 설정 한다. */
public int getTotalCount() {
return totalCount;
}
/** [tui Grid] 조회 총 건수를 반환 한다. */
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
super.setTotalRecordCount(totalCount);
}
}

@ -0,0 +1,81 @@
package com.xit.core.mybatis.paging.util;
import javax.servlet.*;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.*;
import org.springframework.web.context.*;
/**
*
* @: Page Rendedrer
* @:
* @: 2020. 4. 28. 1:10:13
* @:
* @author ()
* @since 2002. 2. 2.
* @version 1.0 Copyright(c) XIT All rights reserved.
*/
public class XitPaginationRenderer extends AbstractPaginationRenderer implements ServletContextAware{
private ServletContext servletContext;
String type ;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public XitPaginationRenderer() {
// no-op
}
public void initVariables(){
firstPageLabel = "<a href=\"#none\" class=\"btn prevAll\" onclick=\"{0}({1}); return false;\"><span class=\"blind\">처음페이지</span></a>";
previousPageLabel = "<a href=\"#none\" class=\"btn prev\" onclick=\"{0}({1}); return false;\"><span class=\"blind\">이전페이지</span></a>";
currentPageLabel = "<strong class=\"on\">{0}</strong>";
otherPageLabel = "<a href=\"#none\" onclick=\"{0}({1}); return false;\">{2}</a>";
nextPageLabel = "<a href=\"#none\" class=\"btn next\" onclick=\"{0}({1}); return false;\"><span class=\"blind\">다음페이지</span></a>";
lastPageLabel = "<a href=\"#none\" class=\"btn nextAll\" onclick=\"{0}({1}); return false;\"><span class=\"blind\">마지막페이지</span></a>";
/* <a href=\"#none\" class=\"btn prevAll\" onclick=\"{0}({1}); return false;\"><span class=\"blind\"></span></a>
<a href=\"#none\" class=\"btn prev\" onclick=\"{0}({1}); return false;\"><span class=\"blind\"></span></a>
<strong class=\"on\">{0}</strong>
<a href=\"#none\" onclick=\"{0}({1}); return false;\">{2}</a>
<a href=\"#none\" class=\"btn next\" onclick=\"{0}({1}); return false;\"><span class=\"blind\"></span></a>
<a href=\"#none\" class=\"btn nextAll\" onclick=\"{0}({1}); return false;\"><span class=\"blind\"></span></a>
*/
/*//이미지 방식
firstPageLabel = "<a class=\"btn prevAll\" href=\"#\" onclick=\"{0}({1}); return false;\">" +
"<img src='" + strWebDir + "prevAll.png' border='0' alt='첫페이지'/></a>&#160;";
previousPageLabel = "<a class=\"btn prev\" href=\"#\" onclick=\"{0}({1}); return false;\">" +
"<img src='" + strWebDir + "prev.png' border='0' alt='이전페이지'/></a>&#160;";
currentPageLabel = "<strong class='on'>{0}</strong>&#160;";
otherPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">{2}</a>&#160;";
nextPageLabel = "<a class=\"btn next\" href=\"#\" onclick=\"{0}({1}); return false;\">" +
"<img src='" + strWebDir + "next.png' border='0' alt='다음페이지'/></a>&#160;";
lastPageLabel = "<a class=\"btn nextAll\" href=\"#\" onclick=\"{0}({1}); return false;\">" +
"<img src='" + strWebDir + "nextAll.png' border='0' alt='마지막페이지'/></a>&#160;";
*/
/*
firstPageLabel = "<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/resources/image/fims/framework/egovframework/com/cmm/icon/icon_prevend.gif\" alt=\"처음\" border=\"0\"/></a>&#160;";
previousPageLabel = "<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/resources/image/fims/framework/egovframework/com/cmm/icon/icon_prev.gif\" alt=\"이전\" border=\"0\"/></a>&#160;";
currentPageLabel = "<strong>{0}</strong>&#160;";
otherPageLabel = "<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \">{2}</a>&#160;";
nextPageLabel = "<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/resources/image/fims/framework/egovframework/com/cmm/icon/icon_next.gif\" alt=\"다음\" border=\"0\"/></a>&#160;";
lastPageLabel = "<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/resources/image/fims/framework/egovframework/com/cmm/icon/icon_nextend.gif\" alt=\"마지막\" border=\"0\"/></a>&#160;";
*/
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
initVariables();
}
}

@ -2,6 +2,7 @@ package egovframework.let.sec.drm.service;
import java.util.*;
import org.apache.ibatis.session.*;
/**
* .
@ -30,6 +31,8 @@ public interface EgovDeptAuthorService {
*/
public List<DeptAuthorVO> selectDeptAuthorList(DeptAuthorVO deptAuthorVO) throws Exception;
public List<DeptAuthorVO> selectDeptAuthorList(DeptAuthorVO deptAuthorVO, final RowBounds rowBounds) throws Exception;
/**
* /
* @param deptAuthor DeptAuthor

@ -2,6 +2,8 @@ package egovframework.let.sec.drm.service.impl;
import java.util.*;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.session.*;
import org.springframework.stereotype.*;
import egovframework.com.cmm.service.impl.*;
@ -36,7 +38,10 @@ public class DeptAuthorDAO extends EgovComAbstractDAO {
public List<DeptAuthorVO> selectDeptAuthorList(DeptAuthorVO deptAuthorVO) throws Exception {
return selectList("deptAuthorDAO.selectDeptAuthorList", deptAuthorVO);
}
public List<DeptAuthorVO> selectDeptAuthorList(DeptAuthorVO deptAuthorVO, final RowBounds rowBounds) throws Exception {
return selectList("deptAuthorDAO.selectDeptAuthorList2", deptAuthorVO.getDeptCode(), rowBounds);
}
/**
* /
* @param deptAuthor DeptAuthor

@ -4,6 +4,7 @@ import java.util.*;
import javax.annotation.*;
import org.apache.ibatis.session.*;
import org.egovframe.rte.fdl.cmmn.*;
import org.springframework.stereotype.*;
@ -42,6 +43,10 @@ public class EgovDeptAuthorServiceImpl extends EgovAbstractServiceImpl implement
return deptAuthorDAO.selectDeptAuthorList(deptAuthorVO);
}
public List<DeptAuthorVO> selectDeptAuthorList(DeptAuthorVO deptAuthorVO, final RowBounds rowBounds) throws Exception {
return deptAuthorDAO.selectDeptAuthorList(deptAuthorVO, rowBounds);
}
/**
* /
* @param deptAuthor DeptAuthor

@ -1,12 +1,21 @@
package egovframework.let.sec.drm.web;
import java.util.*;
import javax.annotation.*;
import org.apache.ibatis.session.*;
import org.egovframe.rte.fdl.property.*;
import org.egovframe.rte.ptl.mvc.tags.ui.pagination.*;
import org.springframework.stereotype.*;
import org.springframework.ui.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.*;
import com.xit.core.mybatis.*;
import com.xit.core.mybatis.paging.domain.*;
import com.xit.core.mybatis.paging.util.*;
import com.xit.core.util.*;
import egovframework.com.cmm.*;
import egovframework.com.cmm.annotation.*;
@ -69,20 +78,10 @@ public class EgovDeptAuthorController extends EgovComAbstractController {
* @exception Exception
*/
@IncludedInfo(name="부서권한관리", listUrl="/sec/drm/EgovDeptAuthorList.do", order = 100,gid = 20)
@RequestMapping(value="/sec/drm/EgovDeptAuthorList.do")
public String selectDeptAuthorList(@ModelAttribute("deptAuthorVO") DeptAuthorVO deptAuthorVO,
@RequestMapping(value="/sec/drm/EgovDeptAuthorList2.do")
public String selectDeptAuthorList2(@ModelAttribute("deptAuthorVO") DeptAuthorVO deptAuthorVO,
@ModelAttribute("authorManageVO") AuthorManageVO authorManageVO,
ModelMap model) throws Exception {
/** paging */
// PaginationInfo paginationInfo = new PaginationInfo();
// paginationInfo.setCurrentPageNo(deptAuthorVO.getPageIndex());
// paginationInfo.setRecordCountPerPage(deptAuthorVO.getPageUnit());
// paginationInfo.setPageSize(deptAuthorVO.getPageSize());
//
// deptAuthorVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
// deptAuthorVO.setLastIndex(paginationInfo.getLastRecordIndex());
// deptAuthorVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
PaginationInfo paginationInfo = builderPaginationInfo(deptAuthorVO);
deptAuthorVO.setDeptAuthorList(egovDeptAuthorService.selectDeptAuthorList(deptAuthorVO));
@ -99,6 +98,58 @@ public class EgovDeptAuthorController extends EgovComAbstractController {
return "egovframework/com/sec/drm/EgovDeptAuthorManage";
}
@IncludedInfo(name="부서권한관리", listUrl="/sec/drm/EgovDeptAuthorList.do", order = 100,gid = 20)
@RequestMapping(value="/sec/drm/EgovDeptAuthorList3.do")
public ModelAndView selectDeptAuthorList3(@ModelAttribute("deptAuthorVO") DeptAuthorVO deptAuthorVO,
@ModelAttribute("authorManageVO") AuthorManageVO authorManageVO) throws Exception {
ModelAndView mav = new ModelAndView("egovframework/com/sec/drm/EgovDeptAuthorManage");
PaginationInfo paginationInfo = builderPaginationInfo(deptAuthorVO);
deptAuthorVO.setDeptAuthorList(egovDeptAuthorService.selectDeptAuthorList(deptAuthorVO));
mav.addObject("deptAuthorList", deptAuthorVO.getDeptAuthorList());
int totCnt = egovDeptAuthorService.selectDeptAuthorListTotCnt(deptAuthorVO);
paginationInfo.setTotalRecordCount(totCnt);
mav.addObject("paginationInfo", paginationInfo);
authorManageVO.setAuthorManageList(egovAuthorManageService.selectAuthorAllList(authorManageVO));
mav.addObject("authorManageList", authorManageVO.getAuthorManageList());
mav.addObject("message", egovMessageSource.getMessage("success.common.select"));
return mav;
}
@IncludedInfo(name="부서권한관리", listUrl="/sec/drm/EgovDeptAuthorList.do", order = 100,gid = 20)
@RequestMapping(value="/sec/drm/EgovDeptAuthorList.do")
public ModelAndView selectDeptAuthorList(@ModelAttribute("deptAuthorVO") DeptAuthorVO deptAuthorVO,
@ModelAttribute("authorManageVO") AuthorManageVO authorManageVO) throws Exception {
RowBounds pagingInfo = MybatisUtils.getPagingInfo(deptAuthorVO);
deptAuthorVO.setDeptCode("ORGNZT_0000000000000");
//RowBounds pagingInfo2 = MybatisUtils.getPagingInfoFromVO(deptAuthorVO);
List<DeptAuthorVO> deptAuthorVOS = egovDeptAuthorService.selectDeptAuthorList(deptAuthorVO, pagingInfo);
ModelAndView mav = ModelAndViewResponse.of(deptAuthorVOS, "egovframework/com/sec/drm/EgovDeptAuthorManage");
PaginationInfo paginationInfo = builderPaginationInfo(deptAuthorVO);
deptAuthorVO.setDeptAuthorList(egovDeptAuthorService.selectDeptAuthorList(deptAuthorVO));
mav.addObject("deptAuthorList", deptAuthorVO.getDeptAuthorList());
int totCnt = egovDeptAuthorService.selectDeptAuthorListTotCnt(deptAuthorVO);
paginationInfo.setTotalRecordCount(totCnt);
mav.addObject("paginationInfo", paginationInfo);
authorManageVO.setAuthorManageList(egovAuthorManageService.selectAuthorAllList(authorManageVO));
mav.addObject("authorManageList", authorManageVO.getAuthorManageList());
mav.addObject("message", egovMessageSource.getMessage("success.common.select"));
return mav;
}
/**
*

@ -8,6 +8,8 @@
<setting name="mapUnderscoreToCamelCase" value="true"></setting>
<!-- 파라미터에 Null 값이 있을 경우 에러 처리 -->
<setting name="jdbcTypeForNull" value="VARCHAR"></setting>
<setting name="callSettersOnNulls" value="true"/> <!-- resultType으로 Map Collection 지정 시 value가 null일 떄 컬럼 누락문제 해결을 위한 설정 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- Type Aliases 설정-->
@ -19,5 +21,20 @@
<typeAlias alias="userSearchVO" type = "egovframework.let.uss.umt.service.UserDefaultVO"/>
<typeAlias alias="mberVO" type = "egovframework.let.uss.umt.service.MberManageVO"/>
</typeAliases>
<typeHandlers>
<!-- java.sql.Timestamp 를 java.util.Date 형으로 반환 -->
<typeHandler javaType="java.sql.Timestamp" handler="org.apache.ibatis.type.DateTypeHandler"/>
<typeHandler javaType="java.sql.Time" handler="org.apache.ibatis.type.DateTypeHandler"/>
<typeHandler javaType="java.sql.Date" handler="org.apache.ibatis.type.DateTypeHandler"/>
<typeHandler handler="com.xit.core.mybatis.ObjectTypeHandler" javaType="java.lang.Object"/>
</typeHandlers>
<!-- //FIXME:: DB type define -->
<plugins>
<plugin interceptor="com.xit.core.mybatis.paging.OffsetLimitInterceptor">
<property name="dialectClass" value="com.xit.core.mybatis.paging.dialect.MySQLDialect"/>
</plugin>
</plugins>
</configuration>

@ -42,6 +42,28 @@
LIMIT #{recordCountPerPage} OFFSET #{firstIndex}
</select>
<select id="selectDeptAuthorList2" parameterType="egovframework.let.sec.drm.service.DeptAuthorVO" resultType="egovframework.let.sec.drm.service.DeptAuthorVO">
SELECT A.DEPT_CODE,
A.DEPT_NM,
A.USER_ID,
A.USER_NM,
B.AUTHOR_CODE,
A.ESNTL_ID,
(CASE WHEN B.SCRTY_DTRMN_TRGET_ID IS NULL THEN 'N'
ELSE 'Y'
END) AS REG_YN
FROM (SELECT A.ORGNZT_ID DEPT_CODE,
A.ORGNZT_NM DEPT_NM,
B.EMPLYR_ID USER_ID,
B.USER_NM USER_NM,
B.ESNTL_ID
FROM COMTNORGNZTINFO A,
COMTNEMPLYRINFO B
WHERE A.ORGNZT_ID = B.ORGNZT_ID
AND A.ORGNZT_ID = #{deptCode, jdbcType=VARCHAR}) A LEFT OUTER JOIN COMTNEMPLYRSCRTYESTBS B
ON A.ESNTL_ID = B.SCRTY_DTRMN_TRGET_ID
</select>
<insert id="insertDeptAuthor" parameterType="egovframework.let.sec.drm.service.DeptAuthor">
INSERT INTO COMTNEMPLYRSCRTYESTBS

@ -42,6 +42,28 @@
LIMIT #{recordCountPerPage} OFFSET #{firstIndex}
</select>
<select id="selectDeptAuthorList2" resultType="egovframework.let.sec.drm.service.DeptAuthorVO">
SELECT A.DEPT_CODE,
A.DEPT_NM,
A.USER_ID,
A.USER_NM,
B.AUTHOR_CODE,
A.ESNTL_ID,
(CASE WHEN B.SCRTY_DTRMN_TRGET_ID IS NULL THEN 'N'
ELSE 'Y'
END) AS REG_YN
FROM (SELECT A.ORGNZT_ID DEPT_CODE,
A.ORGNZT_NM DEPT_NM,
B.EMPLYR_ID USER_ID,
B.USER_NM USER_NM,
B.ESNTL_ID
FROM COMTNORGNZTINFO A,
COMTNEMPLYRINFO B
WHERE A.ORGNZT_ID = B.ORGNZT_ID
AND A.ORGNZT_ID = #{deptCode, jdbcType=VARCHAR}) A LEFT OUTER JOIN COMTNEMPLYRSCRTYESTBS B
ON A.ESNTL_ID = B.SCRTY_DTRMN_TRGET_ID
</select>
<insert id="insertDeptAuthor" parameterType="egovframework.let.sec.drm.service.DeptAuthor">
INSERT INTO COMTNEMPLYRSCRTYESTBS

Loading…
Cancel
Save