本文详细介绍了SSM框架的组成及其功能,包括Spring、Spring MVC和MyBatis三个核心部分,并探讨了SSM框架在企业级应用开发中的应用场景和优势。此外,文章提供了SSM框架的环境搭建、基础配置详解以及实战项目案例,帮助读者更好地理解和使用SSM资料。
SSM框架简介SSM框架是Spring、Spring MVC和MyBatis三个框架的整合。Spring是一个轻量级的企业级开发框架,提供了IoC(控制反转)和AOP(面向切面编程)等功能;Spring MVC是一个基于Spring的Web MVC框架,用于构建Web应用;MyBatis是一个持久层框架,用于操作数据库。这三个框架结合在一起可以快速搭建企业级应用。
jdk-8u291-linux-x64.tar.gz
JAVA_HOME=/usr/local/java/jdk1.8.0_291 PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME PATH
maven-3.6.3-bin.tar.gz
MAVEN_HOME=/usr/local/apache-maven-3.6.3 PATH=$MAVEN_HOME/bin:$PATH export MAVEN_HOME PATH
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.10</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> </dependencies>
Spring配置文件:主要用于配置Spring的IoC容器,定义Bean的生命周期等。
<beans xmlns="http://www.springframework.org/schema/beans" 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"> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <!-- 配置SqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置Mapper扫描 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.mapper"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置事务管理器 --> <tx:annotation-driven transaction-manager="transactionManager"/> </beans>
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
Spring MVC配置文件:主要用于配置前端控制器、处理器映射器、处理器适配器、视图解析器等。
<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" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 启用注解驱动 --> <mvc:annotation-driven/> <!-- 扫描控制器 --> <context:component-scan base-package="com.example.controller"/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
数据库连接配置:在Spring配置文件中配置数据源。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean>
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
控制器层:定义处理Web请求的控制器。
package com.example.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.example.service.UserService; @Controller @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping("/list") public String listUsers(Model model) { model.addAttribute("users", userService.getAllUsers()); return "users/list"; } }
服务层:定义业务逻辑处理类。
package com.example.service; import java.util.List; import com.example.model.User; import com.example.repository.UserRepository; public class UserService { private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public List<User> getAllUsers() { return userRepository.findAll(); } }
DAO层:定义数据访问对象。
package com.example.repository; import java.util.List; import com.example.model.User; public interface UserRepository { List<User> findAll(); }
项目结构:
src/main/java
:存放Java源代码。src/main/resources
:存放资源文件,如Spring配置文件、MyBatis映射文件等。src/main/webapp
:存放Web应用的资源文件,如JSP、CSS、JavaScript等。pom.xml
:Maven项目配置文件。web.xml
:Web应用配置文件。CREATE TABLE user ( id INT PRIMARY KEY, username VARCHAR(50), password VARCHAR(50), email VARCHAR(50) );
添加用户:
package com.example.service; import java.util.List; import com.example.model.User; import com.example.repository.UserRepository; public class UserService { private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void insertUser(User user) { userRepository.save(user); } }
删除用户:
public void deleteUser(int id) { userRepository.delete(id); }
更新用户:
public void updateUser(User user) { userRepository.update(user); }
public List<User> getAllUsers() { return userRepository.findAll(); }
创建分页工具类:
package com.example.utils; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import java.util.List; public class PageUtil { public static <T> Page<T> getPage(List<T> content, int page, int size) { return new PageImpl<>(content, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "id")), content.size()); } }
在DAO层实现分页查询:
package com.example.repository; import java.util.List; import com.example.model.User; public interface UserRepository { List<User> findAll(); Page<User> findAll(Pageable pageable); }
在服务层调用分页查询:
package com.example.service; import java.util.List; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import com.example.model.User; import com.example.repository.UserRepository; @Service public class UserService { @Autowired private UserRepository userRepository; public Page<User> getAllUsers(int page, int size) { return userRepository.findAll(PageRequest.of(page, size)); } }
全局异常处理:
package com.example.controller; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) @ResponseBody public ResponseEntity<String> handleException(Exception ex) { return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } }
日志记录:
package com.example.service; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.example.repository.UserRepository; public class UserService { private final Logger logger = LoggerFactory.getLogger(UserService.class); private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public void insertUser(User user) { logger.info("Inserting user: {}", user); userRepository.save(user); } }
@Controller
和@RequestMapping
注解标注,并检查URL映射是否匹配。问题:如何在Spring中注入事务管理?
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional public void someTransactionalMethod() { // 业务逻辑 }
问题:MyBatis如何实现动态SQL?
<if>
、<choose>
等。
<select id="selectUserById" resultType="User"> SELECT * FROM user <where> <if test="id != null"> AND id = #{id} </if> <if test="username != null"> AND username = #{username} </if> </where> </select>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
@PostMapping("/upload") public String handleFileUpload(@RequestParam("file") MultipartFile file) { if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); Path path = Paths.get("upload/" + file.getOriginalFilename()); Files.write(path, bytes); } catch (IOException e) { e.printStackTrace(); } } return "uploadSuccess"; }
<cache-refresher class="com.example.cache.MyCacheRefresher"/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="userCache"/> </set> </property> </bean>
@Cacheable(value = "userCache") public User getUserById(int id) { // 业务逻辑 }
集成JWT:
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
public String generateToken(User user) { String token = Jwts.builder() .setSubject(user.getUsername()) .claim("userId", user.getId()) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)) .signWith(SignatureAlgorithm.HS256, secret) .compact(); return token; }
public User parseToken(String token) { Claims claims = Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); int userId = claims.get("userId", Integer.class); return userService.getUserById(userId); }
集成Redis:
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.5.4</version> </dependency>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host="localhost" p:port="6379"/> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> </bean>
@Autowired private RedisTemplate<String, String> redisTemplate;
public void setCache(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
public String getCache(String key) {
return redisTemplate.opsForValue().get(key);
}
推荐书籍、博客和在线课程
开源项目参考