在使用pageHelper的过程中,总会遇到一些不支持的数据库方言,此时可能就需要自己去写一个方言,然后注册到pageHelper中就可以了。以人大金仓为例:
package cn.com.infosec.netseal.webserver.config.datasource;
import com.github.pagehelper.Page;
import com.github.pagehelper.dialect.AbstractHelperDialect;
import com.github.pagehelper.page.PageAutoDialect;
import com.github.pagehelper.util.MetaObjectUtil;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class KingBaseDialect extends AbstractHelperDialect {
public KingBaseDialect(){
PageAutoDialect.registerDialectAlias("kingbase",KingBaseDialect.class);
}
@Override
public Object processPageParameter(MappedStatement ms, Map<String, Object> paramMap, Page page, BoundSql boundSql, CacheKey pageKey) {
/**
* 起始行 和每页条数
*/
paramMap.put("First_PageHelper",page.getStartRow());
paramMap.put("Second_PageHelper",page.getPageSize());
pageKey.update(page.getStartRow());
pageKey.update(page.getPageSize());
if(boundSql.getParameterMappings()!=null){
List<ParameterMapping> list = new ArrayList<>();
if(boundSql != null && boundSql.getParameterMappings() != null){
list.addAll(boundSql.getParameterMappings());
}
if(page.getStartRow() == 0){
list.add((new ParameterMapping.Builder(ms.getConfiguration(),"Second_PageHelper",int.class)).build());
}else {
list.add((new ParameterMapping.Builder(ms.getConfiguration(),"First_PageHelper",long.class)).build());
list.add((new ParameterMapping.Builder(ms.getConfiguration(),"Second_PageHelper",int.class)).build());
}
MetaObject metaObject = MetaObjectUtil.forObject(boundSql);
metaObject.setValue("parameterMappings",list);
}
return paramMap;
}
@Override
public String getPageSql(String sql, Page page, CacheKey pageKey) {
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 14);
sqlBuilder.append(sql);
if (page.getStartRow() == 0) {
sqlBuilder.append("\n LIMIT ? ");
} else {
sqlBuilder.append("\n LIMIT ?, ? ");
}
return sqlBuilder.toString();
}
}
精简方法:在pageHelper自定义分页类里注册指定
package cn.com.infosec.netseal.webserver.config.datasource;
import cn.com.infosec.netseal.common.config.ConfigUtil;
import cn.com.infosec.netseal.common.define.ErrCode;
import cn.com.infosec.netseal.common.exceptions.ToLogException;
import com.github.pagehelper.PageInterceptor;
import com.github.pagehelper.dialect.helper.MySqlDialect;
import com.github.pagehelper.page.PageAutoDialect;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Properties;
/**
* @Description 自定义分页插件自动装配策略,使用自定义配置文件
*/
@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class PageHelperAutoConfiguration {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
@PostConstruct
public void addPageInterceptor() {
//pageHelper的sql分页拦截器
PageInterceptor interceptor = new PageInterceptor();
PageAutoDialect.registerDialectAlias("kingbase", MySqlDialect.class);
//读取自定义的配置文件
try {
Properties sqlDialect = ConfigUtil.getInstance().getSqlDialect();
// System.out.println(sqlDialect);
interceptor.setProperties(sqlDialect);
} catch (Exception e) {
throw new ToLogException(ErrCode.READ_CONF_ERROR, e);
}
//将分页拦截器添加到mybatis的sqlsession
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
}
}
}
因为人大金仓数据库分页语句和mysql比较类似,所以使用mysql的驱动也能实现,就不能再自定义驱动类了
pageHelper在找指定驱动时其实是根据驱动连接后的名字找的,即:jdbc:kingbase://IP:PORT/DATABASE,如果不自定义指定别名的话,会取jdbc后的kingbase,根据别名去找对应的驱动
如果在这没有找到,又没有自定义注册驱动,那就会报错了,所以上面我们自定义了人大金仓驱动类,同时将别名注册进去,如果使用了自定义方言插件的话,其实可以不自定义驱动类,比如我们在配置文件中配置人大金仓的方言为mysql
#pageHelper 方言
pagehelper.helperDialect=mysql
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
这样就可实现自定义方言了,自定义驱动类一般建议是特别不常用的数据库,且跟已有的数据库驱动都不类似的情况下才去创建,一般有可替代的驱动类就是有自定义方言了