SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)

SSM+Maven学习笔记整理(持续更新...)

  • 最终目标:搭建一个简单的管理系统
  • 学习目的:熟悉巩固java基础知识,熟悉ssm框架使用,熟悉maven使用
  • 笔记作用:即便是参考博客开发,仍然遇到一个接一个的问题,所以需要记录一下学习过程中遇到的耗时较长的问题,以后再次遇到的话,可以参考
  • 参考博客https://gitchat.csdn.net/ ,这个栏目的热门课程之一【SSM 搭建精美实用的管理系统】

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第1张图片

目录

SSM+Maven学习笔记整理(持续更新...)

问题1:idea中启动tomcat一直失败,提示程序包org.springframework.beans.factory.annotation不存在等错误,查了网上各种方法,均没效果

问题2:Invalid bound statement (not found)

问题3:Driver com.mysql.cj.jdbc.Driver@19b1122e deregistered

问题4:Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 53; 文档根元素 "mapper" 必须匹配 DOCTYPE 根 "null"。

问题5:java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]

问题6:Web应用程序[ROOT]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪

问题7:mybatis执行update时报错

问题8:数据库的date类型字段在页面中只显示日期部分

问题9:mybatis插入数据时,数据回滚


 

问题1:idea中启动tomcat一直失败,提示程序包org.springframework.beans.factory.annotation不存在等错误,查了网上各种方法,均没效果

方法图示:SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第2张图片

 解决说明:我选择了自己的maven仓库,但是这里忘记点击覆盖原先依赖仓库了,导致启动时一直找不到pom.xml中配置下载到D:\maven\repo下的依赖包

问题2Invalid bound statement (not found)

问题说明: tomcat启动后,直接访问controller层手写的一个test方法可以正常访问和跳转静态页面(没用mybatis),但是使用了mybatis访问数据库后就会报该错误,一直提示绑定错误

解决思路:这种问题一看就是mapper映射出了问题,但是由于很久没接触SSM了,一时半会不确定具体要检查的点在哪,参考了网上的提示后,终于找到了问题关键所在(applicationContext.xml中配置自动扫描mapper文件的代码被我注释掉了)

问题图示:

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第3张图片

解决方法:取消注释(上图是取消后的代码) 

问题3:Driver com.mysql.cj.jdbc.Driver@19b1122e deregistered

问题原因1:mysql版本错乱,我本地安装的mysql版本为8.0.20,但是pom.xml中写的版本是5.1.38,如下图位置

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第4张图片

问题原因2: 修改为8.0.20 后,依然报错,全局搜索pom.xml中5.1.38后,发现还有一处,写死了jdbc驱动版本号,如下图

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第5张图片

这样的话mysql版本就会版本就会出错

问题4Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 53; 文档根元素 "mapper" 必须匹配 DOCTYPE 根 "null"。

问题原因: mapper的xml文件中 ,缺少头部声明信息

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第6张图片

问题5:java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]

信息 [mysql-cj-abandoned-connection-cleanup] org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。
    java.lang.IllegalStateException: 非法访问:此Web应用程序实例已停止。无法加载[]。为了调试以及终止导致非法访问的线程,将抛出以下堆栈跟踪。 

问题说明:在使用tomcat启动运行项目时,总是会出现这个错误,虽然不影响项目运行但是看着还是很不舒服的,一大堆错误提示。

问题原因:在tomcat重启的时候,因为之前的tomcat中的线程还没有完全关闭,新启动tomcat就会报这个异常,不过这个不影响正常使用,只是跳个异常挺烦人的。使用过hibernate, spring或其他大型组件,当一个WEB应用系统中有很多类时,如果开启了Tomcat的reloadable=true,那么每当相关文件改变时, Tomcat会停止web app并释放内存,然后重新加载web app.这实在是个浩大的工程。所以我们总是在想如果能有只重载某几个类的功能,将极大的满足了我们的调试。

解决方法:

方法1:修改tomcat目录下的context.xml,找到标签,把reloadble的属性值设为:reloadable="false",即【本人采用】

方法2:将tomcat的server.xml中的Context的reloadable设成false。比如:【本人此文件中原先就是false,无需修改】

 

问题6:Web应用程序[ROOT]似乎启动了一个名为[mysql-cj-abandoned-connection-cleanup]的线程,但未能停止它。这很可能会造成内存泄漏。线程的堆栈跟踪

问题描述:

意思是注册过jdbc‘驱动,但是在容器关闭时没有注销,并且是在开启了一个AbandonedConnectionCleanupThread线程中的。 所以为了内存避免泄露,就强制注销了驱动。

这是一个保护机制,并不是问题,所以可以忽略。

如果你想不打印这个警告信息,可以这么做,写一个容器监听器,在容器销毁时,手动编码注销驱动

package com.ssm.demo.utils;

import com.mysql.jdbc.AbandonedConnectionCleanupThread;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

public class MyContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {

    }

    // 自己写代码注销驱动
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        Enumeration drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            try {
                DriverManager.deregisterDriver(drivers.nextElement());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        // 再关闭AbandonedConnectionCleanupThread线程
        try {
            AbandonedConnectionCleanupThread.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("手动注销驱动、关闭AbandonedConnectionCleanupThread线程");
    }
}

web.xml中添加监听:


    com.ssm.demo.utils.ContextFinalizer


解决方法:尚未找到有效解决办法, 上述代码有报错,仍在解决中

问题7:mybatis执行update时报错

问题描述:

02-Jul-2020 10:33:36.914 信息 [http-nio-8888-exec-6] org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
02-Jul-2020 10:33:36.928 信息 [http-nio-8888-exec-6] org.springframework.jdbc.support.SQLErrorCodesFactory. SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
adminUserDao.updateUserToken方法执行失败

解决方法:

虽然通过控制台打印出来的执行sql(配置打印执行SQL方法:mybatis-config.xml文件添加如下代码

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第7张图片)直接放到数据库中执行没问题,但是这个报错却一直出现,通过打印捕获异常后问题定位在事务属性的配置文件applicationContext.xml中,多了一行,如下图SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第8张图片 (此行导致执行update时匹配到它而匹配不到update*的事务,也就导致update时只有数据库只读权限而出错)

打印异常后报错如下:

### Error updating database.  Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: update tb_admin_user set user_token = ? where user_id = ?
### Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed

解决方法:

注释掉:

(其实事务一般都是会参照一个规范去命名方法,比如查看都用get/find/select做前缀,修改都用update/alter/set做前缀,删除都用del/delete/drop做前缀等等。不需要再用*去当做事务配置)

 

问题8:数据库的date类型字段在页面中只显示日期部分

问题描述:

mysql数据库中的date类型,包含日期和时间,但是通过mybatis获取后展示到界面却没有时间部分

问题原因:

mybatis的映射文件中接收createTime字段时,默认使用的是sql.Date类型,应该指定为Timestamp类型才能显示日期+时间

解决方法:

步骤1:指定返回字段的接受类型为Timestamp,如下:

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第9张图片

步骤2:修改bean的createTime字段为Timestamp类型,如下:

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第10张图片

步骤3:重启服务器,正常显示日期 + 时间

问题9:mybatis插入数据时,数据回滚

问题代码:

Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3415b03f]
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@459c4b97] will be managed by Spring
ooo Using Connection [com.mysql.cj.jdbc.ConnectionImpl@459c4b97]
==>  Preparing: insert into tb_admin_user(user_id,user_name,password_md5) values(?,?,?) 
==> Parameters: t(String), t(String), t(String)
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3415b03f]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3415b03f]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3415b03f]
17:46:02.571 [http-nio-8888-exec-8] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Initiating transaction rollback
17:46:02.571 [http-nio-8888-exec-8] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Rolling back JDBC transaction on Connection [com.mysql.cj.jdbc.ConnectionImpl@459c4b97]
17:46:02.574 [http-nio-8888-exec-8] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@459c4b97] after transaction
17:46:02.574 [http-nio-8888-exec-8] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
17:46:02.575 [http-nio-8888-exec-8] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.ssm.common.Result com.ssm.demo.controller.AdminUserController.user_add(com.ssm.demo.entity.AdminUser,java.lang.String)]: org.apache.ibatis.binding.BindingException: Mapper method 'com.ssm.demo.dao.AdminUserDao.insertAdminUser attempted to return null from a method with a primitive return type (int).
17:46:02.577 [http-nio-8888-exec-8] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public com.ssm.common.Result com.ssm.demo.controller.AdminUserController.user_add(com.ssm.demo.entity.AdminUser,java.lang.String)]: org.apache.ibatis.binding.BindingException: Mapper method 'com.ssm.demo.dao.AdminUserDao.insertAdminUser attempted to return null from a method with a primitive return type (int).
17:46:02.577 [http-nio-8888-exec-8] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.ssm.common.Result com.ssm.demo.controller.AdminUserController.user_add(com.ssm.demo.entity.AdminUser,java.lang.String)]: org.apache.ibatis.binding.BindingException: Mapper method 'com.ssm.demo.dao.AdminUserDao.insertAdminUser attempted to return null from a method with a primitive return type (int).
17:46:02.580 [http-nio-8888-exec-8] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
org.apache.ibatis.binding.BindingException: Mapper method 'com.ssm.demo.dao.AdminUserDao.insertAdminUser attempted to return null from a method with a primitive return type (int).
	at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:69)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:43)
	at com.sun.proxy.$Proxy69.insertAdminUser(Unknown Source)
	at com.ssm.demo.service.impl.AdminUserServiceImpl.insertAdminUser(AdminUserServiceImpl.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
	at com.sun.proxy.$Proxy71.insertAdminUser(Unknown Source)
	at com.ssm.demo.controller.AdminUserController.user_add(AdminUserController.java:98)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:543)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:615)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:818)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1627)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

问题原因:

insert语句但是因为拷贝用成了select标签,导致insert失败

SSM框架学习与问题记录(适合完整SSM框架搭建Web项目学习 | 毕业设计)_第11张图片

解决方法:

修改mapper.xml文件中的select标签为insert

 

2020.7.9 更新

未完待续...

你可能感兴趣的:(java学习历程,Mybatis学习)