SSM基本整合
文章目录
本文介绍
本文是基于spring,spring mvc,mybatis框架整合,适合已经学习完ssm框架的java开发人员
项目搭建
- 创建缺省包
Maven依赖
-
pom.xml依赖
<dependencies> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> <!--数据库连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.12</version> </dependency> <!--mybatis--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency> <!--mybatis对spring框架集成--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> <!--mybatis分页助手--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.3.2</version> </dependency> <!--spring框架依赖--> <!-- spring-webmvc 因为已经传递依赖的原因,所有只需要导入webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.23</version> </dependency> <!--aop--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.23</version> </dependency> <!--spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.23</version> </dependency> <!--spring-test spring继承Junit--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.23</version> </dependency> <!--servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--工具--> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <!--集成测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <!--json转换--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.4.2</version> </dependency> </dependencies>
配置文件详解
-
spring核心配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--加载数据库配置文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--扫描service包--> <context:component-scan base-package="com.xmh.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> <!--配置mybatis sqlSession工厂 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--数据源--> <property name="dataSource" ref="dataSource"/> <!--mapper文件路径--> <property name="mapperLocations" value="classpath:mappers/*.xml"/> <!--mybatis配置文件--> <property name="configLocation" value="classpath:sqlMappingConfig.xml"/> <!--对实体类起别名--> <property name="typeAliasesPackage" value="com.xmh.pojo"/> </bean> <!--配置mapper接口映射--> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--已经配置的sqlSessionFactoryBean--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!--扫描mapper接口包 spring容器会根据mapper接口代理生成实现类 因此我们不需要在mapper接口上加注解--> <property name="basePackage" value="com.xmh.mapper"/> </bean> <!--配置事务管理器--> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!--注入属性--> <property name="dataSource" ref="dataSource"/> </bean> <!--配置事务注解驱动--> <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/> </beans>
-
mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" "http://ibatis.apache.org/dtd/ibatis-3-config.dtd"> <configuration> <settings> <!--开启mybatis框架自带的slfj日志,可以查看sql语句的执行过程--> <setting name="logImpl" value="STDOUT_LOGGING"/> <!--开启驼峰映射,如表中first_name字段可自动映射为 实体类中firstName属性--> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!--方言,当前使用的是那个数据库,如果没有配置,也会自动从url中推测出--> <property name="helperDialect" value="mysql"/> <!--分页合理化 当页码<=0,查询第一页数据, 当页面>最大页码时,查询最后一条记录--> <property name="reasonable" value="true"/> <!--查询总记录数--> <property name="defaultCount" value="true"/> </plugin> </plugins> </configuration>
-
jdbc配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=1234
Spring继承Junit测试
-
创建测试类
-
对测试类进行配置
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:springContext.xml") public class SpringTest { }
数据库准备
-
创建数据库
CREATE DATABASE test;
-
创建测试表
CREATE TABLE `myemp` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '男', `job` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `salary` decimal(7, 2) NULL DEFAULT NULL, `hiredate` date NULL DEFAULT NULL, `deptno` int(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of myemp -- ---------------------------- INSERT INTO `myemp` VALUES (1, 'rose', '男', '研发部', 12345.67, '2013-05-21', 10); INSERT INTO `myemp` VALUES (2, 'jack', '男', NULL, NULL, '2022-11-03', NULL); INSERT INTO `myemp` VALUES (3, 'scott', '男', '市场', 5600.00, '2014-07-28', 20); INSERT INTO `myemp` VALUES (4, 'lucy', '女', '销售', 4300.00, '2015-08-08', 30); INSERT INTO `myemp` VALUES (5, 'lily', '女', '销售', 5800.00, '2017-06-07', 30); INSERT INTO `myemp` VALUES (6, 'bob', '男', '市场', 8500.00, '2016-06-23', 20); INSERT INTO `myemp` VALUES (7, 'hanmei', '女', '市场', 5200.00, '2018-02-23', 20); INSERT INTO `myemp` VALUES (8, 'Tom', '男', '研发部', 6200.00, '2017-02-18', 10);
测试
-
实体类
@Data @NoArgsConstructor @AllArgsConstructor public class Emp { private int id; private String name; private String sex; private String job; private double salary; private Date hiredate; private int deptno; }
-
mapper接口
public interface EmpMapper { /** * 查询所有员工 * * @return 返回员工集合 */ List<Emp> findAll(); /** * 新增一个员工 * * @param emp 传入一个emp对象 * @return 返回插入行数 */ int addEmp(Emp emp); /** * 删除一个员工根据id * * @param id 员工id * @return 返回删除行数 */ int deleteEmpById(int id); /** * 更新一个员工根据id * * @param emp 传入一个emp对象 * @return 返回更新行数 */ int updateEmpById(Emp emp); }
-
service 和 实现类
-
public interface EmpService { List<Emp> findAll(); boolean addEmp(Emp emp); boolean deleteEmpById(int id); boolean updateEmpById(Emp emp); }
-
@Service @Transactional(rollbackFor = Exception.class) public class EmpServiceImpl implements EmpService { private EmpMapper empMapper; @Autowired public void setEmpMapper(EmpMapper empMapper) { this.empMapper = empMapper; } @Override public List<Emp> findAll() { return empMapper.findAll(); } @Override public boolean addEmp(Emp emp) { // System.out.println("事务开启"); int rows = empMapper.addEmp(emp); // System.out.println("出现异常,事务回滚"); // int a = 1/0; return rows != 0; } @Override public boolean deleteEmpById(int id) { return empMapper.deleteEmpById(id) != 0; } @Override public boolean updateEmpById(Emp emp) { return empMapper.updateEmpById(emp) != 0; } }
-
-
mapper映射文件
<?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.xmh.mapper.EmpMapper"> <insert id="addEmp"> insert into myemp(name, sex, job, salary, hiredate, deptno) VALUES (#{name}, #{sex}, #{job}, #{salary}, #{hiredate}, #{deptno}) </insert> <update id="updateEmpById"> update myemp <set> <if test="name!=null">name=#{name},</if> <if test="sex!=null">sex=#{sex},</if> <if test="job!=null">job=#{job},</if> <if test="salary!=0">salary=#{salary},</if> <if test="hiredate!=null">hiredate=#{hiredate},</if> <if test="deptno!=0">deptno=#{deptno},</if> </set> where id = #{id} </update> <delete id="deleteEmpById"> delete from myemp where id = #{id}; </delete> <select id="findAll" resultType="com.xmh.pojo.Emp"> select id, name, sex, job, salary, hiredate, deptno # select * from myemp; </select> </mapper>
-
编写测试
-
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:springContext.xml") public class SpringTest { private EmpService empService; @Autowired public void setEmpService(EmpService empService) { this.empService = empService; }
-
测试findAll()
@Test public void findAll() { long start = System.currentTimeMillis(); List<Emp> empList = empService.findAll(); long end = System.currentTimeMillis(); System.out.println("总耗时:" + (end - start)); System.out.println(empList); }
-
结果
Emp(id=1, name=rose, sex=男, job=研发部, salary=12345.67, hiredate=Tue May 21 00:00:00 CST 2013,deptno=10) Emp(id=2, name=jack, sex=男, job=null, salary=0.0, hiredate=Thu Nov 03 00:00:00 CST 2022, deptno=0) Emp(id=3, name=scott, sex=男, job=市场, salary=5600.0, hiredate=Mon Jul 28 00:00:00 CST 2014, deptno=20) Emp(id=4, name=lucy, sex=女, job=销售, salary=4300.0, hiredate=Sat Aug 08 00:00:00 CST 2015, deptno=30) Emp(id=5, name=lily, sex=女, job=销售, salary=5800.0, hiredate=Wed Jun 07 00:00:00 CST 2017, deptno=30) Emp(id=6, name=bob, sex=男, job=市场, salary=8500.0, hiredate=Thu Jun 23 00:00:00 CST 2016, deptno=20) Emp(id=7, name=hanmei, sex=女, job=市场, salary=5200.0, hiredate=Fri Feb 23 00:00:00 CST 2018, deptno=20) Emp(id=8, name=Tom, sex=男, job=研发部, salary=6200.0, hiredate=Sat Feb 18 00:00:00 CST 2017, deptno=10) Emp(id=11, name=test, sex=男, job=测试, salary=5000.0, hiredate=Thu Nov 03 00:00:00 CST 2022, deptno=10)
-
-
测试addEmp()
@Test public void addEmp() { boolean is = empService.addEmp(new Emp(0, "test", "男", "测试", 2000, new Date(), 10)); System.out.println(is); }
-
测试deleteEmpById()
@Test public void deleteEmpById() { boolean is = empService.deleteEmpById(9); System.out.println(is); }
-
测试updateEmpById()
@Test public void updateEmpById() { Emp emp = new Emp(); emp.setId(11); emp.setJob("测试"); emp.setName("test"); emp.setSalary(5000); boolean is = empService.updateEmpById(emp); System.out.println(is); }
spring对springmvc整合
-
创建springmvc配置文件
<?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/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"> <!--扫描包--> <context:component-scan base-package="com.xmh.controller"/> <!--注解驱动--> <mvc:annotation-driven/> <!--处理静态资源--> <mvc:default-servlet-handler/> </beans>
-
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>ssm</display-name> <!--加载springContext配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springContext.xml</param-value> </context-param> <!--处理delete和put请求--> <filter> <filter-name>formContentFilter</filter-name> <filter-class>org.springframework.web.filter.FormContentFilter</filter-class> </filter> <filter-mapping> <filter-name>formContentFilter</filter-name> <url-pattern>/*</url-pattern> </filter-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> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--spring加载配置文件监听器--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--springmvc前端控制器--> <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: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> </web-app>
服务器配置
-
创建Controller
-
EmpController
@RestController public class EmpController { private EmpService empService; @Autowired public void setEmpService(EmpService empService) { this.empService = empService; } @GetMapping("/emp") public JsonResult findAll() { JsonResult jsonResult = new JsonResult(); jsonResult.setCode(200); jsonResult.setMessage("查询成功"); jsonResult.setData(empService.findAll()); return jsonResult; } @PostMapping("/emp") public JsonResult addEmp(Emp emp) { System.out.println(emp); if (empService.addEmp(emp)) { return JsonResult.success(); } return JsonResult.notSuccessful(); } @DeleteMapping("/emp") public JsonResult deleteEmpById(int id) { if (empService.deleteEmpById(id)) { return JsonResult.success(); } return JsonResult.notSuccessful(); } @PutMapping("/emp") public JsonResult deleteEmpById(Emp emp) { if (empService.updateEmpById(emp)) { return JsonResult.success(); } return JsonResult.notSuccessful(); } }
创建前端页面
-
前端页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form id="addEmp" method="post"> 姓名:<input type="text" name="name"><br> 性别:<input type="text" name="sex"><br> 职位:<input type="text" name="job"><br> 工资:<input type="text" name="salary"><br> 入职日期:<input type="date" name="hiredate"><br> 部门编号<input type="text" name="deptno"><br> <p id="addMsg"></p> <input type="button" value="添加" onclick="addEmp()"> </form> <hr style="margin-top: 20px;margin-bottom: 20px"> 删除员工根据id:<input type="text" name="delId"><br> <p id="deleteMsg"></p> <input type="button" value="删除" onclick="deleteById()"> <hr style="margin-top: 20px;margin-bottom: 20px"> <form id="updateEmp"> 员工id:<input type="text" name="id"><br> 姓名:<input type="text" name="name"><br> 性别:<input type="text" name="sex"><br> 职位:<input type="text" name="job"><br> 工资:<input type="text" name="salary"><br> 入职日期:<input type="date" name="hiredate"><br> 部门编号<input type="text" name="deptno"><br> <p id="updateMsg"></p> <input type="button" value="修改" onclick="updateEmp()"> </form> <hr style="margin-top: 20px;margin-bottom: 20px"> <table> <thead> <tr> <td>id</td> <td>username</td> <td>sex</td> <td>job</td> <td>salary</td> <td>hiredate</td> <td>deptno</td> </tr> </thead> <tbody id="findAll"> </tbody> </table> <script src="./js/jquery.serializejson.js"></script> <script src="./js/jquery-3.6.1.min.js"></script> <script> $(document).ready(function () { $.ajax({ url: "emp", type: "get", success: function (res) { console.log(res) for (let i = 0; i < res.data.length; i++) { $("#findAll").append('<tr>' + '<td>' + res.data[i].id + '</td>' + '<td>' + res.data[i].name + '</td>' + '<td>' + res.data[i].sex + '</td>' + '<td>' + res.data[i].job + '</td>' + '<td>' + res.data[i].salary + '</td>' + '<td>' + res.data[i].hiredate + '</td>' + '<td>' + res.data[i].deptno + '</td>' + '</tr>') } } }) }) function addEmp() { $.ajax({ url: "/emp", type: "post", data: "name=" + $("input[name=name]").val() + "&sex=" + $("input[name=sex]").val() + "&job=" + $("input[name=job]").val() + "&salary=" + $("input[name=salary]").val() + "&hiredate=" + $("input[name=hiredate]").val() + "&deptno=" + $("input[name=deptno]").val(), success: function (res) { $("#addMsg").html(res.message) } }) } function deleteById() { $.ajax({ url: "emp" + $("input[name=delId]").val(), type: "delete", success: function (res) { $("#addMsg").html(res.message) } }) } function updateEmp() { $.ajax({ url: "emp", type: "put", data: "id=" + $("input[name=id]").val() + "&name=" + $("input[name=name]").val() + "&sex=" + $("input[name=sex]").val() + "&job=" + $("input[name=job]").val() + "&salary=" + $("input[name=salary]").val() + "&hiredate=" + $("input[name=hiredate]").val() + "&deptno=" + $("input[name=deptno]").val(), success: function (res) { $("#addMsg").html(res.message) } }) </script> </body> </html>
我更推荐后端开发使用专门的工具发请求,可以发请求和接受参数就可以,可以节约很多时间