diff --git a/src/main/java/cokr/xit/foundation/data/paging/MapperSupport.java b/src/main/java/cokr/xit/foundation/data/paging/MapperSupport.java new file mode 100644 index 0000000..ae53929 --- /dev/null +++ b/src/main/java/cokr/xit/foundation/data/paging/MapperSupport.java @@ -0,0 +1,110 @@ +package cokr.xit.foundation.data.paging; + +import java.sql.SQLException; +import java.sql.Statement; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.executor.resultset.ResultSetHandler; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Signature; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; + +import cokr.xit.foundation.AbstractEntity; + +@Intercepts({ + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}), + + @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), +}) +public class MapperSupport extends MybatisPlugin { + private static final ThreadLocal pagingInfo = new ThreadLocal<>(); + + @Override + protected Object query(Executor executor, MappedStatement mappedStatement, Object obj, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { + Pageable.Info paging = Pageable.Info.create(obj); + if (paging != null && paging.isPaging()) + pagingInfo.set(paging); + + return super.query(executor, mappedStatement, obj, rowBounds, resultHandler); + } + + @Override + protected Object handle(ResultSetHandler resultSetHandler, Statement statement) throws SQLException { + Object obj = super.handle(resultSetHandler, statement); + + Pageable.Info paging = pagingInfo.get(); + if (paging != null && (obj instanceof List)) { + pagingInfo.remove(); + + List list = (List)obj; + BoundedList boundedList = new BoundedList<>(); + boundedList.setFetchSize(paging.fetchSize); + boundedList.addAll(list); + if (!boundedList.isEmpty()) { + boundedList.setStart((paging.pageNum - 1) * paging.fetchSize); + } + obj = boundedList; + } + + return obj; + } + + @Override + protected Object update(Executor executor, MappedStatement mappedStatement, Object obj) throws SQLException { + setEntityTimestamp(mappedStatement.getSqlCommandType(), obj, null); + return super.update(executor, mappedStatement, obj); + } + + private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + + private void setEntityTimestamp(SqlCommandType sqlType, Object arg, String now) { + if (isEmpty(arg)) return; + + now = ifEmpty(now, () -> dateFormat.format(new Date())); + if (arg instanceof AbstractEntity) { + setTimestamp(sqlType, (AbstractEntity)arg, now); + } else if (arg instanceof Map) { + Map map = (Map)arg; + for (Object o: map.values()) + setEntityTimestamp(sqlType, o, now); + } else if (arg instanceof Iterable) { + Iterable iterable = (Iterable)arg; + for (Object o: iterable) + setEntityTimestamp(sqlType, o, now); + } else if (arg.getClass().isArray()) { + Object[] objs = (Object[])arg; + for (Object o: objs) + setEntityTimestamp(sqlType, o, now); + } + } + + private void setTimestamp(SqlCommandType sqlType, AbstractEntity entity, String now) { + String userID = currentUser().getId(); + switch (sqlType) { + case INSERT: + entity.setCreatedBy(userID); + entity.setCreatedAt(now); + entity.setModifiedBy(userID); + entity.setLastModified(now); + break; + case UPDATE: + entity.setModifiedBy(userID); + entity.setLastModified(now); + break; + case DELETE: + entity.setRemovedBy(userID); + entity.setRemovedAt(now); + entity.setUseYN("N"); + break; + default: break; + } + } +} \ No newline at end of file diff --git a/src/main/java/cokr/xit/foundation/data/paging/PagingAid.java b/src/main/java/cokr/xit/foundation/data/paging/PagingAid.java deleted file mode 100644 index d123964..0000000 --- a/src/main/java/cokr/xit/foundation/data/paging/PagingAid.java +++ /dev/null @@ -1,51 +0,0 @@ -package cokr.xit.foundation.data.paging; - -import java.sql.SQLException; -import java.sql.Statement; -import java.util.List; - -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.resultset.ResultSetHandler; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.plugin.Intercepts; -import org.apache.ibatis.plugin.Signature; -import org.apache.ibatis.session.ResultHandler; -import org.apache.ibatis.session.RowBounds; - -@Intercepts({ - @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), - @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) -}) -public class PagingAid extends MybatisPlugin { - private static final ThreadLocal pagingInfo = new ThreadLocal<>(); - - @Override - protected Object query(Executor executor, MappedStatement mappedStatement, Object obj, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException { - Pageable.Info paging = Pageable.Info.create(obj); - if (paging != null && paging.isPaging()) - pagingInfo.set(paging); - - return super.query(executor, mappedStatement, obj, rowBounds, resultHandler); - } - - @Override - protected Object handle(ResultSetHandler resultSetHandler, Statement statement) throws SQLException { - Object obj = super.handle(resultSetHandler, statement); - - Pageable.Info paging = pagingInfo.get(); - if (paging != null && (obj instanceof List)) { - pagingInfo.remove(); - - List list = (List)obj; - BoundedList boundedList = new BoundedList<>(); - boundedList.setFetchSize(paging.fetchSize); - boundedList.addAll(list); - if (!boundedList.isEmpty()) { - boundedList.setStart((paging.pageNum - 1) * paging.fetchSize); - } - obj = boundedList; - } - - return obj; - } -} \ No newline at end of file diff --git a/src/main/java/cokr/xit/foundation/data/paging/PagingSupport.java b/src/main/java/cokr/xit/foundation/data/paging/PagingSupport.java deleted file mode 100644 index 97c499f..0000000 --- a/src/main/java/cokr/xit/foundation/data/paging/PagingSupport.java +++ /dev/null @@ -1,166 +0,0 @@ -package cokr.xit.foundation.data.paging; - -import java.sql.Statement; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.executor.resultset.ResultSetHandler; -import org.apache.ibatis.mapping.MappedStatement; -import org.apache.ibatis.mapping.SqlCommandType; -import org.apache.ibatis.plugin.Interceptor; -import org.apache.ibatis.plugin.Intercepts; -import org.apache.ibatis.plugin.Invocation; -import org.apache.ibatis.plugin.Signature; -import org.apache.ibatis.session.ResultHandler; -import org.apache.ibatis.session.RowBounds; - -import cokr.xit.foundation.AbstractComponent; -import cokr.xit.foundation.AbstractEntity; -import cokr.xit.foundation.component.QueryRequest; - -/**조회 결과의 페이징 처리를 지원하는 MyBatis Interceptor - * @author mjkhan - */ -@Intercepts({ - @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), - @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), - @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class}) -}) -public class PagingSupport extends AbstractComponent implements Interceptor { - private boolean paging; - private int pageNum; - private int fetchSize; - - @Override - public Object intercept(Invocation invocation) throws Throwable { - Object[] args = invocation.getArgs(); - Object arg0 = args[0]; - if (arg0 instanceof MappedStatement) { - MappedStatement stmt = (MappedStatement)arg0; - SqlCommandType sqlType = stmt.getSqlCommandType(); - switch (sqlType) { - case SELECT: return setPaging(invocation); - case INSERT: - case UPDATE: - case DELETE: return setEntityProperties(invocation, sqlType); - default: return invocation.proceed(); - } - } else - switch (getStep(invocation)) { - case "ResultSetHandler.handleResultSets": return setPagingInfo(invocation); - default: return invocation.proceed(); - } - } - - private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); - - private Object setEntityProperties(Invocation invocation, SqlCommandType sqlType) throws Exception { - Object[] args = invocation.getArgs(); - Object arg = args[1]; - setEntityProperties(sqlType, arg, null); - - return invocation.proceed(); - } - - private void setEntityProperties(SqlCommandType sqlType, Object obj, String now) { - if (isEmpty(obj)) return; - - now = ifEmpty(now, () -> dateFormat.format(new Date())); - if (obj instanceof AbstractEntity) { - setProperties(sqlType, (AbstractEntity)obj, now); - } else if (obj instanceof Map) { - Map map = (Map)obj; - for (Object o: map.values()) - setEntityProperties(sqlType, o, now); - } else if (obj instanceof Iterable) { - Iterable iterable = (Iterable)obj; - for (Object o: iterable) - setEntityProperties(sqlType, o, now); - } else if (obj.getClass().isArray()) { - Object[] objs = (Object[])obj; - for (Object o: objs) - setEntityProperties(sqlType, o, now); - } - } - - private void setProperties(SqlCommandType sqlType, AbstractEntity entity, String now) { - String userID = currentUser().getId(); - switch (sqlType) { - case INSERT: - entity.setCreatedBy(userID); - entity.setCreatedAt(now); - entity.setModifiedBy(userID); - entity.setLastModified(now); - break; - case UPDATE: - entity.setModifiedBy(userID); - entity.setLastModified(now); - break; - case DELETE: - entity.setRemovedBy(userID); - entity.setRemovedAt(now); - entity.setUseYN("N"); - break; - default: break; - } - } - - private static final Class[] handlers = {Executor.class, ResultSetHandler.class}; - - private String getStep(Invocation invocation) { - Object obj = invocation.getTarget(); - String result = ""; - for (Class klass: handlers) { - if (klass.isInstance(obj)) { - result = klass.getSimpleName(); - break; - } - } - return result += "." + invocation.getMethod().getName(); - } - - private Object setPaging(Invocation invocation) throws Exception { - Object[] args = invocation.getArgs(); - Object arg = args[1]; - if (arg instanceof Map) { - @SuppressWarnings("unchecked") - Map params = (Map)arg; - fetchSize = Pageable.getFetchSize(params); - pageNum = Pageable.getPageNum(params); - } else if (arg instanceof QueryRequest) { - QueryRequest req = (QueryRequest)arg; - fetchSize = req.getFetchSize(); - pageNum = req.getPageNum(); - } else if (arg instanceof Pageable) { - Pageable pageable = (Pageable)arg; - fetchSize = pageable.getFetchSize(); - pageNum = pageable.getPageNum(); - } - paging = pageNum > 0 && fetchSize > 0; - - return invocation.proceed(); - } - - private Object setPagingInfo(Invocation invocation) throws Exception { - Object obj = invocation.proceed(); - - if (paging && (obj instanceof List)) { - List list = (List)obj; - BoundedList boundedList = new BoundedList<>(); - boundedList.setFetchSize(fetchSize); - boundedList.addAll(list); - if (!boundedList.isEmpty()) { - boundedList.setStart((pageNum - 1) * fetchSize); - } - obj = boundedList; - } - - paging = false; - pageNum = fetchSize = 0; - - return obj; - } -} \ No newline at end of file