这里只适合Mysql数据库,Oracle数据库可自行修改语句
1. 创建分页实体类
public class Page {
// 总条数
private int totalNumber;
// 第几页
private int currentPage;
// 总页数
private int totalPage;
// 每页显示条数
private int pageNumber = 5;
// 数据库中limit的参数,从第几条开始取
private int dbIndex;
// 数据库中limit的参数,一共取多少条
private int dbNumber;
// 根据当前对象中属性值计算并设置相关属性值
public void count() {
// 计算总页数
int totalPageTemp = this.totalNumber / this.pageNumber + ((this.totalNumber % this.pageNumber) == 0 ? 0 : 1);
if (totalPageTemp <= 0) {
totalPageTemp = 1;
}
this.totalPage = totalPageTemp;
// 设置当前页数
// 总页数小于当前页数,应将当前页数设置为总页数
if (this.totalPage < this.currentPage) {
this.currentPage = this.totalPage;
}
// 当前页数小于1设置为1
if (this.currentPage < 1) {
this.currentPage = 1;
}
// 设置limit的参数
this.dbIndex = (this.currentPage - 1) * this.pageNumber;
this.dbNumber = this.pageNumber;
}
public int getTotalNumber() {
return totalNumber;
}
public void setTotalNumber(int totalNumber) {
this.totalNumber = totalNumber;
this.count();
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public int getDbIndex() {
return dbIndex;
}
public void setDbIndex(int dbIndex) {
this.dbIndex = dbIndex;
}
public int getDbNumber() {
return dbNumber;
}
public void setDbNumber(int dbNumber) {
this.dbNumber = dbNumber;
}
}
2. 创建分页拦截器类
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
public class PageInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(statementHandler,
SystemMetaObject.DEFAULT_OBJECT_FACTORY,
SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY);
MappedStatement mappedStatement =
(MappedStatement) metaObject.getValue("delegate.mappedStatement");
// 配置文件中SQL语句的ID
String id = mappedStatement.getId();
if (id.matches(".+ByPage$")) {
BoundSql boundSql = statementHandler.getBoundSql();
// 原始的SQL语句
String sql = boundSql.getSql();
// 查询总条数的SQL语句
String countSql = "select count(*) from (" + sql + ")";
Connection connection = (Connection) invocation.getArgs()[0];
PreparedStatement countStatement = connection.prepareStatement(countSql);
ParameterHandler parameterHandler =
(ParameterHandler) metaObject.getValue("delegate.parameterHandler");
parameterHandler.setParameters(countStatement);
ResultSet rs = countStatement.executeQuery();
// parameter对应 parameterType="java.util.Map" 的 map
Map<?, ?> parameter = (Map<?, ?>) boundSql.getParameterObject();
Page page = (Page) parameter.get("page");
if (rs.next()) {
page.setTotalNumber(rs.getInt(1));
}
// 改造后带分页查询的SQL语句
String pageSql = this.mysqlPageSql(page, sql);
metaObject.setValue("delegate.boundSql.sql", pageSql);
}
return invocation.proceed();
}
// Mysql 分页语句
public String mysqlPageSql(Page page, String sql) {
return sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
3. 将拦截器配置到配置文件中
<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:com/xxx/dao/mapper/*.xml"></property>
<!--PageInterceptor分页拦截器 -->
<property name="plugins">
<bean class="com.xxx.interceptor.PageInterceptor"></bean>
</property>
</bean>
4. 创建查询的dao层,这里假设是PageDao
使用分页查询id必须是ByPage结尾
<select id="selectByPage" parameterType="java.util.Map"
resultType="实体类">
select 表中字段 from 实体类对应的表
</select>
List<实体类> selectByPage(Map<String,Object> map);
5. 测试
...
@Autowired
private PageDao pageDao;
...
public List<实体类> selectByPage(String currentPage) {
Page page = new Page();
Pattern pattern = Pattern.compile("[0-9]{1,9}");
if(currentPage==null||!pattern.matcher(currentPage).matches()){
page.setCurrentPage(1);
} else {
page.setCurrentPage(Integer.valueOf(currentPage));
}
Map<String,Object> parameter = new HashMap<String, Object>();
//如果有其它查询条件可保存到parameter中可在步骤4中使用
parameter.put("page", page);
return pageDao.selectByPage(parameter);
}