Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

增加SQL解析缓存,以提升性能sql parse cache #777

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- test -->
<dependency>
<groupId>junit</groupId>
Expand Down
158 changes: 128 additions & 30 deletions src/main/java/com/github/pagehelper/dialect/AbstractHelperDialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@

package com.github.pagehelper.dialect;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.pagehelper.Constant;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageRowBounds;
import com.github.pagehelper.cache.Cache;
import com.github.pagehelper.cache.CacheFactory;
import com.github.pagehelper.util.ExecutorUtil;
import com.github.pagehelper.util.MetaObjectUtil;
import com.github.pagehelper.util.StringUtil;
Expand All @@ -48,6 +53,16 @@
* @since 2016-12-04 14:32
*/
public abstract class AbstractHelperDialect extends AbstractDialect implements Constant {
/**
* Logger for this class.
*/
private static final Logger logger = LoggerFactory.getLogger(AbstractHelperDialect.class);

protected Cache<String, String> CACHE_COUNTSQL;
protected Cache<String, String> CACHE_PAGESQL;

public static boolean cacheOnFlag = true;// 临时性开关,为了方便切换,以验证缓存前后对比.
public static boolean tracingOn = false;// 临时性开关

/**
* 获取分页参数
Expand All @@ -61,7 +76,7 @@ public <T> Page<T> getLocalPage() {

@Override
public final boolean skip(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {
//该方法不会被调用
// 该方法不会被调用
return true;
}

Expand All @@ -72,13 +87,48 @@ public boolean beforeCount(MappedStatement ms, Object parameterObject, RowBounds
}

@Override
public String getCountSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey countKey) {
public String getCountSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds,
CacheKey countKey) {
final long startTime = tracingOn || logger.isDebugEnabled() ? System.nanoTime() : 0;
if (startTime > 0) {
logger.info("getCountSql start ...");
}
Page<Object> page = getLocalPage();
String countColumn = page.getCountColumn();
final String sql = boundSql.getSql();
final String countSqlKey;
String cachedSql;
final boolean cacheOn = cacheOnFlag && CACHE_COUNTSQL != null;
if (StringUtil.isNotEmpty(countColumn)) {
return countSqlParser.getSmartCountSql(boundSql.getSql(), countColumn);
countSqlKey = sql + countColumn;
cachedSql = cacheOn ? CACHE_COUNTSQL.get(countSqlKey) : null;
if (cachedSql != null) {
logCountSqlEnd(startTime);
return cachedSql;
}
cachedSql = countSqlParser.getSmartCountSql(sql, countColumn);
} else {
countSqlKey = sql;
cachedSql = cacheOn ? CACHE_COUNTSQL.get(countSqlKey) : null;
if (cachedSql != null) {
logCountSqlEnd(startTime);
return cachedSql;
}
cachedSql = countSqlParser.getSmartCountSql(sql);
}
if (cacheOn) {
CACHE_COUNTSQL.put(countSqlKey, cachedSql);
}
logCountSqlEnd(startTime);
return cachedSql;
}

private void logCountSqlEnd(final long startTime) {
if (startTime > 0) {
final long time = System.nanoTime() - startTime;
logger.info("getCountSql(cacheOn={}) end: {}", cacheOnFlag,
Double.toString(time == 0 ? 0 : time / 1000000d));
}
return countSqlParser.getSmartCountSql(boundSql.getSql());
}

@Override
Expand All @@ -88,58 +138,61 @@ public boolean afterCount(long count, Object parameterObject, RowBounds rowBound
if (rowBounds instanceof PageRowBounds) {
((PageRowBounds) rowBounds).setTotal(count);
}
//pageSize < 0 的时候,不执行分页查询
//pageSize = 0 的时候,还需要执行后续查询,但是不会分页
// pageSize < 0 的时候,不执行分页查询
// pageSize = 0 的时候,还需要执行后续查询,但是不会分页
if (page.getPageSizeZero() != null) {
//PageSizeZero=false&&pageSize<=0
// PageSizeZero=false&&pageSize<=0
if (!page.getPageSizeZero() && page.getPageSize() <= 0) {
return false;
}
//PageSizeZero=true&&pageSize<0 返回 false,只有>=0才需要执行后续的
// PageSizeZero=true&&pageSize<0 返回 false,只有>=0才需要执行后续的
else if (page.getPageSizeZero() && page.getPageSize() < 0) {
return false;
}
}
//页码>0 && 开始行数<总行数即可,不需要考虑 pageSize(上面的 if 已经处理不符合要求的值了)
// 页码>0 && 开始行数<总行数即可,不需要考虑 pageSize(上面的 if 已经处理不符合要求的值了)
return page.getPageNum() > 0 && count > page.getStartRow();
}

@Override
public Object processParameterObject(MappedStatement ms, Object parameterObject, BoundSql boundSql, CacheKey pageKey) {
//处理参数
public Object processParameterObject(MappedStatement ms, Object parameterObject, BoundSql boundSql,
CacheKey pageKey) {
// 处理参数
Page page = getLocalPage();
//如果只是 order by 就不必处理参数
// 如果只是 order by 就不必处理参数
if (page.isOrderByOnly()) {
return parameterObject;
}
Map<String, Object> paramMap = null;
if (parameterObject == null) {
paramMap = new HashMap<String, Object>();
} else if (parameterObject instanceof Map) {
//解决不可变Map的情况
// 解决不可变Map的情况
paramMap = new HashMap<String, Object>();
paramMap.putAll((Map) parameterObject);
} else {
paramMap = new HashMap<String, Object>();
// sqlSource为ProviderSqlSource时,处理只有1个参数的情况
if (ms.getSqlSource() instanceof ProviderSqlSource) {
String[] providerMethodArgumentNames = ExecutorUtil.getProviderMethodArgumentNames((ProviderSqlSource) ms.getSqlSource());
String[] providerMethodArgumentNames = ExecutorUtil
.getProviderMethodArgumentNames((ProviderSqlSource) ms.getSqlSource());
if (providerMethodArgumentNames != null && providerMethodArgumentNames.length == 1) {
paramMap.put(providerMethodArgumentNames[0], parameterObject);
paramMap.put("param1", parameterObject);
}
}
//动态sql时的判断条件不会出现在ParameterMapping中,但是必须有,所以这里需要收集所有的getter属性
//TypeHandlerRegistry可以直接处理的会作为一个直接使用的对象进行处理
boolean hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass());
// 动态sql时的判断条件不会出现在ParameterMapping中,但是必须有,所以这里需要收集所有的getter属性
// TypeHandlerRegistry可以直接处理的会作为一个直接使用的对象进行处理
boolean hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry()
.hasTypeHandler(parameterObject.getClass());
MetaObject metaObject = MetaObjectUtil.forObject(parameterObject);
//需要针对注解形式的MyProviderSqlSource保存原值
// 需要针对注解形式的MyProviderSqlSource保存原值
if (!hasTypeHandler) {
for (String name : metaObject.getGetterNames()) {
paramMap.put(name, metaObject.getValue(name));
}
}
//下面这段方法,主要解决一个常见类型的参数时的问题
// 下面这段方法,主要解决一个常见类型的参数时的问题
if (boundSql.getParameterMappings() != null && boundSql.getParameterMappings().size() > 0) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
String name = parameterMapping.getProperty();
Expand Down Expand Up @@ -168,7 +221,8 @@ public Object processParameterObject(MappedStatement ms, Object parameterObject,
* @param pageKey
* @return
*/
public abstract Object processPageParameter(MappedStatement ms, Map<String, Object> paramMap, Page page, BoundSql boundSql, CacheKey pageKey);
public abstract Object processPageParameter(MappedStatement ms, Map<String, Object> paramMap, Page page,
BoundSql boundSql, CacheKey pageKey);

@Override
public boolean beforePage(MappedStatement ms, Object parameterObject, RowBounds rowBounds) {
Expand All @@ -180,19 +234,51 @@ public boolean beforePage(MappedStatement ms, Object parameterObject, RowBounds
}

@Override
public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds, CacheKey pageKey) {
public String getPageSql(MappedStatement ms, BoundSql boundSql, Object parameterObject, RowBounds rowBounds,
CacheKey pageKey) {
String sql = boundSql.getSql();
Page page = getLocalPage();
//支持 order by
// 支持 order by
String orderBy = page.getOrderBy();
String cacheSqlKey = getPageCacheSqlKey(page, sql);
final boolean cacheOn = cacheOnFlag && CACHE_PAGESQL != null;
final boolean orderByOnly = page.isOrderByOnly();
if (StringUtil.isNotEmpty(orderBy)) {
if (cacheOn) {
cacheSqlKey += orderBy;
if (orderByOnly) {
cacheSqlKey += "-orderByOnly";
}
}
pageKey.update(orderBy);
sql = orderBySqlParser.converToOrderBySql(sql, orderBy);

String cachedSql = cacheOn ? CACHE_PAGESQL.get(cacheSqlKey) : null;
if (cachedSql == null) {
cachedSql = orderBySqlParser.converToOrderBySql(sql, orderBy);
if (cacheOn && orderByOnly) {
CACHE_PAGESQL.put(cacheSqlKey, cachedSql);
}
}
sql = cachedSql;
}
if (page.isOrderByOnly()) {
if (orderByOnly) {
return sql;
}
return getPageSql(sql, page, pageKey);
String pageSql = cacheOn ? CACHE_PAGESQL.get(cacheSqlKey) : null;
if (pageSql == null) {
pageSql = getPageSql(sql, page, pageKey);
if (cacheOn) {
CACHE_PAGESQL.put(cacheSqlKey, pageSql);
}
}
return pageSql;
}

protected String getPageCacheSqlKey(final Page page, final String sql) {
if (page.getStartRow() == 0) {
return sql;
}
return sql + "-1";
}

/**
Expand All @@ -212,7 +298,7 @@ public Object afterPage(List pageList, Object parameterObject, RowBounds rowBoun
return pageList;
}
page.addAll(pageList);
//调整判断顺序,如果查全部,total就是size,如果只排序,也是全部,其他情况下如果不查询count就是-1
// 调整判断顺序,如果查全部,total就是size,如果只排序,也是全部,其他情况下如果不查询count就是-1
if ((page.getPageSizeZero() != null && page.getPageSizeZero()) && page.getPageSize() == 0) {
page.setTotal(pageList.size());
} else if (page.isOrderByOnly()) {
Expand All @@ -231,12 +317,21 @@ public void afterAll() {
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
final String sqlCacheClass = properties.getProperty("sqlCacheClass");
if (StringUtil.isNotEmpty(sqlCacheClass) && !sqlCacheClass.equalsIgnoreCase("false")) {
CACHE_COUNTSQL = CacheFactory.createCache(sqlCacheClass, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(sqlCacheClass, "page", properties);
} else if (!"false".equalsIgnoreCase(sqlCacheClass)) {
CACHE_COUNTSQL = CacheFactory.createCache(null, "count", properties);
CACHE_PAGESQL = CacheFactory.createCache(null, "page", properties);
}
}

/**
* @param boundSql
* @param ms
* @deprecated use {@code handleParameter(BoundSql boundSql, MappedStatement ms, Class<?> firstClass, Class<?> secondClass)}
* @deprecated use
* {@code handleParameter(BoundSql boundSql, MappedStatement ms, Class<?> firstClass, Class<?> secondClass)}
*/
@Deprecated
protected void handleParameter(BoundSql boundSql, MappedStatement ms) {
Expand All @@ -247,9 +342,12 @@ protected void handleParameter(BoundSql boundSql, MappedStatement ms) {

protected void handleParameter(BoundSql boundSql, MappedStatement ms, Class<?> firstClass, Class<?> secondClass) {
if (boundSql.getParameterMappings() != null) {
List<ParameterMapping> newParameterMappings = new ArrayList<ParameterMapping>(boundSql.getParameterMappings());
newParameterMappings.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_FIRST, firstClass).build());
newParameterMappings.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_SECOND, secondClass).build());
List<ParameterMapping> newParameterMappings = new ArrayList<ParameterMapping>(
boundSql.getParameterMappings());
newParameterMappings
.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_FIRST, firstClass).build());
newParameterMappings.add(
new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_SECOND, secondClass).build());
MetaObject metaObject = MetaObjectUtil.forObject(boundSql);
metaObject.setValue("parameterMappings", newParameterMappings);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ public Object processPageParameter(MappedStatement ms, Map<String, Object> param
public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sql + " OFFSET ? ROWS FETCH FIRST ? ROWS ONLY";
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,16 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
}
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
String cacheKey = sql;
if (page.getPageSize() > 0) {
cacheKey += "-p";
}
if (page.getStartRow() > 0) {
cacheKey += "-s";
}
return cacheKey;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,8 @@ public String getPageSql(String sql, Page page, CacheKey pageKey) {
return sqlBuilder.toString();
}

@Override
protected String getPageCacheSqlKey(final Page page, final String sql) {
return sql;
}
}
Loading
Loading