算法刷题笔记

Java - SSM 整合案例

2024-06-06  本文已影响0人  Du1in9

👉 在线笔记:https://du1in9.github.io/ssm_demo.github.io/

1 SSM 整合

1.1 整合配置

  1. Spring:Springconfig

    @Configuration
    @ComponentScan({"com.itheima.service"})
    @PropertySource("classpath:jdbc.properties")
    @Import({JdbcConfig.class,MyBatisConfig.class})
    @EnableTransactionManagement // 开启注解式事务驱动
    public class SpringConfig {
    }
    
  2. SpringMVC:Servletconfig、SpringMvcConfig

    public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
        protected Class<?>[] getRootConfigClasses() {
            return new Class[]{SpringConfig.class};
        }
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMvcConfig.class};
        }
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
        @Override
        protected Filter[] getServletFilters() {
            CharacterEncodingFilter filter = new CharacterEncodingFilter();
            filter.setEncoding("UTF-8");
            return new Filter[]{filter};
        }
    }
    
    @Configuration
    @ComponentScan("com.itheima.controller")
    @EnableWebMvc
    public class SpringMvcConfig {
    }
    
  3. MyBatis:MybatisConfig、Jdbcconfig、jdbc.properties

    public class MyBatisConfig {
        @Bean
        public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){
            SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
            factoryBean.setDataSource(dataSource);
            factoryBean.setTypeAliasesPackage("com.itheima.domain");
            return factoryBean;
        }
    
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer(){
            MapperScannerConfigurer msc = new MapperScannerConfigurer();
            msc.setBasePackage("com.itheima.dao");
            return msc;
        }
    }
    
    public class JdbcConfig {
        @Value("${jdbc.driver}")
        private String driver;
        @Value("${jdbc.url}")
        private String url;
        @Value("${jdbc.username}")
        private String username;
        @Value("${jdbc.password}")
        private String password;
    
        @Bean
        public DataSource dataSource(){
            DruidDataSource dataSource = new DruidDataSource();
            dataSource.setDriverClassName(driver);
            dataSource.setUrl(url);
            dataSource.setUsername(username);
            dataSource.setPassword(password);
            return dataSource;
        }
    
        @Bean        // 设置事务管理器
        public PlatformTransactionManager transactionManager(DataSource dataSource){
            DataSourceTransactionManager ds = new DataSourceTransactionManager();
            ds.setDataSource(dataSource);
            return ds;
        }
    }
    
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssm_db?useSSL=false
    jdbc.username=root
    jdbc.password=123456
    

1.2 功能模块

  1. 表与实体类

    CREATE TABLE `tbl_book`  (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
        `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
        `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
        PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    insert into `tbl_book`(`id`, `type`, `name`, `description`)
    values (1, '计算机理论', 'Spring实战 第五版', 'Spring入门经典教程,深入理解Spring原理技术内幕'),
           (2, '计算机理论', 'Spring 5核心原理与30个类手写实践', '十年沉淀之作,手写Spring精华思想'),
           (3, '计算机理论', 'Spring 5设计模式', '深入Spring源码刨析Spring源码中蕴含的10大设计模式'),
           (4, '计算机理论', 'Spring MVC+Mybatis开发从入门到项目实战', '全方位解析面向Web应用的轻量级框架'),
           (5, '计算机理论', '轻量级Java Web企业应用实战', '源码级刨析Spring框架,适合已掌握Java基础的读者'),
           (6, '计算机理论', 'Java核心技术 卷Ⅰ 基础知识(原书第11版)', 'Core Java第11版,Jolt大奖获奖作品'),
           (7, '计算机理论', '深入理解Java虚拟机', '5个纬度全面刨析JVM,大厂面试知识点全覆盖'),
           (8, '计算机理论', 'Java编程思想(第4版)', 'Java学习必读经典,殿堂级著作!赢得了全球程序员的广泛赞誉'),
           (9, '计算机理论', '零基础学Java(全彩版)', '零基础自学编程的入门图书,由浅入深,详解Java语言的编程思想'),
           (10, '市场营销', '直播就这么做:主播高效沟通实战指南', '李子柒、李佳奇、薇娅成长为网红的秘密都在书中'),
           (11, '市场营销', '直播销讲实战一本通', '和秋叶一起学系列网络营销书籍'),
           (12, '市场营销', '直播带货:淘宝、天猫直播从新手到高手', '一本教你如何玩转直播的书,10堂课轻松实现带货月入3W+');
    
    @Data
    public class Book {
        private Integer id;
        private String type;
        private String name;
        private String description;
    }
    
  2. dao(数据层):接口+自动代理

    public interface BookDao {
        @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
        public void save(Book book);
    
        @Update("update tbl_book set type=#{type}, name=#{name}, description=#{description} where id=#{id}")
        public void update(Book book);
    
        @Delete("delete from tbl_book where id = #{id}")
        public void delete(Integer id);
    
        @Select("select * from tbl_book where id = #{id}")
        public Book getById(Integer id);
    
        @Select("select * from tbl_book")
        public List<Book> getAll();
    }
    
  3. service(业务层):接口+实现类

    @Transactional   // 添加 Spring 事务管理
    public interface BookService {
        public boolean save(Book book);
    
        public boolean update(Book book);
    
        public boolean delete(Integer id);
    
        public Book getById(Integer id);
    
        public List<Book> getAll();
    }
    
    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        private BookDao bookDao;
    
        public boolean save(Book book) {
            bookDao.save(book);
            return true;
        }
        public boolean update(Book book) {
            bookDao.update(book);
            return true;
        }
        public boolean delete(Integer id) {
            bookDao.delete(id);
            return true;
        }
        public Book getById(Integer id) {
            return bookDao.getById(id);
        }
        public List<Book> getAll() {
            return bookDao.getAll();
        }
    }
    
  4. controller(表现层)

    @RestController
    @RequestMapping("/books")
    public class BookController {
        @Autowired
        private BookService bookService;
    
        @PostMapping
        public boolean save(@RequestBody Book book) {
            return bookService.save(book);
        }
        @PutMapping
        public boolean update(@RequestBody Book book) {
            return bookService.update(book);
        }
        @DeleteMapping("/{id}")
        public boolean delete(@PathVariable Integer id) {
            return bookService.delete(id);
        }
        @GetMapping("/{id}")
        public Book getById(@PathVariable Integer id) {
            return bookService.getById(id);
        }
        @GetMapping
        public List<Book> getAll() {
            return bookService.getAll();
        }
    }
    

1.3 接口测试

  1. service 接口测试(JUnit)

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfig.class)
    public class BookServiceTest {
        @Autowired
        private BookService bookService;
        @Test
        public void testDeleteById(){
            System.out.println(bookService.delete(2));
        }
        @Test
        public void testGetById(){
            System.out.println(bookService.getById(1));
        }
        @Test
        public void testGetAll(){
            System.out.println(bookService.getAll());
        }
    }
    
  2. controller 接口测试(PostMan)

    post: http://localhost:80/books
    {"type": "def", "name": "123", "description": "abc"}
    
    put: http://localhost:80/books
    {"id": "1", "type": "def", "name": "123", "description": "abc"}
    
    delete: http://localhost:80/books/2
    
    get: http://localhost:80/books/3
    
    get: http://localhost:80/books
    

2 统一结果封装

3 统一异常处理

3.1 异常处理器

3.2 项目异常处理

  1. 自定义异常编码

    public class Code {
        public static final Integer SYSTEM_ERR = 50001;
        public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
        public static final Integer SYSTEM_UNKNOW_ERR = 59999;
        public static final Integer BUSINESS_ERR = 60002;
    }
    
  2. 拦截并处理异常

    package com.itheima.controller;
    
    @RestControllerAdvice
    public class ProjectExceptionAdvice {
        @ExceptionHandler(SystemException.class)
        public Result doSystemException(SystemException ex){
            return new Result(ex.getCode(), null, ex.getMessage());
        }
        @ExceptionHandler(BusinessException.class)
        public Result doBusinessException(BusinessException ex){
            return new Result(ex.getCode(), null, ex.getMessage());
        }
        @ExceptionHandler(Exception.class)
        public Result doOtherException(Exception ex){
            return new Result(Code.SYSTEM_UNKNOW_ERR, null, "系统繁忙,请稍后再试!");
        }
    }
    

4 前后台协议联调

4.1 环境准备

  1. 将静态资源拷贝到 webapp 下,book.html 中的核心代码如下:

    <body>
        <el-button @click="getAll()" class="dalfBut">查询</el-button>
    
        <el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="handleAdd()">确定</el-button>
    
        <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
        <el-button @click="dialogFormVisible4Edit = false">取消</el-button>
        <el-button type="primary" @click="handleEdit()">确定</el-button>
    
        <el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
    </body>
    
    <script>
        var vue = new Vue({
            methods: {
                getAll() {},         // 1. 列表展示
                resetForm() {},          // 重置表单
                handleAdd () {},     // 2. 添加功能
                handleCreate() {},       // 添加窗口
                handleEdit() {},     // 3. 修改功能
                handleUpdate(row) {},    // 编辑窗口
                handleDelete(row) {} // 4. 删除功能
            }
        })
    </script>
    
  2. 因为 SpringMVC 会拦截,所以需要在 SpringConfig 的配置类中将其放行

    @Configuration       
    public class SpringMvcSupport extends WebMvcConfigurationSupport {
        @Override
        protected void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
            registry.addResourceHandler("/css/**").addResourceLocations("/css/");
            registry.addResourceHandler("/js/**").addResourceLocations("/js/");
            registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
        }
    }
    
    @Configuration   
    @ComponentScan({"com.itheima.controller","com.itheima.config"})
    @EnableWebMvc
    public class SpringMvcConfig {
    }
    

4.2 列表展示

  1. 页面的钩子函数 created() 调用了 this.getAll() 方法,使用 axios 发送异步请求从后台获取数据

    getAll() {
        axios.get("/books").then((res)=>{
            this.dataList = res.data.data;
        });
    }
    
  2. 访问 http://localhost/pages/books.html 进行测试

4.3 添加功能

  1. 页面的新建按钮绑定了 @click="handleCreate()" 方法,在方法中打开新增面板

    handleCreate() {
        this.dialogFormVisible = true;
        this.resetForm();
    },
        
    resetForm(){
        this.formData = {};
    }
    

    确定按钮绑定了 @click="handleAdd()" 方法,在方法中发送请求和数据,响应成功后将新增面板关闭并重新查询数据

    handleAdd () {
        axios.post("/books",this.formData).then((res)=>{
            if(res.data.code == 20011){          // 如果操作成功,关闭弹层,显示数据
                this.dialogFormVisible = false;
                this.$message.success("添加成功");
            }else if(res.data.code == 20010){    // 如果操作失败,提示错误信息
                this.$message.error("添加失败");
            }else{
                this.$message.error(res.data.msg);
            }
        }).finally(()=>{
            this.getAll();
        });
    }
    
  2. 后台返回操作结果,将 Dao 层的增删改方法返回值从 void 改成 int

    @Insert("insert into tbl_book (type,name,description) values(#{type},#{name},#{description})")
    public int save(Book book);
    
    @Update("update tbl_book set type=#{type}, name=#{name}, description=#{description} where id=#{id}")
    public int update(Book book);
    
    @Delete("delete from tbl_book where id = #{id}")
    public int delete(Integer id);
    

    在 BookServiceImpl 中,增删改方法根据 Dao 的返回值来决定返回 true/false

    public boolean save(Book book) {
        return bookDao.save(book) > 0;
    }
    public boolean update(Book book) {
        return bookDao.update(book) > 0;
    }
    public boolean delete(Integer id) {
        return bookDao.delete(id) > 0;
    }
    

4.4 编辑功能

  1. 页面中的编辑按钮绑定了 @click="handleUpdate(scope.row)",在方法中根据 ID 查询图书信息

    handleUpdate(row) {
        axios.get("/books/"+row.id).then((res)=>{
            if(res.data.code == 20041){          // 如果查询成功, 打开修改面板回显数据
                this.formData = res.data.data;
                this.dialogFormVisible4Edit = true;
            }else{                               // 如果查询失败, 提示错误信息
                this.$message.error(res.data.msg);
            }
        });
    }
    
  2. handleEdit 方法中发送异步请求提交修改数据

    handleEdit() {
        axios.put("/books",this.formData).then((res)=>{
            if(res.data.code == 20031){          // 如果操作成功,关闭弹层,显示数据
                this.dialogFormVisible4Edit = false;
                this.$message.success("修改成功");
            }else if(res.data.code == 20030){    // 如果操作失败,提示错误信息
                this.$message.error("修改失败");
            }else{
                this.$message.error(res.data.msg);
            }
        }).finally(()=>{
            this.getAll();
        });
    }
    

4.5 删除功能

handleDelete(row) {
    this.$confirm("此操作永久删除当前数据,是否继续?","提示",{
        type:'info'
    }).then(()=>{           // 用户点击确定,发送异步请求, 并携带需要删除数据的主键ID
        axios.delete("/books/"+row.id).then((res)=>{
            if(res.data.code == 20021){     
                this.$message.success("删除成功");
            }else{                          
                this.$message.error("删除失败");
            }
        }).finally(()=>{
            this.getAll();
        });
    }).catch(()=>{          // 用户点击取消,提示操作已经被取消
        this.$message.info("取消删除操作");
    });
}

5 基于 SpringBoot 整合

需求:根据之前的 Spring 案例,实现基于 SpringBoot 的 SSM 整合

  1. config 类:全部删除

  2. dao 类:设置 @Mapper

  3. test 类:设置 @SpringBootTest

  4. pom.xml:配置必要的资源坐标

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    
  5. application.yml:配置数据源、端口等

    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ssm_db
        username: root
        password: 123456
    
  6. static:静态资源,index.html 设置主页

    <script>
        document.location.href="pages/books.html”;
    </script>
    

案例源码:https://wwb.lanzouo.com/ic4f42166e7c

上一篇下一篇

猜你喜欢

热点阅读