前言
文章使用了近期比较流行的框架,适合有一定Maven开发经验的读者。
开发工具:Spring Tool Suite
开发环境:SpringBoot+Maven+SSM(三大框架)+JDK1.8
数据库:本文采用Oracle
当然,也可以用Eclipse/MyEclipse,jdk其他版本来开发,记得修改jre和pom配置等问题就行。
代码
导入相关依赖包pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>page-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<packaging>jar</packaging>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<mybatisplus-spring-boot-starter.version>1.0.1</mybatisplus-spring-boot-starter.version>
<fastjson.version>1.2.31</fastjson.version>
<druid.version>1.0.0</druid.version>
<commons.io.version>2.5</commons.io.version>
</properties>
<dependencies>
<!--spring boot依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 这里指定打包的时候不再需要tomcat相关的包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>${mybatisplus-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--其他依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<executable>true</executable>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceExcludes>src/main/resources/**</warSourceExcludes>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/webapp</directory>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
添加Oracle驱动包:/build/lib/ojdbc14-10.2.0.4.0.jar,后面笔者会贴上下载地址(包括本文Demo),也可自行谷百下载。
application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:property-placeholder location="classpath:application.properties"/>
<!-- 数据源定义,使用Apache DBCP 连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="maxActive" value="${jdbc.maxActive}" />
<property name="minIdle" value="${jdbc.minIdle}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />
<!-- 是否自动回收超时连接 -->
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="150"/>
<!-- 是否在自动回收超时连接的时候打印连接的超时错误 -->
<property name="logAbandoned" value="true"/>
<!-- false : 空闲时是否验证, 若不通过断掉连接, 前提是空闲对象回收器开启状态 -->
<property name="testWhileIdle" value="true"/>
<property name="validationQuery" value="SELECT 'x' from dual" />
<!-- -1 : 以毫秒表示空闲对象回收器由运行间隔。值为负数时表示不运行空闲对象回收器 若需要回收, 该值最好小于 minEvictableIdleTimeMillis 值 -->
<property name="timeBetweenEvictionRunsMillis" value="300000"/>
<!--1000*60*30 : 被空闲对象回收器回收前在池中保持空闲状态的最小时间, 毫秒表示 若需要回收, 该值最好小于DB中的 wait_timeout 值 -->
<property name="minEvictableIdleTimeMillis" value="320000"/>
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath*:/sqlmapper/*.xml" />
<property name="failFast" value="true"></property>
<property name="plugins">
<array>
<bean class="com.page.example.common.PageInterceptor">
</bean>
</array>
</property>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.page.example.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!-- 配置事务管理器,注意这里的dataSource和SqlSessionFactoryBean的dataSource要一致,不然事务就没有作用了 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置事务的传播特性 -->
<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="edit*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="del*">PROPAGATION_REQUIRED</prop>
<prop key="*">readOnly</prop>
</props>
</property>
</bean>
</beans>
代码已经做了详细的说明,不再赘述。
关键代码是事务配置中文件(mybatis-config.xml/)路径引用和分页拦截器PageInterceptor
application.properties
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc\:oracle\:thin\:@192.168.1.70\:1521\:orcl
jdbc.username=kop
jdbc.password=kop237
jdbc.initialSize=5
jdbc.maxActive=20
jdbc.minIdle=1
server.port=8081
server.contextPath=/page
数据库配置以及服务端口、请求路径
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="dialect" value="oracle" />
</properties>
<typeAliases>
<package name="com.page.example.model" />
</typeAliases>
</configuration>
如果想用MySQL,只需修改此处key:dialect对应的value为mysql(或者直接删除该配置,本文代码中默认使用MySQL),还有驱动包
到此,环境就搭建好了。下面进入正题
分页实体类PageQuery.java
分页实体类PageQuery.java
package com.page.example.model;
import java.io.Serializable;
public class PageQuery implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
/*页码*/
private Integer curPageNum;
/*页总数*/
private Integer pageSize;
private Integer startPos;
private Integer endPos;
private String sort;
private String dir;
/**
* 总数,如果总数<>0,则表示
*/
private Integer totalNum = 0;
public PageQuery(){
}
public PageQuery(Integer curPageNum, Integer pageSize) {
this.setPosition(curPageNum, pageSize);
}
public Integer getTotalNum() {
return totalNum;
}
/**
* 总数,如果总数<>0,则表示
*/
private Integer totalPageNum = 0;
public Integer getTotalPageNum() {
return totalPageNum;
}
public void setTotalPageNum(Integer totalPageNum) {
if (totalPageNum == null) {
totalPageNum = 1;
}
this.totalPageNum = totalPageNum;
}
public void setTotalNum(Integer totalNum) {
if (totalNum == null) {
totalNum = 0;
}
this.totalNum = totalNum;
}
public Integer getStartPos() {
return startPos;
}
public Integer getEndPos() {
endPos = startPos + pageSize - 1;
return endPos;
}
public void setPosition(Integer curPageNum, Integer pageSize) {
if (curPageNum == null || curPageNum < 1) {
curPageNum = 1;
}
if (pageSize == null) {
pageSize = 50;
}
this.curPageNum = curPageNum;
this.pageSize = pageSize;
startPos = (curPageNum - 1) * pageSize + 1;
endPos = startPos + pageSize - 1;
}
public Integer getCurPageNum() {
return curPageNum;
}
public Integer getPageSize() {
return pageSize;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public void setStartPos(Integer startPos) {
this.startPos = startPos;
}
public void setCurPageNum(Integer curPageNum) {
this.curPageNum = curPageNum;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public void setEndPos(Integer endPos) {
this.endPos = endPos;
}
@Override
public String toString() {
return "PageQuery [curPageNum=" + curPageNum + ", pageSize=" + pageSize + ", startPos="
+ startPos + ", endPos=" + endPos + ", sort=" + sort + ", dir=" + dir
+ ", totalNum=" + totalNum + ", totalPageNum=" + totalPageNum + "]";
}
}
分页拦截器PageInterceptor.java
package com.page.example.common;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.page.example.model.PageQuery;
/**
*
* @author fengjk
*
*/
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class,Integer.class}) })
public class PageInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(PageInterceptor.class);
private static String defaultDialect = "mysql";
private static String defaultPageSqlId = ".*Page$";
private String dialect = ""; //数据库方言
private String pageSqlId = ""; //mapper.xml中需要拦截的ID(正则匹配)
public int pageSize = 10;
public int curPageNum = 1;
private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
private static final ReflectorFactory DEFAULT_REFLECT_FACTORY = new DefaultReflectorFactory();
public Object intercept(Invocation paramInvocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) paramInvocation.getTarget();
MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECT_FACTORY);
// 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环
// 可以分离出最原始的的目标类)
while (metaStatementHandler.hasGetter("h")) {
Object object = metaStatementHandler.getValue("h");
metaStatementHandler = MetaObject.forObject(object,DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECT_FACTORY);
}
// 分离最后一个代理对象的目标类
while (metaStatementHandler.hasGetter("target")) {
Object object = metaStatementHandler.getValue("target");
metaStatementHandler = MetaObject.forObject(object,DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECT_FACTORY);
}
Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");
dialect = configuration.getVariables().getProperty("dialect");
if (null == dialect || "".equals(dialect)) {
logger.warn("Property dialect is not setted,use default 'mysql' ");
dialect = defaultDialect;
}
pageSqlId = configuration.getVariables().getProperty("pageSqlId");
if (null == pageSqlId || "".equals(pageSqlId)) {
pageSqlId = defaultPageSqlId;
}
MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
// 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的
// MappedStatement的sql
if (mappedStatement.getId().matches(pageSqlId)) {
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
Object parameterObject = boundSql.getParameterObject();
if (parameterObject == null) {
throw new NullPointerException("parameterObject is null!");
} else {
// 分页参数作为参数对象parameterObject的一个属性
PageQuery page = (PageQuery) metaStatementHandler.getValue("delegate.boundSql.parameterObject.page");
if(page.getCurPageNum()<=0 || page.getPageSize()<=0){
page.setPageSize(pageSize);
page.setCurPageNum(curPageNum);
}
String sql = boundSql.getSql();
// 重写sql
String pageSql = this.buildPageSql(sql, page);
metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
// 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
metaStatementHandler.setValue("delegate.rowBounds.offset",RowBounds.NO_ROW_OFFSET);
metaStatementHandler.setValue("delegate.rowBounds.limit",RowBounds.NO_ROW_LIMIT);
Connection connection = (Connection) paramInvocation.getArgs()[0];
// 重设分页参数里的总页数等
this.setPageParameter(sql, connection, mappedStatement, boundSql,page);
}
}
// 将执行权交给下一个拦截器
return paramInvocation.proceed();
}
public Object plugin(Object paramObject) {
return Plugin.wrap(paramObject, this);
}
public void setProperties(Properties paramProperties) {
this.dialect = paramProperties.getProperty("dialect");
}
private String buildPageSql(String sql, PageQuery page) {
if (page != null) {
StringBuilder pageSql = new StringBuilder();
if ("mysql".equals(dialect)) {
pageSql = buildPageSqlForMysql(sql, page);
} else if ("oracle".equals(dialect)) {
pageSql = buildPageSqlForOracle(sql, page);
} else {
return sql;
}
return pageSql.toString();
} else {
return sql;
}
}
public StringBuilder buildPageSqlForMysql(String sql, PageQuery page) {
StringBuilder pageSql = new StringBuilder(100);
String beginrow = String.valueOf((page.getCurPageNum() - 1) * page.getPageSize());
pageSql.append(sql);
pageSql.append(" limit " + beginrow + "," + page.getPageSize());
return pageSql;
}
public StringBuilder buildPageSqlForOracle(String sql, PageQuery page) {
StringBuilder pageSql = new StringBuilder(100);
String beginrow = String.valueOf((page.getCurPageNum() - 1) * page.getPageSize());
String endrow = String.valueOf(page.getCurPageNum() * page.getPageSize());
pageSql.append("select * from ( select temp.*, rownum row_id from ( ");
pageSql.append(sql);
pageSql.append(" ) temp where rownum <= ").append(endrow);
pageSql.append(") where row_id > ").append(beginrow);
return pageSql;
}
/**
* 从数据库里查询总的记录数并计算总页数,回写进分页参数<code>PageParameter</code>,这样调用
* 者就可用通过 分页参数<code>PageParameter</code>获得相关信息。
*
* @param sql
* @param connection
* @param mappedStatement
* @param boundSql
* @param page
*/
private void setPageParameter(String sql, Connection connection, MappedStatement mappedStatement,BoundSql boundSql, PageQuery page) {
// 记录总记录数
String countSql = "select count(0) from (" + sql + ")";
PreparedStatement countStmt = null;
ResultSet rs = null;
try {
countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,boundSql.getParameterMappings(), boundSql.getParameterObject());
setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject());
rs = countStmt.executeQuery();
int totalCount = 0;
if (rs.next()) {
totalCount = rs.getInt(1);
}
page.setTotalNum(totalCount);
page.setTotalPageNum(totalCount);
if(page.getPageSize()>0){
int totalPage = totalCount / page.getPageSize() + ((totalCount % page.getPageSize() == 0) ? 0 : 1);
page.setTotalPageNum(totalPage);
}
} catch (SQLException e) {
logger.error("Ignore this exception", e);
} finally {
try {
if(rs != null){
rs.close();
}
} catch (SQLException e) {
logger.error("Ignore this exception", e);
}
try {
if(countStmt != null){
countStmt.close();
}
} catch (SQLException e) {
logger.error("Ignore this exception", e);
}
}
}
/**
* 对SQL参数(?)设值
*
* @param ps
* @param mappedStatement
* @param boundSql
* @param parameterObject
* @throws SQLException
*/
private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,
Object parameterObject) throws SQLException {
ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler.setParameters(ps);
}
public String getDialect() {
return dialect;
}
public void setDialect(String dialect) {
this.dialect = dialect;
}
public String getPageSqlId() {
return pageSqlId;
}
public void setPageSqlId(String pageSqlId) {
this.pageSqlId = pageSqlId;
}
}
下面就是写个请求的栗子,方便读者理解。
业务实体类RemoteControl.java
package com.page.example.model;
import java.io.Serializable;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
public class RemoteControl implements Serializable {
private static final long serialVersionUID = 1L;
private Long id; // ID
private String electricalroomname; // 电房名称
private Short feederid; // 馈线ID
private String feedername; // 馈线名称
private String devicevender; // 终端厂家
private Byte commmode; // 通信方式
private Date planprocesstime; // 计划操作日期
private String rmtprocesscontent; // 三遥操作内容
private Integer prjproperty; // 工程性质
private String checkresult; // 核实情况
private String feedback; // 具体反馈信息
@DateTimeFormat(iso= ISO.DATE)
private Date realprocesstime; // 实际操作时间
private String operator; // 操作员
private Integer result; // 遥控结果
private Date createtime; // 创建时间
private Date beginTime;
private Date endTime;
public String getFeedername() {
return feedername;
}
public void setFeedername(String feedername) {
this.feedername = feedername;
}
public Date getBeginTime() {
return beginTime;
}
public void setBeginTime(Date beginTime) {
this.beginTime = beginTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getElectricalroomname() {
return electricalroomname;
}
public void setElectricalroomname(String electricalroomname) {
this.electricalroomname = electricalroomname;
}
public Short getFeederid() {
return feederid;
}
public void setFeederid(Short feederid) {
this.feederid = feederid;
}
public String getDevicevender() {
return devicevender;
}
public void setDevicevender(String devicevender) {
this.devicevender = devicevender;
}
public Byte getCommmode() {
return commmode;
}
public void setCommmode(Byte commmode) {
this.commmode = commmode;
}
public Date getPlanprocesstime() {
return planprocesstime;
}
public void setPlanprocesstime(Date planprocesstime) {
this.planprocesstime = planprocesstime;
}
public String getRmtprocesscontent() {
return rmtprocesscontent;
}
public void setRmtprocesscontent(String rmtprocesscontent) {
this.rmtprocesscontent = rmtprocesscontent;
}
public Integer getPrjproperty() {
return prjproperty;
}
public void setPrjproperty(Integer prjproperty) {
this.prjproperty = prjproperty;
}
public String getCheckresult() {
return checkresult;
}
public void setCheckresult(String checkresult) {
this.checkresult = checkresult;
}
public String getFeedback() {
return feedback;
}
public void setFeedback(String feedback) {
this.feedback = feedback;
}
public Date getRealprocesstime() {
return realprocesstime;
}
public void setRealprocesstime(Date realprocesstime) {
this.realprocesstime = realprocesstime;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public Integer getResult() {
return result;
}
public void setResult(Integer result) {
this.result = result;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
@Override
public String toString() {
String log = "";
log += "[id:" + getId() + "]";
log += "[electricalroomname:" + getElectricalroomname() + "]";
log += "[feederid:" + getFeederid() + "]";
log += "[devicevender:" + getDevicevender() + "]";
log += "[commmode:" + getCommmode() + "]";
log += "[planprocesstime:" + getPlanprocesstime() + "]";
log += "[rmtprocesscontent:" + getRmtprocesscontent() + "]";
log += "[prjproperty:" + getPrjproperty() + "]";
log += "[checkresult:" + getCheckresult() + "]";
log += "[feedback:" + getFeedback() + "]";
log += "[realprocesstime:" + getRealprocesstime() + "]";
log += "[operator:" + getOperator() + "]";
log += "[result:" + getResult() + "]";
log += "[createtime:" + getCreatetime() + "]";
log += super.toString();
return log;
}
}
RemoteControlMapper.java
package com.page.example.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.page.example.model.PageQuery;
import com.page.example.model.RemoteControl;
public interface RemoteControlMapper {
List<RemoteControl> getRemoteControlPage(@Param("page")PageQuery pageQuery);
}
RemoteControlMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.page.example.mapper.RemoteControlMapper">
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<![CDATA[id,electricalroomname,feederid,devicevender,commmode,planprocesstime,rmtprocesscontent,prjproperty,checkresult,feedback,realprocesstime,operator,result,createtime]]>
</sql>
<resultMap id="BaseResultMap" type="RemoteControl">
<id column="ID" property="id" />
<result column="ELECTRICALROOMNAME" property="electricalroomname" />
<result column="FEEDERID" property="feederid" />
<result column="DEVICEVENDER" property="devicevender" />
<result column="COMMMODE" property="commmode" />
<result column="PLANPROCESSTIME" property="planprocesstime" />
<result column="RMTPROCESSCONTENT" property="rmtprocesscontent" />
<result column="PRJPROPERTY" property="prjproperty" />
<result column="CHECKRESULT" property="checkresult" />
<result column="FEEDBACK" property="feedback" />
<result column="REALPROCESSTIME" property="realprocesstime" />
<result column="OPERATOR" property="operator" />
<result column="RESULT" property="result" />
<result column="CREATETIME" property="createtime" />
</resultMap>
<select id="getRemoteControlPage" resultType="RemoteControl">
select <include refid="Base_Column_List" /> from REMOTE_CONTROL where 1 = 1
</select>
</mapper>
对外接口RemoteControlController.java
package com.page.example.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.page.example.mapper.RemoteControlMapper;
import com.page.example.model.PageQuery;
import com.page.example.model.RemoteControl;
/**
*
* @author fengjk
* @date 2017-07-17
*/
@Controller
@RequestMapping(value = "/other/remoteControl")
public class RemoteControlController {
@Resource
private RemoteControlMapper remoteControlMapper;
@RequestMapping(value = "/list", method = { RequestMethod.POST })
@ResponseBody
public JSONObject list( @RequestBody JSONObject paramObject) {
int page = paramObject.getIntValue("page");
int size = paramObject.getIntValue("size");
if (page == 0) {
page = 1;
}
if (size == 0) {
size = 10;
}
PageQuery pageQuery = new PageQuery(page, size);
List<RemoteControl> result = remoteControlMapper.getRemoteControlPage(pageQuery);
Map<String, Object> resultMap = new HashMap<String, Object>();
resultMap.put("total", pageQuery.getTotalNum());
resultMap.put("content", result);
JSONObject resultObject = new JSONObject();
resultObject.put("result_data", resultMap);
return resultObject;
}
}
启动类PageApplication.java
package com.page.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportResource;
/**
* 启动类
*
*/
@SpringBootApplication
@ComponentScan({"com.page.example"})
@ImportResource({"classpath:application-context.xml"})
public class PageApplication extends SpringBootServletInitializer{
protected final static Logger logger = LoggerFactory.getLogger(PageApplication.class);
public static void main(String[] args) {
SpringApplication.run(PageApplication.class, args);
logger.info("PageApplication is sussess!");
}
}
这个尤为重要,能不能运行就靠它了。@ComponentScan扫描实体和mapper映射文件,@ImportResource顾名思义。最后启动服务。(PageApplication.java右键--Run As--Java Application)
模拟测试调用接口,笔者用的是谷歌apizza插件工具
也可以不传参数,代码中默认page:1,size:10。page为页码,size为每页条数(此处查询第1页10条数据)。total为表数据总数,content为返回数据。
Error(附上笔者踩过的坑)
以上情况是由于Mybatis版本问题,3.4.4以下版本StatementHandler没有transactionTimeout参数,forObject没有ReflectorFactory。注意:使用Mybatis3.4.4以下版本只需把这两个地方参数去掉,反之,同理
总结
近期比较忙碌,一直没时间整理,终于腾出时间自己搭建一套框架,顺便就分享一下后台开发中常见的分页功能实现,笔者感觉光是搭建项目都能给读者带来帮助,避免踩坑,同样也适合SpringBoot初学者,后期附上Demo下载地址,文章如有笔误,请及时联系笔者,万分感谢,欢迎加qq群学习交流:583138104