项目初始搭建
项目结构:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>SSM</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--Spring事务管理-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--Spring MVC的相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!--MyBatis相关依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--MyBatis与Spring整合相关依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.1</version>
</dependency>
<!--数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
<!--单元测试相关的依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 相关的依赖-->
<!--ServletAPI:引入servlet的功能-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!--ServletAPI: jsp页面的功能包 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- 数据库驱动相关依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
创建实体类
Book.java
package com.itheima.domain;
public class Book {
private Integer id;
private String name;
private String press;
private String author;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPress() {
return press;
}
public void setPress(String press) {
this.press = press;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
创建持久层接口
BookMapper.java
package com.itheima.dao;
import com.itheima.domain.Book;
public interface BookMapper {
public Book findBookById(Integer id);
}
创建持久层映射文件
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.itheima.domain.Book">
<select id="findBookById" parameterType="int"
resultType="com.itheima.domain.Book">
select * from tb_book where id = #{id}
</select>
</mapper>
创建业务层接口
BookService.java
package com.itheima.service;
import com.itheima.domain.Book;
public interface BookService {
public Book findBookById(Integer id);
}
创建业务层实现类
BookServiceImpl.java
package com.itheima.service.impl;
import com.itheima.dao.BookMapper;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookMapper bookMapper;
public Book findBookById(Integer id) {
return bookMapper.findBookById(id);
}
}
创建业务层的控制层
BookController.java
package com.itheima.controller;
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class BookController {
@Autowired
private BookService bookService;
@RequestMapping("/book")
public ModelAndView findBookById(Integer id) {
Book book = bookService.findBookById(id);
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("book.jsp");
modelAndView.addObject("book", book);
return modelAndView;
}
}
Spring和Mybatis整合
搭建Spring环境
Spring配置文件
application-service.xml
<?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:context="<http://www.springframework.org/schema/context>"
xsi:schemaLocation="
<http://www.springframework.org/schema/beans>
<http://www.springframework.org/schema/beans/spring-beans.xsd>
<http://www.springframework.org/schema/context>
<http://www.springframework.org/schema/context/spring-context.xsd>
">
<!--开启注解扫描, 扫描包-->
<context:component-scan base-package="com.itheima.service"/>
</beans>
Spring和Mybatis整合的配置
jdbc.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true\\
&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
applicaiton-dao.xml
<?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:context="<http://www.springframework.org/schema/context>"
xsi:schemaLocation="
<http://www.springframework.org/schema/beans>
<http://www.springframework.org/schema/beans/spring-beans.xsd>
<http://www.springframework.org/schema/context>
<http://www.springframework.org/schema/context/spring-context.xsd>
">
<!--引入属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!--创建SqlSessionFactory对象-->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!--数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--扫描Dao包,创建动态代理对象, 会自动存储到spring IOC容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定要扫描的dao的包-->
<property name="basePackage" value="com.itheima.dao"/>
</bean>
</beans>
测试
BookServiceTest.java
import com.itheima.domain.Book;
import com.itheima.service.BookService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-service.xml", "classpath:application-dao.xml"})
public class BookServerTest {
@Autowired
private BookService bookService;
@Test
public void findBookById() {
Book book = bookService.findBookById(1);
System.out.println("图书id:" + book.getId());
System.out.println("图书名称:" + book.getName());
System.out.println("作者:" + book.getAuthor());
System.out.println("出版社:" + book.getPress());
}
}
@RunWith(SpringJUnit4ClassRunner.class)
:这是一个JUnit注解,用于指定测试运行器。在这里,它指定了使用SpringJUnit4ClassRunner作为测试运行器。SpringJUnit4ClassRunner是Spring TestContext Framework的一部分,它负责在测试开始时加载Spring应用程序上下文,并在测试结束时关闭上下文。这样,我们就可以在测试中使用Spring的功能,如依赖注入等。@ContextConfiguration(locations = {"classpath:application-service.xml", "classpath:application-dao.xml"})
:这是一个Spring注解,用于指定配置文件的位置。在这里,它指定了两个配置文件:application-service.xml和application-dao.xml。这两个文件通常包含了Spring应用程序的配置信息,如bean的定义、数据源配置等。通过这个注解,我们可以告诉Spring在运行测试时加载这些配置文件,以便正确地初始化应用程序上下文。
Spring和Spring MVC整合
Spring的配置
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"<http://java.sun.com/dtd/web-app_2_3.dtd>" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!--配置文件加载-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-*.xml</param-value>
</context-param>
<!--容器加载的监听器-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!--Spring MVC 前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--初始化参数-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--项目启动时候,初始化前端控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring MVC配置
spring-mvc.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>
<http://www.springframework.org/schema/beans/spring-beans.xsd>
<http://www.springframework.org/schema/mvc>
<http://www.springframework.org/schema/mvc/spring-mvc.xsd>
<http://www.springframework.org/schema/context>
<http://www.springframework.org/schema/context/spring-context.xsd>">
<!-- 配置要扫描的包 -->
<context:component-scan base-package="com.itheima.controller"/>
<!-- 配置注解驱动 -->
<mvc:annotation-driven/>
</beans>
测试
book.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head><title>图书信息查询</title></head>
<body>
<table border="1">
<tr>
<th>图书id</th>
<th>图书名称</th>
<th>出版社</th>
<th>作者</th>
</tr>
<tr>
<td>${book.id}</td>
<td>${book.name}</td>
<td>${book.press}</td>
<td>${book.author}</td>
</tr>
</table>
</body>
</html>
访问
纯注解方式整合SSM框架
创建JdbcConfig类
package com.itheima.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/*
等同于
<context:property-placeholder location="classpath*:jdbc.properties"/>
*/
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
/*
使用注入的形式,读取properties文件中的属性值,
等同于<property name="*******" value="${jdbc.driver}"/>
*/
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
/*定义dataSource的bean, 等同于
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
*/
@Bean("dataSource")
public DataSource getDataSource() {
//创建对象
DruidDataSource ds = new DruidDataSource();
/*
等同于set属性注入<property name="driverClassName" value="driver"/>
*/
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
创建MyBatisConfig类
package com.itheima.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MyBatisConfig {
/*
定义MyBatis的核心连接工厂bean,
等同于<bean class="org.mybatis.spring.SqlSessionFactoryBean">
参数使用自动装配的形式加载dataSource,
为set注入提供数据源,dataSource来源于JdbcConfig中的配置
*/
@Bean
public SqlSessionFactoryBean getSqlSessionFactoryBean(
@Autowired DataSource dataSource) {
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//等同于<property name="dataSource" ref="dataSource"/>
ssfb.setDataSource(dataSource);
return ssfb;
}
/*
定义MyBatis的映射扫描,
等同于<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
*/
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//等同于<property name="basePackage" value="com.itheima.dao"/>
msc.setBasePackage("com.itheima.dao");
return msc;
}
}
创建SpringConfig类
相当于application-service.xml的作用
package com.itheima.config;
import org.springframework.context.annotation.*;
@Configuration
@Import({MyBatisConfig.class, JdbcConfig.class})
/*
等同于<context:component-scan base-package="com.itheima.service">
*/
@ComponentScan(value = "com.itheima.service")
/*
将MyBatisConfig类和JdbcConfig类交给Spring管理
*/
public class SpringConfig {
}
创建SpringMvcConxfig类
向当于spring-mvc.xml的作用
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
//等同于<context:component-scan base-package="com.itheima.controller"/>
@ComponentScan("com.itheima.controller")
//等同于<mvc:annotation-driven/>,还不完全相同
@EnableWebMvc
public class SpringMvcConfig {
}
创建ServletContainerslnitConfig类
相当于web.xml的作用
package com.itheima.config;
import org.springframework.web.servlet.support.
AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
/*
加载Spring配置类中的信息,
初始化Spring容器
*/
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/*
加载Spring MVC配置类中的信息,
初始化Spring MVC容器
*/
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//配置DispatcherServlet的映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
}