com.linju.framework.pager.SqlUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.linju.framework.pager.SqlUtil.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 abel533@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.linju.framework.pager;

import com.linju.framework.pager.parser.Parser;
import com.linju.framework.pager.parser.impl.AbstractParser;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.RowBounds;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * Mybatis - sql?countMappedStatement?
 *
 * @author liuzh/abel533/isea533
 * @since 3.6.0
 * ? : http://git.oschina.net/free/Mybatis_PageHelper
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SqlUtil implements Constant {
    private static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();
    //RowBounds?offsetPageNum - ?
    private boolean offsetAsPageNum = false;
    //RowBounds?count - ?
    private boolean rowBoundsWithCount = false;
    //truepagesize0RowBoundslimit=0?
    private boolean pageSizeZero = false;
    //??
    private boolean reasonable = false;
    //params?
    private static Map<String, String> PARAMS = new HashMap<String, String>(5);
    //request?
    private static Boolean hasRequest;
    private static Class<?> requestClass;
    private static Method getParameterMap;

    static {
        try {
            requestClass = Class.forName("javax.servlet.ServletRequest");
            getParameterMap = requestClass.getMethod("getParameterMap", new Class[] {});
            hasRequest = true;
        } catch (Exception e) {
            hasRequest = false;
        }
    }

    //?parser
    private Parser parser;
    //?MS
    private MSUtils msUtils;
    //?
    private Dialect dialect;

    /**
     * 
     *
     * @param strDialect
     */
    public SqlUtil(String strDialect) {
        if (strDialect == null || "".equals(strDialect)) {
            throw new IllegalArgumentException("Mybatis??dialect?!");
        }
        dialect = Dialect.of(strDialect);
        parser = AbstractParser.newParser(dialect);
        msUtils = new MSUtils(parser);

    }

    public static void setLocalPage(Page page) {
        LOCAL_PAGE.set(page);
    }

    /**
     * ?Page?
     *
     * @return
     */
    public static Page getLocalPage() {
        return LOCAL_PAGE.get();
    }

    /**
     * ??
     */
    public static void clearLocalPage() {
        LOCAL_PAGE.remove();
    }

    /**
     * ??
     *
     * @param params RowBounds?
     * @return Page
     */
    public Page getPage(Object params) {
        Page page = getLocalPage();
        if (page == null) {
            if (params instanceof RowBounds) {
                RowBounds rowBounds = (RowBounds) params;
                if (offsetAsPageNum) {
                    page = new Page(rowBounds.getOffset(), rowBounds.getLimit(), rowBoundsWithCount);
                } else {
                    page = new Page(rowBounds, rowBoundsWithCount);
                    //offsetAsPageNum=falsePageNum?reasonablefalse
                    page.setReasonable(false);
                }
            } else {
                page = getPageFromObject(params);
            }
            setLocalPage(page);
        }
        //??
        if (page.getReasonable() == null) {
            page.setReasonable(reasonable);
        }
        //truepagesize0RowBoundslimit=0?
        if (page.getPageSizeZero() == null) {
            page.setPageSizeZero(pageSizeZero);
        }
        return page;
    }

    /**
     * ??
     *
     * @param params
     * @return
     */
    public static Page getPageFromObject(Object params) {
        int pageNum;
        int pageSize;
        MetaObject paramsObject = null;
        if (params == null) {
            throw new NullPointerException("?params?!");
        }
        if (hasRequest && requestClass.isAssignableFrom(params.getClass())) {
            try {
                paramsObject = SystemMetaObject.forObject(getParameterMap.invoke(params, new Object[] {}));
            } catch (Exception e) {
                //
            }
        } else {
            paramsObject = SystemMetaObject.forObject(params);
        }
        if (paramsObject == null) {
            throw new NullPointerException("?params?!");
        }
        try {
            pageNum = Integer.parseInt(String.valueOf(getParamValue(paramsObject, "pageNum", true)));
            pageSize = Integer.parseInt(String.valueOf(getParamValue(paramsObject, "pageSize", true)));
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("???!");
        }
        Object _count = getParamValue(paramsObject, "count", false);
        boolean count = true;
        if (_count != null) {
            count = Boolean.valueOf(String.valueOf(_count));
        }
        Page page = new Page(pageNum, pageSize, count);
        Object reasonable = getParamValue(paramsObject, "reasonable", false);
        if (reasonable != null) {
            page.setReasonable(Boolean.valueOf(String.valueOf(reasonable)));
        }
        Object pageSizeZero = getParamValue(paramsObject, "pageSizeZero", false);
        if (pageSizeZero != null) {
            page.setPageSizeZero(Boolean.valueOf(String.valueOf(pageSizeZero)));
        }
        return page;
    }

    /**
     * ??
     *
     * @param paramsObject
     * @param paramName
     * @param required
     * @return
     */
    public static Object getParamValue(MetaObject paramsObject, String paramName, boolean required) {
        Object value = null;
        if (paramsObject.hasGetter(PARAMS.get(paramName))) {
            value = paramsObject.getValue(PARAMS.get(paramName));
        }
        if (required && value == null) {
            throw new RuntimeException("??:" + PARAMS.get(paramName));
        }
        return value;
    }

    /**
     * Mybatis
     *
     * @param invocation ?
     * @return 
     * @throws Throwable 
     */
    public Object processPage(Invocation invocation) throws Throwable {
        try {
            Object result = _processPage(invocation);
            return result;
        } finally {
            clearLocalPage();
        }
    }

    /**
     * Mybatis
     *
     * @param invocation ?
     * @return 
     * @throws Throwable 
     */
    private Object _processPage(Invocation invocation) throws Throwable {
        final Object[] args = invocation.getArgs();
        RowBounds rowBounds = (RowBounds) args[2];
        if (SqlUtil.getLocalPage() == null && rowBounds == RowBounds.DEFAULT) {
            return invocation.proceed();
        } else {
            //RowBounds-?Mybatis
            args[2] = RowBounds.DEFAULT;
            //?
            Page page = getPage(rowBounds);
            //pageSizeZero
            if ((page.getPageSizeZero() != null && page.getPageSizeZero()) && page.getPageSize() == 0) {
                //?
                Object result = invocation.proceed();
                //?
                page.addAll((List) result);
                //
                page.setPageNum(1);
                //?pageSize=total
                page.setPageSize(page.size());
                //??total
                page.setTotal(page.size());
                //?Page - ???
                return page;
            }
            //?ms
            MappedStatement ms = (MappedStatement) args[0];
            SqlSource sqlSource = ms.getSqlSource();
            //?total??count
            if (page.isCount()) {
                //?MappedStatement?qs
                msUtils.processCountMappedStatement(ms, sqlSource, args);
                //
                Object result = invocation.proceed();
                //
                page.setTotal((Integer) ((List) result).get(0));
                if (page.getTotal() == 0) {
                    return page;
                }
            }
            //pageSize>0pageSize<=0???count
            if (page.getPageSize() > 0 && ((rowBounds == RowBounds.DEFAULT && page.getPageNum() > 0)
                    || rowBounds != RowBounds.DEFAULT)) {
                //?MappedStatement?qs
                msUtils.processPageMappedStatement(ms, sqlSource, page, args);
                //
                Object result = invocation.proceed();
                //?
                page.addAll((List) result);
            }
            //
            return page;
        }
    }

    public void setProperties(Properties p) {
        //offsetPageNum
        String offsetAsPageNum = p.getProperty("offsetAsPageNum");
        this.offsetAsPageNum = Boolean.parseBoolean(offsetAsPageNum);
        //RowBounds???count
        String rowBoundsWithCount = p.getProperty("rowBoundsWithCount");
        this.rowBoundsWithCount = Boolean.parseBoolean(rowBoundsWithCount);
        //truepagesize0RowBoundslimit=0?
        String pageSizeZero = p.getProperty("pageSizeZero");
        this.pageSizeZero = Boolean.parseBoolean(pageSizeZero);
        //??true?????false??
        String reasonable = p.getProperty("reasonable");
        this.reasonable = Boolean.parseBoolean(reasonable);
        //offsetAsPageNum=false?
        //?
        PARAMS.put("pageNum", "pageNum");
        PARAMS.put("pageSize", "pageSize");
        PARAMS.put("count", "countSql");
        PARAMS.put("reasonable", "reasonable");
        PARAMS.put("pageSizeZero", "pageSizeZero");
        String params = p.getProperty("params");
        if (params != null && params.length() > 0) {
            String[] ps = params.split("[;|,|&]");
            for (String s : ps) {
                String[] ss = s.split("[=|:]");
                if (ss.length == 2) {
                    PARAMS.put(ss[0], ss[1]);
                }
            }
        }
    }

    /**
     * [?]countsql
     *
     * @param dialect     ?
     * @param originalSql sql
     */
    public static void testSql(String dialect, String originalSql) {
        testSql(Dialect.of(dialect), originalSql);
    }

    /**
     * [?]countsql
     *
     * @param dialect     ?
     * @param originalSql sql
     */
    public static void testSql(Dialect dialect, String originalSql) {
        Parser parser = AbstractParser.newParser(dialect);
        if (dialect == Dialect.sqlserver) {
            setLocalPage(new Page(1, 10));
        }
        String countSql = parser.getCountSql(originalSql);
        System.out.println(countSql);
        String pageSql = parser.getPageSql(originalSql);
        System.out.println(pageSql);
        if (dialect == Dialect.sqlserver) {
            clearLocalPage();
        }
    }
}