springboot框架(9):SSMP综合开发

文章目录

  • 前言
  • 操作步骤
    • 准备说明 数据库
    • 第一节 构建模块
    • 第二节 实体类的开发(lombok)
    • 第三节 数据层开发CRUD
      • 1. 基本开发
      • 2. 分页查询
      • 3. 条件查询
    • 第四节 业务层开发
      • 1. 传统写法
      • 2. 基于MyBatisPlus快速开发
      • 3. 总结
    • 第五节 表现层标准开发
    • 第六节 表现层数据一致处理
    • 第七节 异常处理

前言

ssmp综合开发

操作步骤

准备说明 数据库

准备了数据表book里的数据
springboot框架(9):SSMP综合开发_第1张图片

第一节 构建模块

  1. 创建模块,并选择组件Spring Web和Mysql Driver
    springboot框架(9):SSMP综合开发_第2张图片
    springboot框架(9):SSMP综合开发_第3张图片

第二节 实体类的开发(lombok)

  1. 引入依赖
<dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
  1. 编辑实体类
import lombok.Data;

@Data
public class Book {

    private Integer id;

    private String type;

    private String name;

    private String description;

}

第三节 数据层开发CRUD

1. 基本开发

  1. 引入依赖mybatis-plus和druid
 
        <dependency>
            <groupId>com.baomidougroupId>
            <artifactId>mybatis-plus-boot-starterartifactId>
            <version>3.4.3version>
        dependency>   
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.2.9version>
        dependency>
  1. 添加数据库的配置
spring:
  datasource:
    druid:
      url: jdbc:mysql://127.0.0.1:3306/mydb?characterEncoding=UTF-8&useSSL=false
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl  #开启日志标注输出

  1. 创建dao

方法一:自己实现方法

@Mapper
public interface BookDao  {

    @Select("select * from book where id=#{id}")
    Book getById(Integer id);
}

方法二: 使用mybatis-plus提供的方法(推荐)

@Mapper
public interface BookDao extends  BaseMapper<Book> {

//    @Select("select * from book where id=#{id}")
//    Book getById(Integer id);
}

可以看到继承BaseMapper之后,已经实现了很多方法。
springboot框架(9):SSMP综合开发_第4张图片

  1. 测试
@SpringBootTest
public class BookDaoTest {

    @Autowired
    private BookDao bookDao;
    @Test
    void testGetById(){
        System.out.println(bookDao.selectById(2));

    }
}

springboot框架(9):SSMP综合开发_第5张图片

  1. 测试新增
 @Test
    void testSave(){
        Book book=new Book();
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据");

        bookDao.insert(book);
    }

由于book表的id是自增的,所以这里需要配置id生成策略

mybatis-plus:
  global-config:
    db-config:
      id-type: auto  #数据库id自增

此时再执行testSave,可以看到数据增加了一条数据
在这里插入图片描述

  1. 依照上面的操作,测试其他方法
@SpringBootTest
public class BookDaoTest {

    @Autowired
    private BookDao bookDao;
    @Test
    void testGetById(){
        System.out.println(bookDao.selectById(2));

    }

    @Test
    void testSave(){
        Book book=new Book();
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据");

        bookDao.insert(book);
    }

    @Test
    void testUpdate(){
        Book book=new Book();
        book.setId(17);
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据-----");

        bookDao.updateById(book);
    }

    @Test
    void testDelete(){
        bookDao.deleteById(14);
    }

    @Test
    void testGetAll(){
        System.out.println( bookDao.selectList(null));
    }
}

2. 分页查询

mybatis-plus分页查询是通过拦截器实现的

  1. 新建拦截器
@Configuration
public class MPConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor=new MybatisPlusInterceptor();//MybatisPlus拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());//分具体的页查询
        return mybatisPlusInterceptor;
    }
}
  1. 编辑代码
   @Test
    void testGetPage(){
        IPage<Book> page=new Page<>(1,5);
        bookDao.selectPage(page,null);
    }
  1. 测试
    springboot框架(9):SSMP综合开发_第6张图片

selectPage返回的是page本身,可以看到从page里面获取到current当前页,总页数,records查出来的数据,size查出来的数量,total总数
springboot框架(9):SSMP综合开发_第7张图片

3. 条件查询

  • 使用QueryWrapper查询
 @Test
    void testGetByCondition(){
        QueryWrapper<Book> qw=new QueryWrapper<>();
        qw.like("name","java");
        bookDao.selectList(qw);
    }

springboot框架(9):SSMP综合开发_第8张图片

  • 使用LambdaQueryWrapper
@Test
    void testGetByCondition2(){
        LambdaQueryWrapper<Book> qw=new LambdaQueryWrapper<>();
        qw.like(Book::getName,"spring");
        bookDao.selectList(qw);

    }

springboot框架(9):SSMP综合开发_第9张图片
但是如果name为null时,这里会出错,只有name不为null时条件才生效,如下。

  @Test
    void testGetByCondition2(){
        String name="spring";
        LambdaQueryWrapper<Book> qw=new LambdaQueryWrapper<>();
        qw.like(null!=name,Book::getName,name);
        bookDao.selectList(qw);

    }

第四节 业务层开发

业务层和数据层属于不同性质,业务层的命名规则与业务相关联,例如login,而数据层的接口则体现数据的性质,例如selectByUserNameAndPwd。

1. 传统写法

  1. 定义Service和实现类
public interface BookService {

    boolean  save(Book book);

    boolean update (Book book);

    boolean delete(Integer id);

    Book getById(Integer id);

    List<Book> getAll();

}
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao;

    @Override
    public boolean save(Book book) {
        return bookDao.insert(book)>0;
    }

    @Override
    public boolean update(Book book) {
        return bookDao.updateById(book)>0;
    }

    @Override
    public boolean delete(Integer id) {
        return bookDao.deleteById(id)>0;
    }

    @Override
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }

    @Override
    public List<Book> getAll() {
        return bookDao.selectList(null);
    }
}

  1. 编写测试用例并运行
@SpringBootTest
public class BookServiceTest {

    @Autowired
    private BookService bookService;

    @Test
    void testGetById(){
        System.out.println(bookService.getById(1));
    }
}

springboot框架(9):SSMP综合开发_第10张图片

  1. 其他测试用例
@Test
    void testSave(){
        Book book=new Book();
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据");

        bookService.save(book);
    }

    @Test
    void testUpdate(){
        Book book=new Book();
        book.setId(17);
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据-----");

        bookService.update(book);
    }

    @Test
    void testDelete(){
        bookService.delete(14);
    }

    @Test
    void testGetAll(){
        System.out.println( bookService.getAll());
    }

2. 基于MyBatisPlus快速开发

很明显传统的开发方式比较简单,但是很繁琐。

  1. 定义接口和实现类
public interface IBookService extends IService<Book> {

}

@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
}
  1. 编写测试用例
@SpringBootTest
public class BookServiceTest {

    @Autowired
    private IBookService bookService;

    @Test
    void testGetById(){
        System.out.println(bookService.getById(1));
    }

    @Test
    void testSave(){
        Book book=new Book();
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据");

        bookService.save(book);
    }

    @Test
    void testUpdate(){
        Book book=new Book();
        book.setId(17);
        book.setName("测试");
        book.setType("测试");
        book.setDescription("测试 数据-----");

        bookService.updateById(book);
    }

    @Test
    void testDelete(){
        bookService.removeById(14);
    }

    @Test
    void testGetAll(){
        System.out.println( bookService.list());
    }

    @Test
    void testGetPage(){
        IPage page =new Page(2,5);
        bookService.page(page);
        System.out.println(page.getCurrent());
        System.out.println(page.getSize());

    }

}
  1. 运行测试用例
    springboot框架(9):SSMP综合开发_第11张图片

3. 总结

传统方式编码需要将各种方法都编写一遍,比较繁琐。基于MyBatisPlus开发后,它已经帮你实现了大量的常用方法,只需要简单的继承即可使用。MyBatis-Plus已经集成了如下方法(如下图)。
springboot框架(9):SSMP综合开发_第12张图片
使用步骤,接口集成IService,实现类ServiceImpl,如下图
springboot框架(9):SSMP综合开发_第13张图片

如果MyBatis-Plus已经提供的方法不能满足需求,则可以自己定义方法和实现方式,但是通常自己定义的方法不应该覆盖MyBatisPlus提供的方法和实现,例如MyBatis-Plus提供的save(),则自己定义的方法不应该与save同名。

第五节 表现层标准开发

  1. 新增分页开发
public interface IBookService extends IService<Book> {

    IPage<Book> getPage(int currentPage,int pageSize);

}
@Service
public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {

    @Autowired
    private  BookDao bookDao;

    @Override
    public IPage<Book> getPage(int currentPage, int pageSize) {
        IPage<Book> page=new Page<>(currentPage,pageSize);
        bookDao.selectPage(page,null);
        return page;
    }
}
  1. 表现层开发
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private IBookService bookService;

    @GetMapping
    public List<Book> getAll(){
        return  bookService.list();
    }

    @PostMapping
    public Boolean save(@RequestBody  Book book){
        return bookService.save(book);
    }

    @PutMapping
    public Boolean update(@RequestBody  Book book){
        return bookService.updateById(book);
    }

    @DeleteMapping("{id}")
    public Boolean delete(@PathVariable Integer id){
        return bookService.removeById(id);
    }

    @GetMapping("{id}")
    public Book getById(@PathVariable  Integer id){
        return bookService.getById(id);
    }

    @GetMapping("{currentPage}/{pageSize}")
    public IPage<Book> getPage(@PathVariable int currentPage,@PathVariable int pageSize){
       return  bookService.getPage(currentPage,pageSize);
    }
}
  1. 启动项目,使用postman测试(以下仅列出部分postman测试截图)
    (1)查询单个
    springboot框架(9):SSMP综合开发_第14张图片
    (2)添加
    springboot框架(9):SSMP综合开发_第15张图片
    (3)分页
    springboot框架(9):SSMP综合开发_第16张图片

总结
Restful制作表现层接口
新增POST
删除DELETE
修改PUT
查询GET
参数接收
实体数据 @RequestBody
springboot框架(9):SSMP综合开发_第17张图片

路径变量: @PathVariable
在这里插入图片描述

第六节 表现层数据一致处理

表现层消息一致性处理
设计表现消息一致性的模型,用于处理前后端进行数据格式统一

@Data
public class R {
    private Boolean flag;
    private Object data;
}

实践步骤

  1. 定义R对象
@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;
    }

}
  1. 修改controller
@RestController
@RequestMapping("/books")
public class BookController {

    @Autowired
    private IBookService bookService;

    @GetMapping
    public R getAll(){
        return  new R(true,bookService.list());
    }

    @PostMapping
    public R save(@RequestBody  Book book){
        return new R(bookService.save(book));
    }

    @PutMapping
    public R update(@RequestBody  Book book){
        return new R(bookService.updateById(book));
    }

    @DeleteMapping("{id}")
    public R delete(@PathVariable Integer id){
        return new R(bookService.removeById(id));
    }

    @GetMapping("{id}")
    public R getById(@PathVariable  Integer id){
        return new R(true,bookService.getById(id));
    }

    @GetMapping("{currentPage}/{pageSize}")
    public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
       return  new R(true,bookService.getPage(currentPage,pageSize));
    }
}
  1. 启动项目,使用postman测试,此时可以看到返回结果统一为R对象。
    springboot框架(9):SSMP综合开发_第18张图片

第七节 异常处理

当controller出现异常时,可能会弹出不同的出错消息,此时定义统一的异常处理拦截。

定义统一的异常拦截

/**
 * 用于springmvc的异常处理器
 */
@RestControllerAdvice
public class ProjectExceptionAdvice {

    @ExceptionHandler(Exception.class)
    public R doException(Exception e){
        e.printStackTrace();
        return new R("数据处理异常");
    }

    /**
     * 也可以拦截其他异常
     */
//    @ExceptionHandler(MyException.class)
//    public R doException2(Exception e){
//        e.printStackTrace();
//        return new R("数据处理异常");
//    }

}

你可能感兴趣的:(springboot,spring,boot,java,spring)