整合SSM框架、快速开发CRUD项目
本文学习内容来自尚硅谷的视频 尚硅谷SSM实战演练丨ssm整合快速开发CRUD_哔哩哔哩_bilibili
项目概述
实现员工、部门管理后台,可以对员工进行增删改查等操作
功能点
- 分页
- 数据校验
- ajax
- Rest风格的URI,使用HTTP协议请求方式,来表示对资源的操作,GET(查询),POST(新增),PUT(修改),DELETE(删除)
技术点
- 基础框架-ssm(Spring MVC+Spring+MyBatis)
- 数据库-MySql
- 前端框架-bootstrap
- 项目依赖管理-Maven
- 分页-pageHelper
- 逆向工程-MyBatis Generator
基础环境搭建
创建maven工程
创建maven工程就不过多介绍
引入项目依赖的jar包
先将我们能想到的jar包添加到项目中,后期如果用到再添加
- spring
- springmvc
- mybatis
- spring整合mybatis
- 数据库连接池
- 其他(servlet api、日志、junit测试)
<?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>SpringMVC_ssm</name>
<groupId>com.yellowstar.ssm</groupId>
<artifactId>SpringMVC_ssm</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--spring jdbc-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.12</version>
</dependency>
<!--spring webmvc-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.12</version>
</dependency>
<!--spring aspects-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.12</version>
</dependency>
<!-- Spring5和Thymeleaf整合包 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
<!-- 导入jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--mybatis整合spring-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- mybatis的分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
<!--mbg插件-->
<!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
<!--德鲁伊数据库连接池-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<!--mysql-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!--servlet-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!--junit-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<!--tomcat8插件-->
<pluginRepositories>
<pluginRepository>
<id>alfresco</id>
<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat8-maven-plugin</artifactId>
<version>3.0-r1655215</version>
<configuration>
<port>8080</port>
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
引入前端框架(bootstrap)
关于bootstrap直接去官网下载即可 ----------》 下载地址
bootstrap是依赖jQuery的,所以需要一并下载jQuery
使用时只需要导入依赖即可
<script src="static/js/jquery-1.12.4.min.js"></script>
<link href="static/bootstrap-3.3.7-dist/css/bootstrap.min.css" rel="stylesheet">
<script src="static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
配置web.xml文件
web.xml文件的主要作用时配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<!--启动spring容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置前端控制器-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--设置springmvc配置文件的名称和路径-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.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>
<!--字符集过滤器-->
<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>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--restful风格过滤器-->
<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>
编写springmvc配置文件springMVC.xml
springmvc用来控制请求的跳转,所以我们只扫描带有controller注解的类
<?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 http://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.yellowstar.ssm" use-default-filters="true">
<!--只扫描控制器-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--配置Thymeleaf视图解析器-->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<!--设置优先级-->
<property name="order" value="1"></property>
<property name="characterEncoding" value="utf-8"></property>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/templates/" />
<!--设置后缀-->
<property name="suffix" value=".html"/>
<property name="characterEncoding" value="utf-8"/>
<property name="templateMode" value="HTML5" />
</bean>
</property>
</bean>
</property>
</bean>
<!--将springmvc不能解析的文件交给tomcat处理-->
<mvc:default-servlet-handler/>
<!--支持spring更高级的设置-->
<mvc:annotation-driven/>
</beans>
编写spring配置文件application-context.xml
spring配置文件主要配置和业务逻辑有关的,比如数据源、与mybatis的整合、事务管理等
<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--扫描出控制器外的组件-->
<context:component-scan base-package="com.yellowstar.ssm">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--=================================数据源===================================-->
<!--引入外部文件-->
<context:property-placeholder location="classpath:jdbcConnection.properties" />
<!--创建数据库连接池对象-->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--=================================mybatis整合===================================-->
<!--整合mybatis-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定mybatis全局配置文件的位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="dataSource" ref="datasource"></property>
<!--指定mapper文件所在位置-->
<property name="mapperLocations" value="classpath:mappers/*.xml"></property>
</bean>
<!--配置扫描器,将mapper文件加入到ioc容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yellowstar.ssm.dao"></property>
</bean>
<!--配置一个可批量执行sql的sqlsession-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" ref="sessionFactory"></constructor-arg>
<constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>
<!--=================================事务控制===================================-->
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--控制数据源-->
<property name="dataSource" ref="datasource"></property>
</bean>
<!--开启基于注解的事务,使用xml配置形式的事务(必要主要的都是使用配置式)-->
<aop:config>
<!--切入点表达式-->
<aop:pointcut id="txpoint" expression="execution(* com.yellowstar.ssm.serivce..*.*(..))"/>
<!--配置事务增强-->
<aop:advisor advice-ref="txAdvisor" pointcut-ref="txpoint"></aop:advisor>
</aop:config>
<tx:advice id="txAdvisor" transaction-manager="transactionManager">
<tx:attributes>
<!-- 所有方法都是事务方法 -->
<tx:method name="*"/>
<!-- 查询方法设置为只读 -->
<tx:method name="get*" read-only="true"/>
</tx:attributes>
</tx:advice>
</beans>
创建需要的数据库表
此项目有两张表,员工表以及部门表,员工d_id和部门id作为外键相关联,让我们来看一下数据库结构
使用逆向工程生成所需要的文件
逆向工程会根据数据库表自动的帮我们生成JavaBean文件、mapper接口、mapper配置类
逆向工程配置参考小黄的另外一篇文章,这里操作是一样的 MyBatis Generator链接
执行完逆向工程操作后,我们的项目结构是这样的
修改mapper文件
逆向工程生成的查询语句大部分可以满足开发需求,但还有一小部分需要我们进行修改,比如我们查询员工的时候需要将员工对应的部门信息一并带出,这样我们就需要修改对应的文件
1.employee实体类中添加department属性,并生成对应的get,set方法
public class Employee {
private Department department;
}
2.在EmployeeMapper接口中添加两个查询方法
//查询带有部门数据的员工信息
List<Employee> selectByExampleWithDept(EmployeeExample example);
Employee selectByPrimaryKeyWithDept(Integer id);
3.在EmployeeMapper.xml文件中添加以下配置
<resultMap id="BaseResultWithDeptMap" type="com.yellowstar.ssm.bean.Employee">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="gender" jdbcType="CHAR" property="gender" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="d_id" jdbcType="INTEGER" property="dId" />
<association property="department" javaType="com.yellowstar.ssm.bean.Department">
<id column="dept_id" jdbcType="INTEGER" property="deptId"/>
<result column="dept_name" jdbcType="VARCHAR" property="deptName"/>
</association>
</resultMap>
<sql id="Base_Column_withDept_List">
e.id,e.name,e.gender,e.email,e.d_id,d.dept_id,d.dept_name
</sql>
<select id="selectByExampleWithDept" parameterType="com.yellowstar.ssm.bean.EmployeeExample" resultMap="BaseResultWithDeptMap">
select
<if test="distinct">
distinct
</if>
<include refid="Base_Column_withDept_List" />
from tbl_emp e
left join tbl_dept d
on d.dept_id = e.d_id
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null">
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKeyWithDept" parameterType="java.lang.Integer" resultMap="BaseResultWithDeptMap">
select
<include refid="Base_Column_withDept_List" />
from tbl_emp e
left join tbl_dept d
on d.dept_id = e.d_id
where id = #{id,jdbcType=INTEGER}
</select>
测试环境
基础环境搭建好之后,我们需要对环境进行测试,这里我们使用spring的测试类测试,这样极大程度符合我们实际开发的写法
需要在maven依赖管理中导入以下配置
<!--spring test 测试包-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.12</version>
</dependency>
创建测试类进行测试,spring test配置如下
-
导入spring test
-
ContextConfiguration指定spring配置文件的路径
-
RunWith告诉使用springJunit4来测试
/**
* 推荐spring项目测试,使用spring的测试方法
* 1.导入spring test
* 2.ContextConfiguration指定spring配置文件的路径
* 3.RunWith告诉使用springJunit4来测试
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:application-context.xml"})
public class MapperTest {
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
private DepartmentMapper departmentMapper;
@Autowired
private SqlSession sqlSession;
@Test
public void test01(){
// departmentMapper.insertSelective(new Department("开发部"));
// departmentMapper.insertSelective(new Department("测试部"));
// employeeMapper.insertSelective(new Employee("Tom","F","Tom@123.com",1));
// employeeMapper.insertSelective(new Employee("Jerry","M","Jerry@123.com",1));
for (int i = 0; i < 1000; i++) {
String name = UUID.randomUUID().toString().substring(0,5);
employeeMapper.insertSelective(new Employee(name,"M",name + "@123.com",1));
}
System.out.println("批量插入完成");
}
}