org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NullPointerException
### The error may exist incom/imooc/config/sqlxml/Command.xml
### The error may involvecom.imooc.dao.IMessage.queryCommandListByPage
### The error occurred whileexecuting a query
### Cause: java.lang.NullPointerException
atorg.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
atorg.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:122)
atorg.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113)
atorg.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:122)
atorg.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:64)
atorg.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
at$Proxy5.queryCommandListByPage(Unknown Source)
atcom.imooc.dao.CommandDAO.queryCommandListByPage(CommandDAO.java:71)
atcom.imooc.service.QueryService.queryCommandListByPage(QueryService.java:58)
atcom.imooc.servlet.ListServlet.doGet(ListServlet.java:42)
atcom.imooc.servlet.ListServlet.doPost(ListServlet.java:57)
atjavax.servlet.http.HttpServlet.service(HttpServlet.java:650)
atjavax.servlet.http.HttpServlet.service(HttpServlet.java:731)
atorg.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
atorg.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
atorg.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
atorg.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
atorg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
atorg.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
atorg.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
atorg.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
atorg.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
atorg.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
atorg.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
atorg.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
atorg.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2516)
atorg.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2505)
atjava.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
atorg.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
atjava.lang.Thread.run(Thread.java:619)
原因:
分页拦截器代码:
package com.imooc.interceptor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
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.SystemMetaObject;
import com.imooc.entity.Page;
/**
* 分页拦截器
*/
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})
public class PageInterceptor implements Interceptor {
private String test;
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, new DefaultReflectorFactory());
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 + ")a";
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();
Map,?> parameter = (Map,?>)boundSql.getParameterObject();
Page page = (Page)parameter.get("page");
if(rs.next()) {
page.setTotalNumber(rs.getInt(1));
}
// 改造后带分页查询的SQL语句
String pageSql = sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
metaObject.setValue("delegate.boundSql.sql", pageSql);
}
return invocation.proceed();
}
public Object plugin(Object target) {
System.out.println(this.test);
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
this.test = properties.getProperty("test");
// TODO Auto-generated method stub
}
}
其中MetaObject metaObject= MetaObject.forObject(statementHandler,SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, null);
新版本中此方法增加了一个参数,部分源码:
publicstaticMetaObject forObject(Object object, ObjectFactory objectFactory,ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) {
if(object == null){
returnSystemMetaObject.NULL_META_OBJECT;
} else{
returnnewMetaObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
}
第四个参数使用默认的ReflectorFactory接口的实现类
改成这样:
MetaObject metaObject = MetaObject.forObject(statementHandler,SystemMetaObject.DEFAULT_OBJECT_FACTORY,SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
执行成功。