这里写目录标题

  • 要求
  • Spirng整合Mybatis
  • Spirng整合SpringMVC
  • 表与实体类的创建
  • 创建层级
  • Dao层
  • Service层
  • controller层
  • 接口测试
    • 业务层`service`测试
    • 表现层`controller`测试
  • 表现层数据封装
    • 定义前后端通信协议
  • 异常处理
  • 前端
    • 配置访问
    • 页面展示
  • 拦截器

要求

Spirng整合Mybatis

基本的步骤就不说了,反正前面这么多案例了已经
现在,就把maven坐标与创建好的目录看一下

名字 实例名/插件名
springmvc框架 spring-webmvc
spring操纵jdbc spring-jdbc
spring操纵test测试 spring-test
mybatis框架 mybatis
servlet技术(运行需要屏蔽,即provided) javax.servlet-api
json技术 jackson-databind
德鲁伊数据库连接池 druid
mybatis整合spring mybatis-spring
junit测试 junit
mysql驱动 mysql-connector-java
tomcat7插件(需要配端口与路径) tomcat7-maven-plugin

这里必须将characterEncoding=UTF-8放在url参数第一位!

jdbc.properties

jdbc.classname=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/20220806lige?characterEncoding=UTF-8&useSSL=false&useServerPrepStmts=true&useUnicode=true
jdbc.username=root
jdbc.password=root

SpringConfig.java配置类

JdbcConfig.java配置类

package cn.calendo.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;import javax.sql.DataSource;public class JdbcConfig {//把jdbc.properties里的变量引入(通过@Value注解形式)@Value("${jdbc.classname}")private String classname;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;//收集连接池数据,整理成一个bean交给Spring管理@Beanpublic DataSource dataSource() {DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setDriverClassName(classname);druidDataSource.setUrl(url);druidDataSource.setUsername(username);druidDataSource.setPassword(password);return druidDataSource;}//事务控制器,整理成一个bean交给Spring管理@Beanpublic PlatformTransactionManager platformTransactionManager(DataSource dataSource) {DataSourceTransactionManager ds = new DataSourceTransactionManager();ds.setDataSource(dataSource);return ds;}
}

MybatisConfig.java配置类

public class MybatisConfig {//开始造mybatis最渴望需要的工厂bean(又需要我们提供已造好的datasource),并启用类型别名(需要扫描pojo包)//这个datasource是在spring容器中自动帮我们装配好的(对,就是前面我们JdbcConfig设置好的datasource提交给spring容器处理好的)//返回一个工厂bean交给spring容器处理@Beanpublic SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);sqlSessionFactoryBean.setTypeAliasesPackage("cn.calendo.pojo");return sqlSessionFactoryBean;}//这个bean来指定从pojo类字段到dao层接口的映射,由于我们在dao中配的是接口,所以我们写到dao包即可@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer msc = new MapperScannerConfigurer();msc.setBasePackage("cn.calendo.dao");return msc;}
}

Spirng整合SpringMVC

ServletConfig.java配置类

public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {@Override//对于root,我们需要加载spring的核心配置类,当web容器启动时,getRootConfigClasses会加载SpringConfig里面的beanprotected Class<?>[] getRootConfigClasses() {return new Class[]{SpringConfig.class};}//由于SpringMVC是Spring的父容器,所以SpringMVC容器能访问Spring容器中的东西,而Spring容器不能访问SpringMVC容器中的东西@Override//对于web容器,我们需要加载springMvc的配置类,当web容器启动时,getServletConfigClasses会加载SpringMVCConfig里面的beanprotected Class<?>[] getServletConfigClasses() {return new Class[]{SpringMVCConfig.class};}@Override//springmvc需要拦截所有请求给自己处理,而不是给servlet一点机会protected String[] getServletMappings() {return new String[]{"/"};}//这里本来可以写过滤器,但是我们先不写吧
}

SpringMVCConfig.java配置类

@Configuration
//他需要读取controller层的方法进行配置
@ComponentScan({"cn.calendo.controller"})
//必定开启功能强大的注解
@EnableWebMvc
public class SpringMVCConfig {}

表与实体类的创建

sql脚本:

use 20220806lige;drop table if exists tb_user;create table tb_user
(id       int primary key auto_increment,username varchar(20),password varchar(20),gender   varchar(8),address  text
);INSERT INTO tb_user
VALUES (1, '张三', '123456', '男', '浙江,杭州');
INSERT INTO tb_user
VALUES (2, '李四', '123456', '女', '浙江,温州');
INSERT INTO tb_user
VALUES (3, '王五', '123456', '男', '江苏,苏州');
INSERT INTO tb_user
VALUES (4, '刘六', '123456', '女', '江苏,南京');
INSERT INTO tb_user
VALUES (5, '孙七', '123456', '男', '山东,青岛');
INSERT INTO tb_user
VALUES (6, '钱吧', '123456', '女', '山东,烟台');
INSERT INTO tb_user
VALUES (7, '阿猫', '123456haode', '无', '福建,厦门');
INSERT INTO tb_user
VALUES (8, '阿狗', '1234we56', '无', '广东,深圳');
INSERT INTO tb_user
VALUES (9, '阿信', 'hahaha123456', '女', '广东,广州');
INSERT INTO tb_user
VALUES (10, '阿文', 'wokao123456', '男', '上海');

好的现在表已经建好了

pojo实体类

public class User {private Integer id;private String username;private String password;private String gender;private String address;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}//toString其实只是给我们调试用,其它没啥用的,但是我们都会加上它的@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", gender='" + gender + '\'' +", address='" + address + '\'' +'}';}
}

创建层级

Dao层

public interface UserDao {//md我们很懒我们写了接口然后不想自己写实现类,那就用mybatis的代理来帮我们创建这些实现类啊@Insert("insert into tb_user values(null, #{username}, #{password}, #{gender}, #{address})")public void add(User user);@Update("update tb_user set username = #{username}, password = #{password}, gender = #{gender}, address = #{address} where id = #{id}")public void update(User user);@Delete("delete from tb_user where id = #{id}")public void delete(Integer id);@Select("select * from tb_user where id = #{id}")public User selectById(Integer id);@Select("select * from tb_user")public List<User> selectAll();
}

Service层

UserService实现类

public interface UserService {/*** 新增/保存* @param user* @return*/public boolean addUser(User user);/*** 修改/更新* @param user* @return*/public boolean updateUser(User user);/*** 删除/注销* @param user* @return*/public boolean deleteUser(User user);/*** 单个查询* @param id* @return*/public User selectUserById(Integer id);/*** 查询所有* @return*/public List<User> selectAllUser();
}

UserServiceImpl实现类

//定义组件给SpringConfig扫描到
@Service
public class UserServiceImpl implements UserService {//由于自动装配了我们就没有new一个user对象,idea好心帮我们查了,但是这不是错误,把这个错误忽略即可//自动装配,不需要我们手动实例化@Autowiredprivate UserDao userDao;//然后我们需要调用Dao层的接口,把值传进去public boolean addUser(User user) {userDao.add(user);return true;}public boolean updateUser(User user) {userDao.update(user);return true;}public boolean deleteUser(Integer id) {userDao.delete(id);return true;}public User selectUserById(Integer id) {return userDao.selectById(id);}public List<User> selectAllUser() {return userDao.selectAll();}
}

controller层

UserController

//设置组件名,给springmvc加载,以及虚拟路径
@RestController
@RequestMapping("/users")
public class UserController {//也是自动装配,调用service层@Autowiredprivate UserService userService;//post请求,参数实体类,用json传数据@PostMappingpublic boolean addUser(@RequestBody User user) {return userService.addUser(user);}//put请求,参数实体类,用json传数据@PutMappingpublic boolean updateUser(@RequestBody User user) {return userService.updateUser(user);}//delete请求,参数id,用路径传递@DeleteMapping("/{id}")public boolean deleteUser(@PathVariable Integer id) {return userService.deleteUser(id);}//get请求,参数id,用路径传递@GetMapping("/{id}")public User selectUserById(@PathVariable Integer id) {return userService.selectUserById(id);}//get请求,无参数@GetMappingpublic List<User> selectAllUser() {return userService.selectAllUser();}
}

接口测试

在企业开发中,当我们写完业务层service接口时需要进行junit测试,以及写完表现层controller接口时需要进行api-post测试

业务层service测试

//spring调用junit需要的引用类
//指定配置类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {@Autowiredprivate UserService userService;/*** 测试删除一个用户* @param id*/@Testpublic void testDeleteUser(Integer id){boolean user = userService.deleteUser(2);System.out.println(user);}/*** 测试根据id选择用户* @param id*/@Testpublic void testSelectUserById() {User user = userService.selectUserById(1);//正规测试需要做断言匹配System.out.println(user);}/*** 测试选择全部用户*/@Testpublic void testSelectAllUser() {List<User> ListUser = userService.selectAllUser();System.out.println(ListUser);}
}

表现层controller测试

建立测试数据(delete不需要任何数据只要在url上添加数字即可(遵循rest风格))

如果数据库中文是问号?那就在jdbc.properties后面加参数,示例:
jdbc.url=jdbc:mysql://localhost:3306/20220806lige?characterEncoding=UTF-8
成功

表现层数据封装

这就是前端与后端人员之间的通信协议

code代表操作的方法,以及成功与否1成功0失败
成功,数据都在data里,失败,返回信息放在msg

定义前后端通信协议

package cn.calendo.controller;//定义前后端协议
public class Result {private Object data;public Integer code;private String msg;public Result() {}public Result(Object data, Integer code) {this.data = data;this.code = code;}public Result(Object data, Integer code, String msg) {this.data = data;this.code = code;this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

然后在controller里新建一个code,java来定义code码

package cn.calendo.controller;public class Code {public static final Integer SAVE_OK = 20011;public static final Integer UPDATE_OK = 20021;public static final Integer DELETE_OK = 20031;public static final Integer SELECT_OK = 20041;public static final Integer SAVE_ERR = 20010;public static final Integer UPDATE_ERR = 20020;public static final Integer DELETE_ERR = 20030;public static final Integer SELECT_ERR = 20040;
}

这时我们在UserController里面所返回的值就需要改动了

package cn.calendo.controller;import cn.calendo.pojo.User;
import cn.calendo.service.UserService;
import com.alibaba.druid.support.json.JSONUtils;
import com.sun.org.apache.xml.internal.serializer.Serializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.filter.CharacterEncodingFilter;import java.io.Serializable;
import java.util.List;//设置组件名,给springmvc加载,以及虚拟路径
@RestController
@RequestMapping("/users")
public class UserController {//也是自动装配,调用service层@Autowiredprivate UserService userService;//post请求,参数实体类,用json传数据@PostMappingpublic Result addUser(@RequestBody User user) {boolean flag = userService.addUser(user);return new Result(flag ? Code.SAVE_OK : Code.SAVE_ERR, flag);}//put请求,参数实体类,用json传数据@PutMappingpublic Result updateUser(@RequestBody User user) {boolean flag = userService.updateUser(user);return new Result(flag ? Code.UPDATE_OK : Code.UPDATE_ERR, flag);}//delete请求,参数id,用路径传递@DeleteMapping("/{id}")public Result deleteUser(@PathVariable Integer id) {boolean flag = userService.deleteUser(id);return new Result(flag ? Code.DELETE_OK : Code.DELETE_ERR, flag);}//get请求,参数id,用路径传递@GetMapping("/{id}")public Result selectUserById(@PathVariable Integer id) {User user = userService.selectUserById(id);Integer code = (user != null ? Code.SELECT_OK : Code.SELECT_ERR);String msg = (user != null ? "" : "数据查询失败!");return new Result(code, user, msg);}//get请求,无参数@GetMappingpublic Result selectAllUser() {List<User> ListUser = userService.selectAllUser();Integer code = (ListUser != null ? Code.SELECT_OK : Code.SELECT_ERR);String msg = (ListUser != null ? "" : "数据查询失败!");return new Result(code, ListUser, msg);}
}

测试之后,成功

异常处理

新建一个拦截异常类在controller层

//使用这个写好的aop
@RestControllerAdvice
public class ProjectExceptionAdvice {//此注解可以拦截指定异常@ExceptionHandler(Exception.class)public Result doException(Exception e) {System.out.println("拦截到异常");return new Result(404, null,"拦截到异常");}
}


新建异常包处理各种异常

package cn.calendo.exception;public class SystemException extends RuntimeException {private Integer code;public Integer getCode() {return code;}public SystemException(Integer code) {this.code = code;}public SystemException(Integer code, String message) {super(message);this.code = code;}public SystemException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}public SystemException(Integer code, Throwable cause) {super(cause);this.code = code;}public SystemException(Integer code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);this.code = code;}
}




前端

配置访问

由于springmvc会把webapp里的东西全部拦截,所以我们需要放行

新建一个叫SpringMVCSupport的访问放行配置

@Configuration
public class SpringMVCSupport extends WebMvcConfigurationSupport {@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");registry.addResourceHandler("/css/**").addResourceLocations("/css/");registry.addResourceHandler("/js/**").addResourceLocations("/js/");registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");}
}

然后让SpringMVCConfig去扫描
@ComponentScan({"cn.calendo.controller", "cn.calendo.config"})

页面展示

我们写一下getAll即可获取到全部数据

然后把新增业务做出来

修改功能:

vue methods:

methods: {//列表getAll() {axios.get("/users").then((res) => {this.dataList = res.data.data;})},//弹出添加窗口handleCreate() {this.resetForm();this.dialogFormVisible = true;},//重置表单resetForm() {this.formData = {};},//添加handleAdd() {axios.post("/users", this.formData).then((res) => {if (res.data.code === 20011) {this.dialogFormVisible = false;this.$message.success("添加成功" + " " + "status: " + res.data.code);} else if (res.data.code === 20010) {this.$message.error("添加失败" + " " + "status: " + res.data.code);} else {this.$message.error(res.data.msg)}this.dialogFormVisible = false;this.getAll();}).finally(() => {this.getAll();});},//弹出编辑窗口handleUpdate(row) {axios.get("/users/" + row.id).then((res) => {if (res.data.code === 20041) {this.formData = res.data.data;this.dialogFormVisible4Edit = true;} else {this.$message.error(res.data.msg);}})},//编辑handleEdit() {axios.put("/users", this.formData).then((res) => {if (res.data.code === 20021) {this.dialogFormVisible4Edit = false;this.$message.success("修改成功" + "  " + "status: " + res.data.code);} else if (res.data.code === 20020) {this.$message.error("修改失败" + "  " + "status: " + res.data.code);} else {this.$message.error(res.data.msg)}this.dialogFormVisible4Edit = false;this.getAll();}).finally(() => {this.getAll();});},// 删除handleDelete(row) {this.$confirm("此操作永久删除当前数据,是否继续?", "警告", {type: 'info'}).then(() => {axios.delete("/users/" + row.id).then((res) => {if (res.data.code === 20031) {this.$message.success("删除成功" + "  " + "status: " + res.data.code);} else if (res.data.code === 20030) {this.$message.error("删除失败" + "  " + "status: " + res.data.code);} else {this.$message.error(res.data.msg);}}).finally(() => {this.getAll();});}).catch(() => {this.$message.info("取消删除");})}}

拦截器

springmvc独有的拦截器
和之前的转发一样的写法

先在springmvcConfig里面写好能扫描到拦截器的路径
这是SpringMvcSupportConfig

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {@Autowiredprivate ProjectInterceptor projectInterceptor;@Overrideprotected void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");}@Overrideprotected void addInterceptors(InterceptorRegistry registry) {//配置拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");}
}

然后开始新建拦截器
拦截器

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {@Override//原始方法调用前执行的内容//返回值类型可以拦截控制的执行,true放行,false终止public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String contentType = request.getHeader("Content-Type");HandlerMethod hm = (HandlerMethod)handler;System.out.println("preHandle..."+contentType);return true;}@Override//原始方法调用后执行的内容public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("postHandle...");}@Override//原始方法调用完成后执行的内容public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("afterCompletion...");}
}

其实在springmvcconfig里面也可以直接继承WebMvcConfigurer

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
//实现WebMvcConfigurer接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {@Autowiredprivate ProjectInterceptor projectInterceptor;@Autowiredprivate ProjectInterceptor2 projectInterceptor2;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//配置多拦截器registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");}
}


SSM学习——SSM整合案例(Spring+SpringMVC+Mybatis)(13)相关推荐

  1. SSM三大框架整合(Spring+SpringMVC+MyBatis)

    文章目录 SSM整合 一.导入依赖 1.1 Spring依赖 1.2 SpringMVC依赖 1.3 MyBatis依赖 二.配置文件 2.0 Web.xml 配置文件 2.1 Spring的配置文件 ...

  2. SSM实现学生管理系统(spring+springMVC+MyBatis)

    SSM实现学生管理系统(spring+springMVC+MyBatis) 一.项目介绍 该项目是基于SSM框架实现的学生管理系统,能够对学生信息进行增删改查,分页查询,以及实现管理员的注册.登录 数 ...

  3. SSM纯注解后台代码整合(Spring+SpringMvc+Mybatis)

    SSM后台整合(Spring+SpringMvc+Mybtis+事务+Rest风格+统一结果封装+统一异常处理+拦截器) 文章目录 1 基础环境搭建 1.1 建表 1.2 创建web项目 1.3 导入 ...

  4. SSM实战项目-员工管理系统 Spring+SpringMVC+MyBatis

    项目描述: JavaWeb实战之员工管理系统,一个完整的SSM整合项目,适用于刚学完SSM框架的伙伴,熟练一下SSM整合,融会贯通.基本的增删改查都有,功能比较完善.使用框架并不是很难,关键是要理解起 ...

  5. SSM框架整合(Spring+SpringMVC+MyBatis)

    输出结果 1.Maven Web项目创建 之前有写过Eclipse+Maven创建web项目的帖子,如果需要,请参考这里写链接内容 创建好项目之后因为入下图: 2.SSM整合 2.1 引入需要的JAR ...

  6. SSM框架整合(Spring+SpringMVC+MyBatis+Oracle)

    1.开发环境搭建以及创建Maven Web项目 参看之前的博文:http://www.cnblogs.com/cainiaomahua/p/6306476.html 2.SSM整合 这次整合有2个配置 ...

  7. 超级详细配置SSM (Intellij idea + Maven + Spring + SpringMVC + MyBatis + c3p0 )

    时间2018/12/31,使用的包都是最新的和用的人最多的QAQ. Maven仓库查找包的地址 https://mvnrepository.com/ 在经历了70多个小时的奋斗后(花了60个小时学习了 ...

  8. SSM整合(Spring + SpringMVC + Mybatis)

    SSM所需要的依赖 <?xml version="1.0" encoding="UTF-8"?><project xmlns="ht ...

  9. ssm注解配置连接mysql_SSM框架整合(注解)-Spring+SpringMVC+MyBatis+MySql

    准备工作: 下载整合所需的jar包 点击此处下载 使用MyBatis Generator生成dao接口.映射文件和实体类 如何生成 搭建过程: 先来看一下项目的 目录结构 1.配置dispatcher ...

  10. SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)

    登录 | 注册 收藏成功 确定 收藏失败,请重新收藏 确定 查看所有私信查看所有通知 暂没有新通知 想要绕过微信小程序开发中的坑吗?不妨来听这个,今晚8点,1小时帮你搞定! 14小时以前 CSDN日报 ...

最新文章

  1. 美法加三位科学家获2018诺贝尔物理学奖
  2. linux字体栅格化,响应式开发---网页的布局方式、媒体查询、栅格化布局、less语言...
  3. 转)使用C/C++扩展Python
  4. django批量修改table_django-formset实现数据表的批量操作
  5. Robots.txt 协议详解及使用说明
  6. Android + Appium 自动化测试完整的环境配置及代码详解
  7. 谈谈为什么要系统学习算法-开复的一篇文章
  8. rk3399_android7.1耳机拔插ADC检测
  9. log4j的使用 slf4j简单介绍
  10. 使用AStar算法解决八数码问题
  11. python wget_python wget下载文件处理的一些问题
  12. 手动批量下载ts文件并合并
  13. 远心镜头(Telecentric lens)原理介绍
  14. 计算机类绘图的文献,基于计算机CAD绘图探讨论文
  15. b站pink老师JavaScript的DOM案例代码——模拟京东快递单号查询
  16. 回给collapsar的信
  17. OCPC不起量该怎么办?从这四个方面着手,轻松起量
  18. MyBatis遇到:There is no getter for property named ‘Xxx‘ in ‘class xxx.xxx.Xxx‘问题
  19. 京林生态花园2021年(第三届)春节花展即将盛大开幕
  20. 在HashSet集合中添加三个Person对象,把姓名相同的人当作同一个人,禁止重复添加。 提示:Person类中定义name和age属性,重写hashCode()方法和equals()方法,针对Pe

热门文章

  1. python爬取百度指数
  2. 日本語を勉強する日記 十八回目
  3. 往事如烟 - 摘掉脱贫的帽子
  4. vuex的基本介绍和使用
  5. c#解析Josn(解析多个子集,数据,可解析无限级json)
  6. 人工蜂群算法(ABC)
  7. 图的深度优先遍历(DFS)和广度优先遍历(BFS)非递归实现C++
  8. Codeforces #635题解
  9. 宠物消费升级 “黑科技”带来了哪些改变?
  10. 计算机应用中的销售方案,关于计算机销售管理的应用论文