1.guns使用的是bootstrap和mybatis-plus实现分页的分为两种“client”和“server”分页这里只讲述server端分页
1.MybatisPlusConfig
package com.stylefeng.guns.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.stylefeng.guns.config.datasource.DynamicDataSource;
import com.stylefeng.guns.core.common.constant.DatasourceEnum;
import com.stylefeng.guns.core.datascope.DataScopeInterceptor;
import com.stylefeng.guns.core.datasource.DruidProperties;
import com.stylefeng.guns.core.mutidatasource.config.MutiDataSourceProperties;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
/**
* MybatisPlus配置
*
* @author stylefeng
* @Date 2017/5/20 21:58
*/
@Configuration
@EnableTransactionManagement(order = 2)//由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao"})
//@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao"})
public class MybatisPlusConfig {
/**********************************************新增动态数据源配置*************************************************/
@Bean(name = "ds1")
@ConfigurationProperties(prefix = "spring.datasource.default")
public DataSource dataSource1() {
return new DruidDataSource();
/* return DataSourceBuilder.create().build();*/
}
@Bean(name = "dataSource")
@Primary
public DataSource dynamicDataSource(
@Qualifier(value ="ds1")DataSource ds1){
DynamicDataSource dynamicDataSource = new DynamicDataSource(ds1);
return dynamicDataSource;
}
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(ResourceLoader resourceLoader) throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dynamicDataSource(dataSource1()));
//实体类扫码路径
sqlSessionFactory.setTypeAliasesPackage("com.stylefeng.guns.modular.system.model");
//mybatis-config xml路径
//sqlSessionFactory.setConfigLocation(resourceLoader.getResource());
//mapper xml路径
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "com/stylefeng/guns/modular/**/mapping/*.xml";
sqlSessionFactory.setMapperLocations(pathMatchingResourcePatternResolver.getResources(packageSearchPath));
MybatisConfiguration configuration = new MybatisConfiguration();
//configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
configuration.setJdbcTypeForNull(JdbcType.NULL);
sqlSessionFactory.setConfiguration(configuration);
sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
paginationInterceptor()
});
sqlSessionFactory.setGlobalConfig(globalConfiguration());
return sqlSessionFactory.getObject();
}
@Bean
public GlobalConfiguration globalConfiguration() {
GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
conf.setLogicDeleteValue("-1");
conf.setLogicNotDeleteValue("1");
conf.setIdType(2);
//conf.setMetaObjectHandler(new H2MetaObjectHandler());
return conf;
}
/**************************************************************************************************************/
@Autowired
DruidProperties druidProperties;
@Autowired
MutiDataSourceProperties mutiDataSourceProperties;
/**
* 另一个数据源
*/
private DruidDataSource bizDataSource() {
DruidDataSource dataSource = new DruidDataSource();
druidProperties.config(dataSource);
mutiDataSourceProperties.config(dataSource);
return dataSource;
}
/**
* guns的数据源
*/
private DruidDataSource dataSourceGuns() {
DruidDataSource dataSource = new DruidDataSource();
druidProperties.config(dataSource);
return dataSource;
}
/**
* 单数据源连接池配置
*/
@Bean
@ConditionalOnProperty(prefix = "guns", name = "muti-datasource-open", havingValue = "true")
public DruidDataSource singleDatasource() {
return dataSourceGuns();
}
/**
* 多数据源连接池配置
*/
@Bean
@ConditionalOnProperty(prefix = "guns", name = "muti-datasource-open", havingValue = "true")
public DynamicDataSource mutiDataSource() {
DruidDataSource dataSourceGuns = dataSourceGuns();
DruidDataSource bizDataSource = bizDataSource();
try {
dataSourceGuns.init();
bizDataSource.init();
} catch (SQLException sql) {
sql.printStackTrace();
}
DynamicDataSource dynamicDataSource = new DynamicDataSource();
HashMap<Object, Object> hashMap = new HashMap();
hashMap.put(DatasourceEnum.DATA_SOURCE_GUNS, dataSourceGuns);
hashMap.put(DatasourceEnum.DATA_SOURCE_BIZ, bizDataSource);
dynamicDataSource.setTargetDataSources(hashMap);
dynamicDataSource.setDefaultTargetDataSource(dataSourceGuns);
return dynamicDataSource;
}
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
/**
* 数据范围mybatis插件
*/
@Bean
public DataScopeInterceptor dataScopeInterceptor() {
return new DataScopeInterceptor();
}
/**
* 乐观锁mybatis插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
}
2.bootstrap-table-object.js
BSTable.prototype = {
/**
* 初始化bootstrap table
*/
init: function () {
var tableId = this.bstableId;
var me = this;
this.btInstance =
$('#' + tableId).bootstrapTable({
contentType: "application/x-www-form-urlencoded",
url: this.url, //请求地址
method: this.method, //ajax方式,post还是get
ajaxOptions: { //ajax请求的附带参数
data: this.data
},
toolbar: "#" + this.toolbarId,//顶部工具条
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true
pagination: true, //是否显示分页(*)
sortable: true, //是否启用排序
sortOrder: "desc", //排序方式
pageNumber: 1, //初始化加载第一页,默认第一页
pageSize: 10, //每页的记录行数(*)
pageList: [10, 50, 100], //可供选择的每页的行数(*)
queryParamsType: '', //默认值为 'limit' ,在默认情况下 传给服务端的参数为:offset,limit,sort *************这里一定要改为''默认值是limit因为改为''后在这种情况下传给服务器的参数为:pageSize,pageNumber**************
queryParams: function (param) {
return $.extend(me.queryParams, param);
}, // 向后台传递的自定义参数
sidePagination: this.paginationType, //分页方式:client客户端分页,server服务端分页(*)
search: false, //是否显示表格搜索,此搜索是客户端搜索,不会进服务端
strictSearch: true, //设置为 true启用 全匹配搜索,否则为模糊搜索
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
minimumCountColumns: 2, //最少允许的列数
clickToSelect: true, //是否启用点击选中行
searchOnEnterKey: true, //设置为 true时,按回车触发搜索方法,否则自动触发搜索方法
columns: this.columns, //列数组
pagination: true, //是否显示分页条
height: this.height,
showExport: true, //是否显示导出按钮
buttonsAlign:"right", //按钮位置
exportDataType:'all',
exportTypes:['json', 'xml', 'csv', 'txt', 'sql', 'excel'], //导出文件类型
icons: {
refresh: 'glyphicon-repeat',
toggle: 'glyphicon-list-alt',
columns: 'glyphicon-list',
export:'glyphicon-export'
},
iconSize: 'outline'
});
return this;
},
3.js端
/**
* 点击跳转本年统计
*/
BussnissIndex.openBussnissIndexYear = function () {
var queryData = {};
//pageNumber和pageSize一定要从bootstrap中获取实时的
queryData['pageNumber'] =
$("#IndexSdbB2cOrdersTable").bootstrapTable('getOptions').pageNumber;
queryData["pageSize"] = $("#IndexSdbB2cOrdersTable").bootstrapTable('getOptions').pageSize;
queryData['day'] = '';
queryData['month'] = '';
queryData['year'] = 'year';
if (queryData['day'] != null || queryData['day'] != '' || queryData['month'] != null || queryData['month'] != '' || queryData['year'] != null || queryData['year'] != '') {
queryData['beginTimestamp'] = '';
queryData['endTimestamp'] = '';
}
;
if (this.get("pageType") == 'year') {
return;
} else {
//提交信息
var ajax = new $ax(Feng.ctxPath + "/blackboard/year", function (data) {
BussnissIndex.loadData(data);
}, function (data) {
return data;
});
ajax.start();
BussnissIndex.table.refresh({query: queryData});
}
};
//页面加载时需要加载的数据
$(function () {
var defaultColunms = BussnissIndex.initColumn();
var table = new BSTable(BussnissIndex.id, "/indexdata/list", defaultColunms);
table.setPaginationType("server"); //client是客户端 server是服务器端分页
table.setQueryParams(BussnissIndex.formParams());
BussnissIndex.table = table.init();
});
4.controller层
@Controller
@RequestMapping("/indexdata")
public class IndexDataController extends BaseController {
@Autowired
private IndexDataService indexDataService;
private static Logger logger = LoggerFactory.getLogger(IndexDataController.class);
private String PREFIX = "/basic/basicExport";
/**
* 获取首页数据 表格
*/
@RequestMapping(value = "/list")
@ResponseBody
public Object list(String day, String month, String year, String beginTimestamp, String endTimestamp,String pageNumber,String pageSize) {
long startTime = System.currentTimeMillis();
logger.info("---------------查询表格开始时间为:【"+startTime+"】---------------");
try {
if (StringUtils.isNotBlank(beginTimestamp)) {
beginTimestamp = TimeUtil.toTimestamp11(beginTimestamp);
}
if (StringUtils.isNotBlank(endTimestamp)) {
endTimestamp = TimeUtil.toTimestamp11(endTimestamp);
}
} catch (ParseException e) {
logger.debug(e.toString());
}
//如果开始时间和结束时间是相等的那就做一下处理
if (StringUtils.isNotBlank(endTimestamp)) {
if (beginTimestamp.equals(endTimestamp)) {
Long endtime = (Long.valueOf(endTimestamp) + 86400L);
endTimestamp = endtime.toString();
}
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String today = simpleDateFormat.format(new Date());
String thisYear = today.substring(0, 4);
String thisMonth = today.substring(5, 7);
List<IndexData> indexDataList = null;
if (day != null && !day.isEmpty() || beginTimestamp != null && !beginTimestamp.isEmpty() || endTimestamp != null && !endTimestamp.isEmpty()) {
indexDataList = indexDataService.queryIndexTableDataDay(day, month, year, beginTimestamp, endTimestamp, today, thisMonth, thisYear);
} else {
//这两个参数一定是从前端传过来的,否则查询的总是前pageSize条数据,虽然可以分页但数据错误
//$("#tableId").bootstrapTable('getOptions').pageNumber;
int page_number = Integer.parseInt(pageNumber);
//$("#tableId").bootstrapTable('getOptions').pageSize;
int page_size = Integer.parseInt(pageSize);
Page<IndexData> indexDataPage = indexDataService.queryIndexTableData2(day, month, year, beginTimestamp, endTimestamp, today, thisMonth, thisYear,page_number,page_size);
List<IndexData> records = indexDataPage.getRecords();
HashMap<String, Object> map = new HashMap<>();
map.put("total",indexDataPage.getTotal());
map.put("rows",records);
for (IndexData record : records) {
System.out.println("-------record:------" + record);
}
long endTime = System.currentTimeMillis();
logger.info("---------------------查询表格用时总计:【"+(endTime-startTime)+"】-------------------------");
return map;
}
long endTime = System.currentTimeMillis();
logger.info("---------------------查询表格用时总计:【"+(endTime-startTime)+"】-------------------------");
return indexDataList;
}
}
5.service层
Page<IndexData> queryIndexTableData2(String day, String month, String year, String beginTimestamp, String endTimestamp, String today, String thisMonth, String thisYear, int page, int pageSize);
6.serviceImpl层
package com.stylefeng.guns.modular.business.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.entity.IndexData;
import com.stylefeng.guns.entity.MerchantTransactionSummary;
import com.stylefeng.guns.entity.TransactionGoodsDetails;
import com.stylefeng.guns.entity.TransactionPaymentDetails;
import com.stylefeng.guns.modular.business.dao.IndexDataMapper;
import com.stylefeng.guns.modular.business.service.IndexDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class IndexDataServiceImpl implements IndexDataService {
@Autowired
private IndexDataMapper indexDataMapper;
@Override
public Page<IndexData> queryIndexTableData2(String day, String month, String year, String beginTimestamp, String endTimestamp, String today, String thisMonth, String thisYear, int page, int pageSize) {
//创建Page对象,传入page,pageSize参数 当前页和页面数据量大小
Page<IndexData> indexDataPage = new Page<>(page, pageSize);
//接收参数一定要是setRecord()
Page<IndexData> indexDataPage1 = indexDataPage.setRecords(indexDataMapper.queryIndexTableData2(day, month, year, beginTimestamp, endTimestamp, today, thisMonth, thisYear, indexDataPage));
return indexDataPage1;
}
}
7.dao层
List<IndexData> queryIndexTableData2(@Param("day") String day, @Param("month") String month, @Param("year") String year, @Param("beginTimestamp") String beginTimestamp, @Param("endTimestamp") String endTimestamp, @Param("today") String today, @Param("thisMonth") String thisMonth, @Param("thisYear") String thisYear, Page<IndexData> indexDataPage);
8.xml可以看出没有任何分页的迹象,因为拦截器帮我们做了操作
<select id="queryIndexTableData2" resultType="com.stylefeng.guns.entity.IndexData">
SELECT
om.mer_name AS merName,
IFNULL( SUM( osmd.order_amt ), 0 ) AS totalAmount,
IFNULL( SUM( osmd.order_total ), 0 ) AS orderTotal,
om.mer_address AS merAdress,
om.contact_name AS contactPerson,
om.contact_phone AS contractMobile,
om.mer_no AS merId,
tr.trading_name AS tradingName
FROM
sdb_basic_merchant AS om
LEFT JOIN sdb_basic_trading_mer mer on mer.mer_id=om.id
LEFT JOIN sdb_basic_trading tr on tr.id=mer.trading_id
LEFT JOIN o2o_sts_mrt_dly AS osmd on om.mer_no = osmd.mer_id
WHERE 1=1
<if test="month != null and month !=''">
and osmd.`month` = #{thisMonth} and osmd.`year` = #{thisYear}
</if>
<if test="year != null and year !=''">
and osmd.`year` = #{thisYear}
</if>
GROUP BY
om.mer_no
order by
totalAmount DESC
</select>
效果
每点击一次下一页就查询一页的数据,成功完成了服务器端分页