本文介绍在idea中使用Maven搭建SSM框架,实现对一个学生实体类的CRUD操作。
运行环境:MySQL 8.0.21 + JDK 11 + idea 2020
框架版本:Spring 5.2.7.RELEASE + MyBatis 3.5.4
构建工具:Maven 3.6.2
文章目录
- 项目结构一览
- 1 创建工程骨架
- 2 完善工程
- 2.1 创建三层架构
- 2.2 创建配置文件
- 2.2.1 数据库配置文件resources/config/jdbcConfig.properties
- 2.2.2 Spring配置文件resources/config/applicationContext.xml
- 2.2.3 日志文件resources/config/log4j.properties(这个可不加)
- 2.2.4 mybatis配置文件resources/config/mybatis-config.xml
- 2.2.5 SpringMVC配置文件resources/config/springmvc.xml
- 2.2.6 映射文件resources/mapper/StudentMapper.xml
- 2.2.7 全局配置文件webapp/WEB-INF/web.xml
- 3 运行测试
- 4 junit测试CRUD
项目结构一览
G:\PROGRAMFILES\WORKSPACE\IDEA\SSM-DEMO\SRC
├───main
│ ├───java
│ │ └───com
│ │ └───fanyi
│ │ ├───controller
│ │ │ HelloController.java
│ │ │ StudentController.java
│ │ │
│ │ ├───dao
│ │ │ StudentMapper.java
│ │ │
│ │ ├───domain
│ │ │ Student.java
│ │ │
│ │ └───service
│ │ │ StudentService.java
│ │ │
│ │ └───impl
│ │ StudentServiceImpl.java
│ │
│ ├───resources
│ │ ├───config
│ │ │ applicationContext.xml
│ │ │ jdbcConfig.properties
│ │ │ log4j.properties
│ │ │ mybatis-config.xml
│ │ │ springmvc.xml
│ │ │
│ │ └───mapper
│ │ StudentMapper.xml
│ │
│ └───webapp
│ │ index.jsp
│ │
│ └───WEB-INF
│ │ web.xml
│ │
│ └───pages
│ │ welcome.jsp
│ │
│ └───students
│ findAll.jsp
│
└───test
└───java
└───com
└───fanyi
├───dao
│ StudentMapperTest.java
│
└───service
StudentServiceTest.java
1 创建工程骨架
1.1 使用maven的webapp模板创建一个web项目
创建项目时选择maven,勾选webapp模板即可
1.2 在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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>ssm-demo</name>
<groupId>org.example</groupId>
<artifactId>ssm-demo</artifactId>
<version>${spring.version}1.0-SNAPSHOT</version>
<properties>
<!-- 框架版本信息 -->
<spring.version>5.2.7.RELEASE</spring.version>
<mybatis.version>3.5.4</mybatis.version>
<slf4j.version>1.7.30</slf4j.version>
<log4j2.version>2.13.3</log4j2.version>
<mysql.version>8.0.20</mysql.version>
<!-- 编码类型 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- JDK版本信息 -->
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!--spring-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring-mvc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!--servlet & jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--log-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!--引入slf4j-nop,解决如下问题-->
<!--SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".-->
<!--SLF4J: Defaulting to no-operation (NOP) logger implementation-->
<!--SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.6.4</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
</project>
1.3 创建/src/test、/src/main/java目录
/src/test:用户后续测试使用。鼠标放在test目录,单击右键,Mark Directory as →Test Sources Root
/src/main/java:存放项目源代码。鼠标放在java目录,单击右键,Mark Directory as →Sources Root
……
项目中若缺少其它文件夹,设置方式类似
1.4 创建数据库、添加表
-- MySQL dump 10.13 Distrib 8.0.21, for Win64 (x86_64)
--
-- Host: localhost Database: spring
-- ------------------------------------------------------
-- Server version 8.0.21
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Current Database: `spring`
--
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `spring` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `spring`;
--
-- Table structure for table `t_student`
--
DROP TABLE IF EXISTS `t_student`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `t_student` (
`id` int NOT NULL AUTO_INCREMENT,
`stu_name` varchar(30) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`stu_address` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `t_student`
--
LOCK TABLES `t_student` WRITE;
/*!40000 ALTER TABLE `t_student` DISABLE KEYS */;
INSERT INTO `t_student` VALUES (1,'tom','f','shanghai'),(3,'lisa','m','tianjin'),(4,'george','f','hunan');
/*!40000 ALTER TABLE `t_student` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2020-08-21 16:06:39
2 完善工程
2.1 创建三层架构
先创建一个com.xxx
包,再创建包domain、controller、service、service.impl、dao
2.1.1 实体类domain/Student.java
public class Student implements Serializable {
private int id;
private String stuName;
private char sex;
private String stuAddress;
// 省略getter、setter、toString方法
}
2.1.2 业务层
2.1.2.1 service/StudentService.java
public interface StudentService {
/**
* 查询所有学生
*
* @return
*/
List<Student> findAll();
/**
* 插入一条学生信息
*
* @param student
*/
void insert(Student student);
/**
* 更新一条学生信息
*
* @param student
*/
void update(Student student);
/**
* 根据学生id查询一条学生信息
*
* @param id
*/
Student selectById(int id);
/**
* 根据学生id删除一条学生信息
*
* @param stuId
*/
void deleteById(int stuId);
}
2.1.2.2 service/impl/StudentServiceImpl.java
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> findAll() {
return studentMapper.findAll();
}
@Override
public void insert(Student student) {
studentMapper.insert(student);
}
@Override
public void update(Student student) {
studentMapper.update(student);
}
@Override
public Student selectById(int id) {
return studentMapper.selectById(id);
}
@Override
public void deleteById(int stuId) {
studentMapper.deleteById(stuId);
}
}
2.1.2.3 controller/StudentController.java
@Controller
@RequestMapping(value = "/student")
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping(value = "/findAll")
public ModelAndView findAll(){
List<Student> students = studentService.findAll();
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("students", students);
modelAndView.setViewName("students/findAll");
return modelAndView;
}
}
2.1.3 持久层dao/StudentMapper.java
// @Repository
public interface StudentMapper {
/**
* 查询所有学生
*
* @return
*/
List<Student> findAll();
/**
* 插入一条学生信息
*
* @param student
*/
void insert(Student student);
/**
* 更新一条学生信息
*
* @param student
*/
void update(Student student);
/**
* 根据学生id查询一条学生信息
*
* @param id
*/
Student selectById(int id);
/**
* 根据学生id删除一条学生信息
*
* @param stuId
*/
void deleteById(int stuId);
}
2.1.4 表现层
2.1.4.1 webapp/index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
Hello
</body>
</html>
2.1.4.2 webapp/WEB-INF/pages/students/findAll.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>查看所有学生</title>
</head>
<body>
<table border="1px solid black" cellspacing="0">
<c:forEach var="stu" items="${students}">
<tr>
<td>${stu.id}</td>
<td>${stu.stuName}</td>
<td>${stu.sex}</td>
<td>${stu.stuAddress}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
2.2 创建配置文件
2.2.1 数据库配置文件resources/config/jdbcConfig.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true
jdbc.username=xxx
jdbc.password=xxx
2.2.2 Spring配置文件resources/config/applicationContext.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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd">
<!--扫描service层的类-->
<context:component-scan base-package="com.fanyi.service"/>
<!--加载数据库配置文件-->
<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="locations" value="classpath:config/jdbcConfig.properties"/>
</bean>
<!--druid数据库连接池-->
<bean id="druidDataSource" 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>
<!--配置mybaits的SqlSessionFactoryBean-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"/>
<property name="configLocation" value="classpath:config/mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!--使用mybaits接口代理开发模式-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--扫描dao接口所在的包-->
<property name="basePackage" value="com.fanyi.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
2.2.3 日志文件resources/config/log4j.properties(这个可不加)
log4j.rootLogger=debug,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.Java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
2.2.4 mybatis配置文件resources/config/mybatis-config.xml
<?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>
<properties resource="config/jdbcConfig.properties">
<!--<property name="password" value="F2Fa3!33TYyg"/>-->
</properties>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
2.2.5 SpringMVC配置文件resources/config/springmvc.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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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">
<!--开启注解扫描,扫描controller层-->
<context:component-scan base-package="com.fanyi.controller"/>
<!--视图解析器-->
<bean id="internalVeiwResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--mvc注解支持-->
<mvc:annotation-driven/>
</beans>
2.2.6 映射文件resources/mapper/StudentMapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fanyi.dao.StudentMapper">
<select id="findAll" resultType="com.fanyi.domain.Student">
select * from t_student
</select>
<select id="selectById" parameterType="int" resultType="com.fanyi.domain.Student">
select * from t_student where id = #{id}
</select>
<insert id="insert" parameterType="com.fanyi.domain.Student"
useGeneratedKeys="true" keyProperty="id">
insert into t_student(stu_name, sex, stu_address) values(#{stuName}, #{sex}, #{stuAddress})
</insert>
<update id="update" parameterType="com.fanyi.domain.Student">
update t_student set
stu_name = #{stuName},
sex = #{sex},
stu_address = #{stuAddress}
where id = #{id}
</update>
<delete id="deleteById" parameterType="int">
delete from t_student where id = #{id}
</delete>
</mapper>
2.2.7 全局配置文件webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--配置监听器,加载/WEB-INF目录下的配置文件-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--加载applicationContext.xml-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/config/applicationContext.xml</param-value>
</context-param>
<!--log4j2-->
<context-param>
<param-name>log4jConfigurationLocation</param-name>
<param-value>classpath:/config/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshIntervel</param-name>
<param-value>60000</param-value>
</context-param>
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<!--解决post请求中文乱码的过滤器-->
<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>
<!--配置前端控制器DispatcherServlet-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置初始化参数,创建完DispatcherServlet对象,加载springmvc.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/config/springmvc.xml</param-value>
</init-param>
<!--服务器启动的时候,让DispatcherServlet对象创建-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3 运行测试
将项目部署到tomcat,启动tomcat,浏览器地址栏输入如图所示url
4 junit测试CRUD
src\test\java\com\fanyi\service\StudentServiceTest.java
运行相应的测试方法即可
package com.fanyi.service;
import com.fanyi.domain.Student;
import com.fanyi.service.impl.StudentServiceImpl;
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;
import java.util.List;
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:config/applicationContext.xml"})
public class StudentServiceTest {
@Autowired
private StudentService studentService;
@Test
public void findAll() {
List<Student> list = studentService.findAll();
for (Student li : list) {
System.out.println(li);
}
}
@Test
public void insert() {
Student student = new Student();
student.setStuAddress("BeiJing");
student.setSex('f');
student.setStuName("tom");
studentService.insert(student);
}
@Test
public void update() {
Student s = studentService.selectById(5);
s.setStuName("update name");
// 执行此句报错,加上useSSL=false
studentService.update(s);
}
@Test
public void selectById() {
System.out.println(studentService.selectById(3));
}
@Test
public void deleteById() {
studentService.deleteById(5);
}
}