BUG汇总:
1.在配置spring与mybatis的整合文件时出现了报错:
<bean id="dataSource" class="org.springframework."></bean>
其中org.springframework.没有jdbc模块,思考原因大概是依赖导入出现了问题,最后发现pom.xml中如下所示:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.16</version> <scope>test</scope> </dependency>
在pom.xml
中,spring-jdbc
的<scope>
被设置为test
,这会导致该依赖仅在测试阶段可用。
2.也是在配置spring与mybatis的整合文件时出现了报错:
<bean id="factory" class="org.mybatis"> 找不到mybatis类,问题在于我导入依赖时只导入了mybatis的依赖而没有导入mybatis-spring
3.在定义service层中的实现类时,出现报错
@Service public class BookServiceimpl implements BookService { @Autowired private BookMapper bookMapper; @Override public List selectALL() { return Collections.emptyList(); } }
说 private BookMapper bookMapper:无法自动装配。找不到 'BookMapper' 类型的 Bean。
那么显然就是BookMapper的实现类出现了问题,找到对应的BookMapper实现类:
<?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.hxy.pojo.Book"> <select id="sellectAll" resultType="book"> select * from book </select> </mapper>
发现命名空间出现了错误,因为实现类对应的应该是接口,而这里对应成了<mapper namespace="com.hxy.pojo.Book">,将其指向了类,那么显然出现了错误。从而导致无法创建实现类,页就无法使用 @Autowired private BookMapper bookMapper;,因为容器中并没有创建好的实现类。
修改后发现继续报错:private BookMapper bookMapper:无法自动装配。找不到 'BookMapper' 类型的 Bean。
还出现这个报错,说明实现类还是没有成功创建,所以去查找applicationConnect.xml配置文件,也就是mybatis和spring的整合配置文件,在其中查找与mapper.xml的配置是否正确,查找到
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/书城?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 起别名,对应路径类的小写即为别名(规定如此)--> <property name="typeAliasesPackage" value="com.hxy.pojo"></property> <property name="configLocation" value="classpath:mybatis.xml"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="factory"></property> <property name="basePackage" value="com.hxy.pojo"></property> </bean>
上述内容中的倒数第二行是对mapper实现类的地址进行搜索的,这里出现了错误,将其修改为正确的mapper.xml路径即可解决报错。
4.连接服务器时出现了报错:
ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.13.0:compile (default-compile) on project SSM: Fatal error compiling: 无效的目标发行版: 23 -> [Help 1]
大概意思就是我的java版本不对,但我看我的项目中的JDK版本是对的,在项目的pom.xml中导入
<properties> <java.version>1.8</java.version> <maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.release>${java.version}</maven.compiler.release> <project.build.sourceEncoding>US-ASCII</project.build.sourceEncoding> <thymeleaf.version>3.0.12.RELEASE</thymeleaf.version> </properties>
5.连接服务器成功后,我的控制层会将数据库的内容存入列表,并打印列表的大小,
@org.springframework.stereotype.Controller public class Controller { @Autowired BookService bookService; @RequestMapping("/sel") public String findAll() { List list = bookService.selectALL(); System.out.println(list.size()); return("index.jsp"); } }
如果项目配置正确,那么会在配置网页+/sel后出现index.jps的内容并且会在控制台返回list.size(),但现在控制台的输出为0,也就是并没有将数据库的内容正确的传递给控制层。
那么问题也比较简单,就是数据传输时出现了问题:
@Service public class BookServiceimpl implements BookService { @Autowired private BookMapper bookMapper; @Override public List selectALL() { return Collections.emptyList(); } }
这里是业务层的逻辑,讲道理来说业务层会接受数据库连接层的内容,并且传递给控制层内容。上述代码只是接受了数据库连接层的内容,而没有传递给控制层(压根没用熟练)
修改后继续报错:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.hxy.mapper.BookMapper.sellectAll at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235) at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53) at org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:108) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) at org.apache.ibatis.util.MapUtil.computeIfAbsent(MapUtil.java:35) at org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:95) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:86) at com.sun.proxy.$Proxy43.sellectAll(Unknown Source) at com.hxy.service.impl.BookServiceimpl.selectALL(BookServiceimpl.java:18) at com.hxy.controller.Controller.findAll(Controller.java:15) 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:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:750)
大概是说找不到mapper.xml这个配置文件了。
我排查了所有的配置文件,都能对应上,最后想起来问题出在这里:
这个com.hxy.mapper不能够直接在目录进行创建目录:com.hxy
应该分级创建:先创建com,在创建hxy,最后再创建配置文件,但是如果将目录设置为源代码时就可以直接通过.来进行分级创建了
完整流程:
1.首先构建spring和mybatis的整合配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/书城?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 起别名,对应路径类的小写即为别名(规定如此)--> <property name="typeAliasesPackage" value="com.hxy.pojo"></property> <!-- <property name="mapperLocations" value="classpath*:com/hxy/mapper/*.xml"/>--> <property name="configLocation" value="classpath:mybatis.xml"></property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="factory"></property> <property name="basePackage" value="com.hxy.mapper"></property> </bean> <context:component-scan base-package="com.hxy.service"></context:component-scan> </beans>
<context:component-scan base-package="com"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven>
上述内容中:
1.1context:component-scan
是用于组件扫描的,告诉Spring在指定的包及其子包下查找带有注解的类,比如@Component、@Service、@Controller、@Repository等,然后自动将它们注册为Spring的Bean。这样就不用在XML中手动配置每个Bean了,非常方便。我这里是扫描com
包,项目结构里所有的组件都在com包及其子包下。
1.2mvc:annotation-driven
,这个标签的作用是启用Spring MVC的注解驱动功能。它会自动注册一些关键的Bean,比如RequestMappingHandlerMapping和RequestMappingHandlerAdapter,这样就能处理@RequestMapping这样的注解,支持@RequestBody、@ResponseBody等,以及转换JSON和XML格式的数据。此外,它还启用了数据绑定、验证和格式化等功能。如果没有这个标签,即使有组件扫描,控制器可能也无法正确处理请求。
1.3@RequestMapping
是 Spring MVC 中最核心的注解之一,用于将 HTTP 请求映射到对应的控制器方法。
1.4<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/书城?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>
这部分内容是在创建一个驱动管理数据源类,将jdbc中的等必要连接配置进行定义。
1.5 </bean> <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <!-- 起别名,对应路径类的小写即为别名(规定如此)--> <property name="typeAliasesPackage" value="com.hxy.pojo"></property> <property name="configLocation" value="classpath:mybatis.xml"></property> </bean>
-
**
dataSource
**
注入数据源 Bean(dataSource
),用于连接数据库。 -
**
typeAliasesPackage
**
自动扫描com.hxy.pojo
包下的 POJO 类,并为它们注册 MyBatis 类型别名。- 默认别名规则:类名首字母小写(例如
Book
→book
)。 - 在 XML 映射文件中可直接使用别名:
resultType="book"
。
- 默认别名规则:类名首字母小写(例如
-
**
configLocation
**
指定 MyBatis 全局配置文件mybatis.xml
的位置(如日志实现、驼峰映射等配置)。
1.6<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="factory"></property> <property name="basePackage" value="com.hxy.mapper"></property> </bean>
-
**
sqlSessionFactoryBeanName
**
关联之前定义的SqlSessionFactoryBean
(id="factory"
),确保 Mapper 接口使用正确的数据库会话工厂。 -
**
basePackage
**
自动扫描com.hxy.mapper
包下的所有 Mapper 接口,并将它们注册为 Spring Bean。- 接口无需手动实现,MyBatis 会动态生成代理类。
2.配置springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <context:component-scan base-package="com"></context:component-scan> <mvc:annotation-driven></mvc:annotation-driven> </beans>
2.1<context:component-scan base-package="com">
-
作用:
自动扫描com
包及其子包下所有标注了 Spring 注解的类,并将它们注册为 Spring Bean。- 支持的注解:
@Controller
:标识控制器类(处理 HTTP 请求)。@Service
:标识业务逻辑层组件。@Repository
:标识数据访问层组件(如 DAO)。@Component
:通用组件注解(非 MVC 层组件)。
- 支持的注解:
-
意义:
替代手动在 XML 中配置<bean>
标签,简化开发。
2.2<mvc:annotation-driven>
-
作用:
启用 Spring MVC 的注解驱动功能,使以下注解生效:@RequestMapping
:将 HTTP 请求映射到控制器方法。@RequestBody
/@ResponseBody
:处理 JSON/XML 数据绑定。@PathVariable
:从 URL 路径中提取参数。@Valid
:启用数据校验(需配合 JSR-303 实现如 Hibernate Validator)。@ModelAttribute
:绑定请求参数到模型对象。
-
隐含配置:
自动注册以下关键组件:RequestMappingHandlerMapping
:解析请求映射到控制器方法。RequestMappingHandlerAdapter
:执行控制器方法并处理参数绑定。HttpMessageConverter
:处理消息转换(如 JSON ↔ Java 对象)。
上述内容中的@RequestMapping的作用:
请求处理流程
当在浏览器中输入 URL(如 http://localhost:8080/sel
)时,Spring MVC 的工作流程如下:
-
请求到达
DispatcherServlet
DispatcherServlet
(前端控制器)拦截所有 HTTP 请求,并负责协调请求处理。 -
查找匹配的控制器方法
DispatcherServlet
通过HandlerMapping
查找与请求路径匹配的控制器方法。- 如果方法标注了
@RequestMapping("/sel")
,则路径/sel
的请求会匹配到该方法。
- 如果方法标注了
-
执行控制器方法
匹配成功后,Spring 会调用该方法,执行业务逻辑(如查询数据库、处理数据等)。 -
返回响应
方法返回的字符串(如"index.jsp"
)会被ViewResolver
解析为具体的视图(如 JSP 页面),最终由浏览器渲染。
3.mybatis中的mapper配置文件
<?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.hxy.mapper.BookMapper"> <select id="sellectAll" resultType="book"> select * from book </select> </mapper> 上述命名空间指向自行创建的接口,返回类型为Book的别名book(这部分在spring与mybatis的整合文件中定义)。
4.定义Book类,对应数据库内容
package com.hxy.pojo; public class Book { int id; String name; String author; Double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public Book(int id, String name, String author, Double price) { this.id = id; this.name = name; this.author = author; this.price = price; } public Book() { } }
5.数据库连接层
5.1接口BookMapper
package com.hxy.mapper; import java.util.List; public interface BookMapper { List sellectAll(); }
5.2BookMapper在mybatis中使用mapper进行映射创建实现类(BookMapper.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.hxy.mapper.BookMapper"> <select id="sellectAll" resultType="book"> select * from book </select> </mapper>
6.业务层:用于接受数据库连接层数据并传递给控制层
6.1业务接口
package com.hxy.service; import java.util.List; public interface BookService { List selectALL(); }
6.2业务接口实现类:
package com.hxy.service.impl; import com.hxy.mapper.BookMapper; import com.hxy.pojo.Book; import com.hxy.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; @Service public class BookServiceimpl implements BookService { @Autowired private BookMapper bookMapper; @Override public List selectALL() { return bookMapper.sellectAll(); } }
7.控制层:接收业务层传递数据,并使用web进行显示
package com.hxy.controller; import com.hxy.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; @org.springframework.stereotype.Controller public class Controller { @Autowired BookService bookService; @RequestMapping("/sel") public String findAll() { List list = bookService.selectALL(); System.out.println(list.size()); return("index.jsp"); } }