08-SSM
1. 准备BD
-- auto-generated definition
create table mvc_user
(
uid int not null primary key,
uname varchar(255) null,
password varchar(255) null
);
2. 创建maven_web
- 补充项目结构,准备好MVC模式下的主要目录
3. web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
</web-app>
4. 导入依赖
<dependencies>
<!-- Spring核心容器包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.19</version>
</dependency>
<!-- Spring切面包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.5</version>
</dependency>
<!-- aop联盟包 -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- SpringJDBC包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.5</version>
</dependency>
<!-- Spring事务控制包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.5</version>
</dependency>
<!-- Spring-orm映射依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.3.5</version>
</dependency>
<!-- Apache Commons日志包 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- log4j2日志 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.5</version>
<scope>test</scope>
</dependency>
<!-- junit5单元测试 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
<scope>test</scope>
</dependency>
<!-- SpringMVC支持包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.5</version>
</dependency>
<!-- servlet、jsp依赖 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- json依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.0-rc1</version>
</dependency>
<!-- mybatis 核心jar包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- Spring mybatis整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- 文件上传依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.8.0</version>
</dependency>
<!-- 跨服务文件上传依赖 -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19</version>
</dependency>
</dependencies>
5. 配置文件
1. log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<!-- SYSTEM_ERR红色,OUT应该是黑色 -->
<Console name="Console" target="SYSTEM_ERR">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
<!-- <scope>注释,不然只对单元测试生效 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.14.0</version>
<!--<scope>test</scope>-->
</dependency>
2. jdbc.properties
jdbc_driver=com.mysql.cj.jdbc.Driver
jdbc_url=jdbc:mysql://ip:port/mca?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc_username=******
jdbc_password=******
3. web.xml
- 请求域
Request
- 会话域
Session
- 应用域
Application
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- Spring配置 -->
<!-- ServletContext中添加Spring核心配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application_context.xml</param-value>
</context-param>
<!-- 监听器,JAVAWEB项目中的ServletContext创建时,创建一个Spring的容器,放入ServletContext对象中 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- SpringMVC配置 -->
<!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数,读取SpringMVC的核心配置文件 -->
<!-- 不使用`<init-param>`,默认路径:/WEB-INF/<servlet-name>-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring_mvc.xml</param-value>
</init-param>
<!-- 启动立即初始化servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 映射路径为
/:匹配所有资源,JSP除外
/*:全部servlet + JSP
-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- SpringMVC提供字符编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- POST转换为PUT、DELETE -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
4. spring_mvc.xml
<!-- 扫描controller -->
<context:component-scan base-package="com.listao.mvc.controller"></context:component-scan>
<!-- 三大组件 -->
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>
5. applicationContext.xml
Spring整合MyBatis思路,目的在于Service层注入Mapper对象,Mapper对象由MyBatis生成
- SqlSessionFactory
- SqlSession
UserMapper userMapper = sqlSession.getMapper(UserMapper.class)
SqlsessionFactory, Sqlsession, ***Mapper
全部交给Spring去创建
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!-- 加载properties配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 扫描service层 -->
<context:component-scan base-package="com.listao.mvc.service"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc_driver}"/>
<property name="url" value="${jdbc_url}"/>
<property name="username" value="${jdbc_username}"/>
<property name="password" value="${jdbc_password}"/>
</bean>
<!-- SqlSessionFactoryBean -->
<bean id="sqlSessionFB" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 实体类别名包扫描 -->
<property name="typeAliasesPackage" value="com.listao.mvc.pojo"/>
</bean>
<!-- sqlSession ==>> ***Mapper -->
<!-- MapperScanner mapper扫描仪 生成所有的Mapper对象并放入容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入factory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFB"/>
<!-- 扫描所有的mapper接口、映射文件 -->
<property name="basePackage" value="com.listao.mvc.mapper"/>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
6. login业务
1. jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>login.jsp</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="uname">
<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success.jsp</title>
</head>
<body>
登录成功
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>fail.jsp</title>
</head>
<body>
登录失败
</body>
</html>
2. ctl + service
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
private Integer uid;
private String uname;
private String password;
}
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/login")
public String login(String uname, String password) {
String view;
User user = userService.selUser(uname, password);
if (user != null) {
view = "/success.jsp";
} else {
view = "/fail.jsp";
}
return view;
}
@ResponseBody
@RequestMapping("/selAllUser")
public List<User> selAllUser() {
return userService.selAllUser();
}
}
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public User selUser(String uname, String password) {
return userMapper.selUser(uname, password);
}
@Override
public List<User> selAllUser() {
return userMapper.selAllUser();
}
}
public interface UserMapper {
User selUser(String uname, String password);
List<User> selAllUser();
}
3. mapper
- MyBatis官方文档
resources/com/listao/mvc/mapper
必须为目录且和mapper接口目录层级一致。target
会编译在一起- 目录名可能为
com.listao.mvc.mapper
- 目录名可能为
Type Exception Report
Message Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.listao.mvc.mapper.UserMapper.selAllUser
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.listao.mvc.mapper.UserMapper.selAllUser
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
javax.servlet.http.HttpServlet.service(HttpServlet.java:529)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:94)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
Root Cause
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.listao.mvc.mapper.UserMapper.selAllUser
org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
org.apache.ibatis.binding.MapperProxy.lambda$cachedInvoker$0(MapperProxy.java:115)
java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
org.apache.ibatis.binding.MapperProxy.cachedInvoker(MapperProxy.java:102)
org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:85)
com.sun.proxy.$Proxy36.selAllUser(Unknown Source)
<?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.listao.mvc.mapper.UserMapper">
<select id="selUser" resultType="user">
select *
from mvc_user
where uname = #{param1}
and password = #{param2}
</select>
<select id="selAllUser" resultType="user">
select *
from mvc_user
</select>
</mapper>
4. junit
package com.listao.mvc.test;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@SpringJUnitConfig(locations = "classpath:application_context.xml")
public class TestUser {
@Autowired
private UserService userService;
@Test
public void login(){
User user = userService.selUser("1", "1");
System.out.println("user = " + user);
}
}