JavaWeb中MySQL和Oracle数据库通用分页功能实现完整例子
2017-07-20 17:59
801 查看
前言
文章使用了近期比较流行的框架,适合有一定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
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(附上笔者踩过的坑)
RemoteControlMapper.xml中空间命名namespace路径错误或者DML方法名、参数和mapper中不一致。
以上情况是由于Mybatis版本问题,3.4.4以下版本StatementHandler没有transactionTimeout参数,forObject没有ReflectorFactory。注意:使用Mybatis3.4.4以下版本只需把这两个地方参数去掉,反之,同理
总结
近期比较忙碌,一直没时间整理,终于腾出时间自己搭建一套框架,顺便就分享一下后台开发中常见的分页功能实现,笔者感觉光是搭建项目都能给读者带来帮助,避免踩坑,同样也适合SpringBoot初学者,后期附上Demo下载地址,文章如有笔误,请及时联系笔者,万分感谢,欢迎加qq群学习交流:583138104相关文章推荐
- 【struts2+hibernate+spring项目实战】分页功能的完整的实现(通用分页、基类实现)
- ssh项目实战----分页功能的完整的实现(通用分页、基类实现)
- JSP+MySQL实现分页功能
- 使用mysql实现分页功能
- 6、实现通用分页功能二(实现通用分页查询的业务方法)
- MySQL中用select实现TOP N功能 及分页
- php+mysql结合Ajax实现点赞功能完整实例
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- springMVC详细配置+Mysql+jdbcTemplate实现分页功能
- java+mysql+jquey实现分页功能
- php+mysql结合Ajax实现点赞功能完整实例
- JSP实现从mysql读取数据并实现分页功能
- 用Java实现异构数据库的高效通用分页查询功能
- 基于spring boot的mysql使用pagehelper实现分页功能
- 7、实现通用分页功能三(实现通用分页JSP代码)
- Spring MVC+MyBatis+MySQL实现分页功能实例
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- jQuery实现的分页功能,包括ajax请求,后台数据,有完整demo
- 5、实现通用分页功能一(创建分页实体)
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)