SpringMVC_SSM整合

一、回顾SpringMVC访问接口流程

1.容器加载分析

  • 容器分析

    SpringMVC_SSM整合_第1张图片

  • 手动注册WebApplicationContext

    public class ServletConfig extends AbstractDispatcherServletInitializer {
    
        @Override
        protected WebApplicationContext createServletApplicationContext() {
            //获取SpringMVC容器
            AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            context.register(SpringMvcConfig.class);
            return context;
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
        @Override
        protected WebApplicationContext createRootApplicationContext() {
            return null;
        }
    }
    

2.容器加载过程分析

  • tomcat 服务器启动的时候,加载ServletConfig类之后,做初始化web容器操作,相当于 web.xml

  • 执行注册容器的方法,获取 SpringMVC容器 WebApplicationContext

    @Nullable
        protected WebApplicationContext createRootApplicationContext() {
            Class<?>[] configClasses = this.getRootConfigClasses();
            if (!ObjectUtils.isEmpty(configClasses)) {
                AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
                context.register(configClasses);
                return context;
            } else {
                return null;
            }
        }
    
        protected WebApplicationContext createServletApplicationContext() {
            AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            Class<?>[] configClasses = this.getServletConfigClasses();
            if (!ObjectUtils.isEmpty(configClasses)) {
                context.register(configClasses);
            }
    
            return context;
        }
    
  • 通过@ComponentScan(“cn.sycoder.controller”) 加载 Controller 下面的bean 进 WebApplicationContext

    @RestController
    public class TestController {
    
        @GetMapping("/test/{id}")
        public String test(@PathVariable Long id) {
            return "ok:" + id;
        }
    }
    
  • 把使用了 RequestMapping 注解的方法的 value — 对应一个方法,建立起了一对一映射关系(可以想象hashmap)

    • /test/{id} ---- test 方法

3.请求接口过程

  • 访问 http://localhost:8082/test/1
  • 匹配 springmvc 的 / servletMapping 规则,交给 springmvc 处理
  • 解析 /test/1路径找到对应的 test 方法
  • 执行方法
  • 因为使用 RestController ,所以返回方法的返回值作为响应体返回给浏览器

4.SSM整合会出现bean界定不清楚问题

  • SpringMVC 需要加载哪些bean?
    • controller 层(表现层即可)
  • Spring 加载哪些bean?
    • service
    • dao

4.1如何处理

  • 将spring配置注入到 web 容器中

    @Configuration
    @ComponentScan(value={"cn.sycoder.service","cn.sycoder.dao"})
    public class SpringConfig {
    }
    
    
    public class ServletConfig  extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    

4.2验证两个容器的bean相互不干扰

  • 验证代码

    @Test
    public void test(){
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(SpringConfig.class);
        ITestService bean = applicationContext.getBean(ITestService.class);
        bean.get(1L);
    
        TestController bean1 = applicationContext.getBean(TestController.class);
        System.out.println(bean1.test(1L));
    }
    

二、SSM整合

1.SSM整合流程分析

  • 概述SSM:Spring SpringMVC Mybatis

1.1创建工程

  • 导入依赖

    • ssm 所需要的依赖包
  • 配置 web 项目入口配置替换 web.xml(AbstractAnnotationConfigDispatcherServletInitializer)

    • 配置 Spring 配置类交给 web 容器管理

      @Override
          protected Class<?>[] getRootConfigClasses() {
              return new Class[]{SpringConfig.class};
          }
      
    • 配置 SpringMVC 配置类交给 web 容器管理

      @Override
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
    • 配置请求拦截规则,交给 springmvc 处理

      @Override
          protected String[] getServletMappings() {
              return new String[]{"/"};
          }
      

1.2配置 Spring

  • SpringConfig
    • @Configuration 标记Spring配置类,替换Spring-config-xml
    • @ComponetScan 扫描需要被Spring 管理的bean
    • @EnableTransactionManagment 启动管理事务支持
    • @PropertySource 引入db.properties 配置文件
  • 配置 JdbcConfig 配置类
    • 使用德鲁伊 DataSource 数据源
    • 构建平台事务管理器 DataSourceTransactionManager
  • 配置 MyBatis 配置类
    • 构建 SqlSessionFactoryBean
    • 指定 MapperScanner 设置 mapper 包扫描寻找 mapper.xml 文件

1.3配置 SpringMVC

  • 配置SpringMvcConfig
    • @Configuration
    • @ComponentScan 只扫描 Controller
    • 开启SpringMVC 注解支持 @EnableWebMvc

1.4开发业务

  • 使用注解
    • 注入bean 注解
      • @Autowired
    • @RestController
      • @GetMapping
        • @RequestParam
      • @PostMapping
        • @RequestBody
      • @DeleteMapping
        • @PathVariable
      • @PutMapping
    • @Service
      • @Transactional
    • junit
      • @RunWith
      • @ContextConfiguration
      • @Test

2.SSM整合

2.1导入依赖

  • 依赖

    <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.2.17.RELEASE</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>5.2.17.RELEASE</version>
        </dependency>
    
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>5.2.17.RELEASE</version>
        </dependency>
    
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.6</version>
        </dependency>
    
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis-spring</artifactId>
          <version>1.3.0</version>
        </dependency>
    
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.29</version>
        </dependency>
    
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.16</version>
        </dependency>
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
    
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.0</version>
        </dependency>
      </dependencies>
    

2.2创建各目录结构

  • 目录如下

    SpringMVC_SSM整合_第2张图片

2.3创建SpringConfig

  • SpringConfig(在整合项目的时候不能扫描mvc的类,否则会出现创建容器失败)

    @Configuration
    @ComponentScan(value = {"cn.sycoder.service","cn.sycoder.dao"})
    @EnableTransactionManagement
    @PropertySource("classpath:db.properties")
    @Import({DbConfig.class,MybatisConfig.class})
    public class SpringConfig {
    }
    

2.4创建DbConfig配置类

  • 创建数据库配置文件

    jdbc.url=jdbc:mysql://localhost:3306/ssm
    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.username=root
    jdbc.password=123456
    
  • 创建DbConfig

    public class DbConfig {
        
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
    
        /**
         * 配置德鲁伊连接池
         * @return
         */
        @Bean
        public DataSource dataSource(){
            DruidDataSource source = new DruidDataSource();
            source.setUrl(url);
            source.setDriverClassName(driver);
            source.setPassword(password);
            source.setUsername(username);
            return source;
        }
        
        @Bean
        public PlatformTransactionManager transactionManager(DataSource dataSource){
            DataSourceTransactionManager manager = new DataSourceTransactionManager();
            manager.setDataSource(dataSource);
            return manager;
        }
        
    }
    

2.5创建MybatisConfig配置类

  • MyBatisConfig

    public class MybatisConfig {
        
        @Bean
        public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource){
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setTypeAliasesPackage("cn.sycoder.domain");
            return bean;
        }
        
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer(){
            MapperScannerConfigurer configurer = new MapperScannerConfigurer();
            configurer.setBasePackage("cn.sycoder.dao");
            return configurer;
        }
    }
    

2.6创建SpringMVC配置类

  • SpringMvcConfig

    @Configuration
    @ComponentScan("cn.sycoder.controller")
    @EnableWebMvc
    public class SpringMvcConfig {
    }
    

2.7创建Web项目入口配置类

  • ServletConfig

    public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};//配置Spring交给Web 管理
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    }
    

3.功能开发

3.1创建数据库及表

  • 创建 ssm 数据库

  • 创建 item 表

    create table item
    (
    	id bigint auto_increment,
    	type varchar(64) null,
    	name varchar(64) null,
    	remark text null,
    	constraint item_pk
    		primary key (id)
    );
    
    

3.2编写模型类

  • 添加 lombok 依赖

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.22</version>
    </dependency>
    
  • 模型类

    @Data
    public class Item {
        private Long id;
        private String name;
        private String type;
        private String remark;
    }
    

3.3编写Mapper接口

  • Mapper 接口

    @Repository
    public interface ItemMapper {
        @Insert("insert into item(name,type,remark) value(#{name},#{type},#{remark})")
        public int save(Item item);
        @Delete("delete from item where id = #{id}")
        public int delete(Long id);
        @Update("update item set name = #{name},type = #{type},remark=#{remark} where id=#{id}")
        public int update(Item item);
        @Select("select * from item where id = #{id}")
        public Item getById(Long id);
        @Select("select * from item")
        public List<Item> list();
    
    }
    

3.4编写Service接口和实现类

  • Service 接口

    public interface IItemService {
        /**
         * 添加闲置物品方法
         * @param item
         * @return
         */
        public boolean save(Item item);
    
        /**
         * 删除闲置物品
         * @param id
         * @return
         */
        public boolean delete(Long id);
    
        /**
         * 更新闲置物品
         * @param item
         * @return
         */
        public boolean update(Item item);
    
        /**
         * 查询闲置物品通过id
         * @param id
         * @return
         */
        public Item getById(Long id);
    
        /**
         * 查询所有闲置商品
         * @return
         */
        public List<Item> lists();
    }
    
  • 定义接口实现类

    @Service
    public class ItemServiceImpl implements IItemService {
        
        @Autowired
        ItemMapper mapper;
        
        @Override
        @Transactional
        public boolean save(Item item) {
            return mapper.save(item) > 0;
        }
    
        @Override
        @Transactional
        public boolean delete(Long id) {
            return mapper.delete(id) >0;
        }
    
        @Override
        @Transactional
        public boolean update(Item item) {
            return mapper.update(item) >0;
        }
    
        @Override
        public Item getById(Long id) {
            return mapper.getById(id);
        }
    
        @Override
        public List<Item> lists() {
            return mapper.list();
        }
    }
    

3.5编写Contorller类

  • Controller

    @RestController
    @RequestMapping("/item")
    public class ItemController {
    
        @Autowired
        IItemService service;
    
        @PostMapping
        public boolean save(@RequestBody Item item){
            return service.save(item);
        }
    
        @PutMapping
        public boolean update(@RequestBody Item item){
            return service.update(item);
        }
    
        @DeleteMapping("/{id}")
        public boolean delete(@PathVariable Long id){
            return service.delete(id);
        }
    
        @GetMapping("/{id}")
        public Item getById(@PathVariable Long id){
            return service.getById(id);
        }
    
        @GetMapping
        public List<Item> list(){
            return service.lists();
        }
    }
    

4.验证 ssm 整合结果

  • 启动项目并且解决问题

    在这里插入图片描述

  • 修改Spring配置类

    @Configuration
    @ComponentScan(value = {"cn.sycoder.service","cn.sycoder.dao"})
    @EnableTransactionManagement
    @PropertySource("classpath:db.properties")
    @Import({DbConfig.class,MybatisConfig.class})
    public class SpringConfig {
    }
    

4.1添加item 数据

  • 准备 item 数据

    {"name":"键盘","type":"电脑外设","remark":"9成新,半价卖"}
    
    {"name":"笔记本","type":"电脑","remark":"9成新,8折出售"}
    
    {"name":"鞋子","type":"收藏鞋","remark":"科比签名的,独一无二"}
    
  • 添加数据

    SpringMVC_SSM整合_第3张图片

4.2修改数据

  • 准备数据

    {"id":4,"name":"二手鞋子","type":"废鞋","remark":"破鞋子"}
    
  • 修改操作

    SpringMVC_SSM整合_第4张图片

4.3查询单个数据

  • 查询id=4的物品

    SpringMVC_SSM整合_第5张图片

4.4删除单个数据

  • 删除id=4的物品

    SpringMVC_SSM整合_第6张图片

4.5查询全部数据操作

  • 查询全部

    SpringMVC_SSM整合_第7张图片

5.整合单元测试

  • 目录结构

    SpringMVC_SSM整合_第8张图片

  • 新建测试类

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfig.class)
    public class ItemTest {
    
        @Autowired
        IItemService service;
    
    
        @Test
        public void save(){
            Item item = new Item();
            item.setName("单元测试");
            item.setRemark("单元测试");
            item.setType("单元测试");
            boolean save = service.save(item);
            System.out.println(save);
        }
    
        @Test
        public void update(){
            Item item = new Item();
            item.setId(5L);
            item.setName("单元测试");
            item.setRemark("单元测试");
            item.setType("单元测试");
            boolean save = service.update(item);
            System.out.println(save);
        }
    
        @Test
        public void getById(){
            Item byId = service.getById(5L);
            System.out.println(byId);
        }
    
        @Test
        public void list(){
            List<Item> lists = service.lists();
            System.out.println(lists);
        }
    }
    

三、项目实战中细节问题

1.导入前端资源

1.1静态资源拦截处理

  • 设置访问 index 访问主页

    @Controller
    public class IndexController {
        @RequestMapping("/index")
        public String index(){
            System.out.println("----------------");
            return "/pages/items.html";
        }
    
    }
    
  • 出现静态资源被拦截问题

    @Configuration
    public class StaticSupport extends WebMvcConfigurationSupport {
    
        @Override
        protected void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
            registry.addResourceHandler("/js/**").addResourceLocations("/js/");
            registry.addResourceHandler("/css/**").addResourceLocations("/css/");
            registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    
        }
    }
    
  • 将 staticSupport 交给 SpringMvc 管理

    @Configuration
    @ComponentScan(value = {"cn.sycoder.controller","cn.sycoder.config"})
    @EnableWebMvc
    public class SpringMvcConfig {
    }
    

1.2项目实现

  • 保存方法

    handleAdd () {
        console.log("========")
        axios.post("/item",this.formData).then((res)=>{
            //todo
        })
    },
    
  • 列表查询

    getAll() {
        axios.get("/item",).then((res)=>{
            this.dataList = res.data;
        })
    },
    
  • 删除操作

    handleDelete(row) {
        axios.delete("/item/"+row.id).then((res)=>{
            //todo
        })
    }
    

你可能感兴趣的:(开发语言,java,后端)