SSMP整合案例 前后端分离版(附前后端分离解决跨域问题)

本文介绍了如何基于SpringBoot项目集成Mybatis-plus和Druid,利用Lombok简化实体类,完成基础的CRUD操作。还涉及到了Mybatis-plus的分页查询、条件查询以及业务层和服务层的快速开发。最后提到了前后端分离时的跨域问题及其解决方案。
摘要由CSDN通过智能技术生成

SSMP开发

本篇笔记基于黑马程序员的SpringBoot教学视频,具体视频链接:黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战

创建项目

SpringMVC+SpringBoot+Mybatis-plus

勾选web、sql即可,其余手动装配

  1. Mybatis-plus

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>
  1. Druid

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.2.15</version>
    </dependency>
  1. lombok

    <!-- 还需要安装lombok插件 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.18</version>
    </dependency>

创建实体Dao类和domain类

使用lombok技术快速封装Getter和Setter方法

@Data
public class Book {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

基础CRUD

  1. 使用Mybatis-plus让Dao类继承BaseMapper进行快速开发

@Mapper
@Repository
public interface BookDao extends BaseMapper<Book> {}
  1. 在测试类中测试是否生效

@SpringBootTest
public class BookDaoTestCase {
    @Autowired
    private BookDao bookDao;

    @Test
    void getBookById() {
        System.out.println(bookDao.selectById(1));
    }

    @Test
    void save() {
        Book book = new Book();
        book.setName("test123");
        book.setType("test123");
        book.setDescription("test123");

        bookDao.insert(book);
    }

    @Test
    void update() {
        Book book = new Book();
        book.setId(13);
        book.setName("测试测试");
        book.setType("测试测试");
        book.setDescription("测试测试");

        bookDao.updateById(book);
    }

    @Test
    void delete() {
        bookDao.deleteById(13);
    }

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

Mybatis-plus配置

mybatis-plus:
  global-config:
    db-config:
      # 表头名称
      table-prefix: tbl_
      # id设置自增需要进行该设置
      id-type: auto
  configuration:
      # 日志打印方式配置
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

分页查询

通过Mybatis-plus内置的方法selectPage(Page, queryWrapper);进行设置分页数据请求

设置分页数据请求的时候需要进行配置类设置拦截器。

前端更方便的做法是先获取全部数据,再在element-ui等组件中设置current(第几页)、size(每页有几个数据)即可。
    @Test
    void getByPage() {
        IPage page = new Page(1, 5);
        bookDao.selectPage(page, null);
    }

通过配置类设置拦截器

Mybatis-plus的配置类

通过该配置类设置拦截器能够完成分页操作

//有这个注解存在能被扫描到
@Configuration
public class MPConfig {
    @Bean
    public MybatisPlusInterceptor MybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

Page可调用的方法

在前面创建了Page实例之后,我们可以调用实例的方法进行操作

  1. page.getCurrent():获取现在第几页

  1. page.getSize():获取每页几个数据

  1. page.getPages():获取总页数

  1. page.getTotal():获取数据总数

  1. page.getRecords():获取全部数据

条件查询

使用QueryWrapper/LambdaQueryWrapper进行条件查询

//使用QueryWrapper进行条件查询,需要使用字符串,容易出错,不推荐,对应SQL语句:Preparing: SELECT id,type,name,description FROM tbl_book WHERE (name LIKE %Spring%)
@Test
void getByDetail() {
    QueryWrapper<Book> qw = new QueryWrapper<>();
    qw.like("name", "Spring");
    bookDao.selectList(qw);
}

//使用LambdaQueryWrapper进行条件查询,可以通过调用来减少出错,推荐,对应SQL语句同上
@Test
void getByDetail2() {
    String name = "Spring";
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
    lqw.like(Book::getName, name);
    bookDao.selectList(lqw);
}

//当数据为null的时候的查询不会进行条件查询,而是返回所有的数据,对应SQL语句:SELECT id,type,name,description FROM tbl_book
@Test
void getByDetail3() {
    String name = null;
    LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
    lqw.like(name != null, Book::getName, lqw);
    bookDao.selectList(lqw);
}

业务层

这个是SpringMVC比较慢的方式,Mybatis-plus提供了更快的方式给我们进行开发。
  1. 定义业务层接口BookService

public interface BookService {
    boolean save(Book book);

    boolean update(Book book);

    boolean delete(Integer id);

    Book getById(Integer id);

    List<Book> getAll();

    IPage getByPage(Integer current, Integer size);
}
  1. 定义业务层实现类BookServiceImpl,实现业务层接口

// 必须要这个@Service注解
@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);
    }

    @Override
    public IPage getByPage(Integer current, Integer size) {
        IPage page = new Page(current, size);

        return bookDao.selectPage(page, null);
    }
}
  1. 测试类测试是否可行

@SpringBootTest
public class BookDaoTestCase {

    @Autowired
    private BookService bookService;

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

    @Test
    void save() {
        Book book = new Book();
        book.setName("test123");
        book.setType("test123");
        book.setDescription("test123");

        bookService.save(book);
    }

    @Test
    void update() {
        Book book = new Book();
        book.setId(16);
        book.setName("测试测试");
        book.setType("测试测试");
        book.setDescription("测试测试");

        bookService.update(book);
    }

    @Test
    void delete() {
        bookService.delete(15);
    }

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

    @Test
    void getPage(){
        System.out.println(bookService.getByPage(2, 5));
    }
}

快速开发业务层

使用Mybatis-plus提供的方式可以实现快速开发业务层

  1. 业务层接口继承IService<Book>

业务可以自己进行扩展,但是尽量不要重写原来的方法

public interface IBookService extends IService<Book> {
    // 可以自己进行扩展,但是尽量不要重写原来的方法
    Book getBookByBookId(Integer id);
}
  1. 业务层实现类实现IBookService接口,并继承ServiceImpl<BookDao, Book>

之前在接口定义的方法要自己重写

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

    @Autowired
    private BookDao bookDao;

    public Book getBookByBookId(Integer id) {
        return bookDao.selectById(id);
    }
}
  1. 测试类测试是否可行

@SpringBootTest
public class BookServiceTestCase_MP {
    @Autowired
    private IBookService iBookService;

    @Test
    void getBookById() {
        System.out.println(iBookService.getById(1));
    }

    @Test
    void save() {
        Book book = new Book();
        book.setName("test123");
        book.setType("test123");
        book.setDescription("test123");

        iBookService.save(book);
    }

    @Test
    void update() {
        Book book = new Book();
        book.setId(16);
        book.setName("测试测试123");
        book.setType("测试测试123");
        book.setDescription("测试测试123");

        iBookService.updateById(book);
    }

    @Test
    void delete() {
        iBookService.removeById(17);
    }

    @Test
    void getAll() {
        System.out.println(iBookService.list());
    }

    @Test
    void getPage(){
        IPage page = new Page<Book>(3, 5);
        System.out.println(iBookService.page(page));
    }

    @Test
    void getBookByBookId(){
        iBookService.getBookByBookId(2);
    }
}

控制层开发

教程中叫表现层,个人习惯不同我管他叫控制层Controller

写控制层代码和写测试类代码差不多,只是需要运用RESTful语法并Postman进行接口测试。

  1. Controller类

@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private IBookService iBookService;

    @GetMapping("/{id}")
    public Result getBookById(@PathVariable Integer id) {
        return new Result(true, iBookService.getById(id));
    }

    @GetMapping
    public Result getAll(){
        return new Result(true, iBookService.list());
    }

    @PostMapping
    public Result save(@RequestBody Book book){
        return new Result(iBookService.save(book));
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id){
        return new Result(iBookService.removeById(id));
    }

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

    @GetMapping("/{current}/{size}")
    public Result getByPage(@PathVariable Integer current, @PathVariable Integer size){
        return new Result(true, iBookService.getByPage(current, size));
    }
}
  1. 运行SpringBoot启动类

  1. 使用Postman进行测试

数据一致性

前端在获取数据的时候需要获取一定格式的数据,这个时候可以使用工具类Result

// 不能漏这个注解
@Data
public class Result {
    private Object data;
    private boolean flag;

    public Result(boolean flag) {
        this.flag = flag;
    }

    public Result(boolean flag, Object data) {
        this.data = data;
        this.flag = flag;
    }
}

返回的代码分为两部分,数据及状态码如图:

实际开发中并不会使用boolean类型作为状态码,而是类似于404、502等作为状态码。

前后端接口调用(前后端分离模式)

前端结构

https://gitee.com/Lindaxia1026/SSMP_vue.git

后端结构

https://gitee.com/Lindaxia1026/SSMP_SpringBoot.git

前后端分离跨域问题

什么是跨域?

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

该项目后端服务器是:http://localhost(浏览器默认端口号,即http://localhost:80)

前端服务器是:http://localhost:8080

两者的端口号不同所以造成了跨域

解决前后端分离跨域问题

方式一:

在每个controller类中加入@CrossOrigin注解(亲测有效)

// 用于前后端分离项目解决跨域问题
@CrossOrigin
public class BookController {}

方式二:

在 Controller的基类中加上 @CrossOrigin 注解然后其他 Controller 类就有了这个 @Controller

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值