SpringBoot基础篇(二)

整合第三方技术

整合JUnit

@SpringBootTest

  • 类型:测试类注解

  • 位置测试类定义上方

  • 作用:设置Junit加载的SpringBoot启动类

    @SpringBootTest
    class SpringbootJunitApplicationTests {}
    
    • classes:设置SpringBoot启动类

      • 如果测试类不在引导类所在的包或者子包中需要通过classes属性指定引导类
      @SpringBootTest(classes = SpringbootJunitApplicationTests.class)
      class SpringbootJunitApplicationTests {}
      
整合MyBatis
  • 核心配置:数据库链接相关信息

  • 映射配置:SQL映射(XML/注解)

  • 设置Application.yml链接SQL

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/数据库名
        username: SQL账号
        password: SQL密码
    
  • 选择依赖项:

    • Mybatis Framework
    • MySQL Driver
  • 编写字段表,如:

    // 需要导入Lombok依赖
    @Data
    public class User{
        private Integer id;
        private String type;
        private String name;
    }
    
  • 定义数据层接口与映射配置

    @Mapper
    public interface UserMapper {
        @Select("select * from 表名")
        Book getAll();
    }
    
  • 测试类中注入dao接口,测试功能

    @SpringBootTest
    class SpringbootMybatisApplicationTests {
        @Autowired
        private UserMapper userMapper;
        @Test
        void contextLoads() {
            System.out.println(UserMapper.getAll());
        }
    
    }
    
MySQL配置问题
  1. MySQL 8.x驱动强制要求设置时区
    • 修改rul,添加sererTimezone设定

      url: jdbc:mysql://localhost:3306/ssm_db?sererTimezone = utf
      
    • 修改MySQL数据库配置

  2. 驱动类过时,提醒更换为:com.mysql.cj.jdbc.Driver

整合MyBatis-Plus
  • MyBatis-plus与MyBatis区别
    • 导入坐标不同
    • 数据层实现简化
  1. 手动添加SpringBoot整合MyBatis-Plus坐标,可以通过mvnrepository获取

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>
    
  2. 定义数据层接口与映射配置,继承BaseMapper

    @Mapper
    public interface BookMapper extends BaseMapper<Book> {
    }
    
整合Druid
  1. 需要导入Druid对应的starter

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.8</version>
    </dependency>
    
  2. 根据Druid提供的配置方式进行配置(不加默认使用Hikari)

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ssm_db
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
    

    或者

    spring:
      datasource:
      	druid:
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/ssm_db
            username: root
            password: root
    
  3. 整合第三方技术通用方式

    • 导入对应的starter
    • 根据提供的配置格式,配置非默认值对应的配置项

基于SpringBoot的SSMP整合案例

  1. 实体类开发——使用Lombok快速制作实体类
  2. Dao开发——整合MyBatisPlus,制作数据层测试
  3. Service开发——基于MyBatisPlus进行增量开发,制作业务层测试类
  4. Controller开发——基于Restful开发,使用PostMan测试接口功能
  5. Controller开发——前后端开发协议制作
  6. 页面开发——基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
    • 列表
    • 新增
    • 修改
    • 删除
    • 分页
    • 查询
  7. 项目异常处理
  8. 按条件查询————页面功能调整、Controller修正功能、Service修正功能
数据层开发
  • 配置数据源与MyBatisPlus对应的基础配置

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ssm_db
        username: root
        password: root
        type: com.alibaba.druid.pool.DruidDataSource
    
    mybatis-plus:
      global-config:
        db-config:
          table-prefix: tbl_
          id-type: auto
    
  • 继承BaseMapper并指定泛型

    @Mapper
    public interface BookMapper extends BaseMapper<Book> {}
    
  • 制作测试类测试结果

    @SpringBootTest
    class Springboot07SsmpApplicationTests {
        @Autowired
        private BookMapper bookMapper;
        @Test
        void contextLoads() {
            System.out.println(bookMapper.selectById(1));
        }
        @Test
        void testSave(){
            Book book = new Book();
            book.setName("张三");
            book.setType("张三");
            book.setDescription("张三");
            bookMapper.insert(book);
        }
        @Test
        void testUpdate(){
            Book book = new Book();
            book.setId("输入需要更改的id");
            book.setName("张三123");
            book.setType("张三123");
            book.setDescription("张三123");
            bookMapper.updateById(book);
        }
        @Test
        void testDelete(){
            bookMapper.deleteById(58007553);
        }
        @Test
        void testGetAll(){
            System.out.println(bookMapper.selectList(null));
        }
        ……
    }
    
开启MP运行日志
  • 方便调试可以开启MyBatisPlus日志

    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
数据层开发——分页功能
  • 分页操作需要设定分页对象Page

    @Test
    void testGetPage(){
        Page<Book> page = new Page<>(1, 5);
        System.out.println(bookMapper.selectPage(page,null));
    }
    
  • 分页操作是在MyBatisPlus的上操作的,内部是动拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现

    @Configuration
    public class MPConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
            mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return mybatisPlusInterceptor;
        }
    }
    
数据层开发——查询功能
  • 使用QueryWrapper对象封装查询条件,推荐使用LambdaQueryWrapper对象

    @Test
    void testGetBy(){
        QueryWrapper<Book> qw = new QueryWrapper<>();
        qw.like("name","spring");
        bookMapper.selectList(qw);
    }
    
    @Test
    void testGetBy2(){
        LambdaQueryWrapper<Book> qw = new LambdaQueryWrapper<>();
        String name = null;
        qw.like(name != null,Book::getName,name);
        bookMapper.selectList(qw);
    }
    
业务层开发

业务层标准开发——CRUD构建
  • 接口定义

    public interface BookService {
        Book getById(Integer id);
        List<Book> getAll();
        IPage<Book> getPage(int currentPage,int pageSize);
    }
    
  • 实现类定义

    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        private BookMapper bookMapper;
        @Override
        public Book getById(Integer id) {
            return bookMapper.selectById(id);
        }
        @Override
        public List<Book> getAll() {
            return bookMapper.selectList(null);
        }
        @Override
        public IPage<Book> getPage(int currentPage, int pageSize) {
            IPage<Book> bookIPage = new Page<Book>(currentPage, pageSize);
            bookMapper.selectPage(bookIPage,null);
            return bookIPage;
        }
    }
    
  • 测试类定义

    @SpringBootTest
    public class BookServiceTestCase {
        @Autowired
        private BookService bookService;
        @Test
        void testGetById(){
            System.out.println(bookService.getById(1));
        }
        @Test
        void testGetAll(){
            System.out.println(bookService.getAll());
        }
        @Test
        void testGetPage(){
            IPage<Book> page = bookService.getPage(1, 5);
            System.out.println(page);
            System.out.println(page.getRecords());
        }
    }
    
业务层快速开发——MyBatisPlus构建
  • 快速开发方案

    • 使用MyBatisPlus提供有业务层通用接口 (IService<T>) 与业务层通用实现类 (ServiceImpl<M,T>)
    • 在通用类基础上做功能重载或功能追加
    • 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
  • 接口定义

    public interface BookIService extends IService<Book> {
        // 追加的操作与原始操作通过命名区分
    }
    
  • 实现类定义

    @Service
    public class BookIServiceImpl extends ServiceImpl<BookMapper, Book> implements BookIService {
        // 在BookIService类追加的操作,在此类追加功能
    }
    
表现层开发
  • 基于Restful进行表现层接口开发
  • 使用Postman测试表现层接口功能
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookIService bookIService;
    @GetMapping
    public List<Book> getAll(){
        return bookIService.list();
    }
    ……
}
  1. 基于Restful制作表现层接口
    • 新增:POST
    • 删除:DELETE
    • 修改:PUT
    • 查询:GET
  2. 接收参数
    • 实体数据:@RequestBody
    • 路径变量:@pathVariable
表现层信息——一致性处理
  • 设计表现层返回结果的模型类,用于后端与前端进行数据格式统一

    @Data
    public class R {
        private Boolean flag;
        private Object data;
        public R(){}
        public R(Boolean flag){
    		this.flag = flag;
        }
        public R(Boolean flag,Object data){
            this.flag = flag;
            this.data = data;
        }
    }
    
  • 表现层接口统一返回值类型结果

    @RestController
    @RequestMapping("/books")
    public class BookController {
        @Autowired
        private BookIService bookIService;
        @PostMapping
        public R save(@RequestBody Book book){
            return new R(bookIService.save(book));
        }
        @GetMapping
        public R getAll(){
            return new R(true,bookIService.list());
        }
    }
    
  • 业务操作成功或失败返回数据格式

    {
        "flag": true/false,
        "data": null
    }
    
  • 后台代码BUG导致数据格式不统一性

    {
        "timestamp": "2023-01-11T04:39:12.424+00:00",
        "status": 500,
        "error": "Internal Server Error",
        "path": "/books"
    }
    
前后端协议联调(略)
  1. 前后端分离结构设计中页面归属前端服务器
  2. 单体工程页面放置在resources目录下的static目录中(建议执行clean)
弹出添加窗口
handleCreate() {
    // 重置表单
    this.resetForm();
    this.dialogFormVisible = true;
},
清除数据
// 重置表单
resetForm() {
    this.formData = {};
},
添加
//添加
handleAdd () {
    // 发送异步请求
    axios.post("/books",this.formData).then((res) =>{
        //如果操作成功,关闭弹层,显示数据
        if (res.data.flag){
            // 1.关闭弹层
            this.dialogFormVisible = false;
            this.$message.success("添加成功");
        }else {
            this.$message.error("添加失败");
        }
    }).finally(()=>{
        // 2.重新加载数据
        this.getAll();
    });
},
取消添加
//取消
cancel(){
    this.dialogFormVisible = false;
    this.$message.info("操作取消");
},
删除
// 删除
handleDelete(row) {
    console.log(row);
    this.$confirm("此操作永久删除当前信息,是否继续?","提示",{type: "info"}).then(()=>{
        axios.delete("/books/"+row.id).then((res)=>{
            if (res.data.flag){
                this.$message.success("删除成功");
            }else {
                this.$message.error("删除失败");
            }
        }).finally(()=>{
            this.getAll();
        })
    }).catch(()=>{
        this.$message.info("取消操作");
    })
},
弹出编辑窗口
//弹出编辑窗口
handleUpdate(row) {
    // 发送异步请求
    axios.get("/books/"+row.id).then((res)=>{
        if (res.data.flag && res.data.data != null){
            this.dialogFormVisible4Edit = true;
            this.formData = res.data.data;
        }else {
            this.$message.error("数据同步失败,自动刷新");
        }
    }).finally(()=>{
        this.getAll();
    });
},
修改
  • 修改

    //修改
    handleEdit() {
        axios.put("/books",this.formData).then((res) =>{
            if (res.data.flag){
                // 1.关闭弹层
                this.dialogFormVisible4Edit = false;
                this.$message.success("修改成功");
            }else {
                this.$message.error("修改失败");
            }
        }).finally(()=>{
            // 2.重新加载数据
            this.getAll();
        });
    },
    
  • 取消添加

    //取消
    cancel(){
        this.dialogFormVisible = false;
        //添加修改弹窗
        this.dialogFormVisible4Edit = false;
        this.$message.info("操作取消");
    },
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值