SpringBoot学习3(1.1整合案例项目数据层、业务层、表现层)
1.整合第三方技术
1.整合JUnit
target测试类和引导类为什么要有对应关系,如果没有相似的包结构导致出现的问题原因如下:
基础篇-24-整合JUnit——classes属性_哔哩哔哩_bilibili
2.整合MyBatis
创建的时候选上mybatis和sql驱动
创建之后,进入setting修改信息,打开pom.xml修改信息,如javaversion,springboot版本
如果要想用这个2.5.4版本的话,对应的mybatis的version都需要改变,不然会出现报错‘
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>springboot_mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_mybatis</name> <description>springboot_mybatis</description> <properties> <java.version>8</java.version> </properties> <dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter-test</artifactId> <version>2.2.0</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.整合MyBatisPlus
基础篇-27-SpringBoot整合MyBatisPlus_哔哩哔哩_bilibili
4.整合Druid
基础篇-28-SpringBoot整合Druid_哔哩哔哩_bilibili
2.整合案例
数据层、业务层、表现层的结构如下
2.1 创建新项目
先创建一个空项目然后dependencies选择mysql和springweb
项目创建好后,先去看settings-->maven中的路径是否为自己的maven路径
打开pom.xml刷新看javaversion版本和spring-boot-starter-parent版本是否是自己想要的
然后导入mybatisplus和druid
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version> </dependency>
resource里面的application.properties改为yml文件,然后进去配置端口
2.2 创建实体类+lombok
使用lombok
先进入pom.xml导入lombok坐标,在parent里面是有收纳lombok,所以可以不用些版本信息,然后再实体类中就可以不用些一堆的getter、setter等方法了
直接使用@Data,里面就包含了。
这样在实体类中就简化了很多,但是@Data没有包含构造方法。
构造方法:
2.3 配置druid和mybatisplus
进入application.yml中写入相关信息
2.4使用BaseMapper提供的增删改查的方法学习(数据层dao)
在BookDaoTest中直接调用BaseMapper中的方法即可
BookDaoTest.java
package com.example.dao; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.example.entity.Book; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class BookDaoTest { @Autowired private BookDao bookDao; // @Test //1.没使用BaseMapper之前的编写 // void testGetById1(){ // System.out.println(bookDao.getById(1)); // } //2.使用BaseMapper后 //2.1BaseMapper提供的查询方法 @Test void testGetById(){ System.out.println(bookDao.selectById(1)); } //2.2BaseMapper提供的插入数据的方法 @Test void testSave(){ Book book = new Book(); book.setName("aaa"); book.setType("数学"); book.setDescription("abcdefg"); //由于数据库中id是自增的,在application中需要进行指定,因为mybatis生成id的方法和sql不一样 bookDao.insert(book); } //2.3BaseMapper提供的更新数据方法其一:根据id修改数据 @Test void testUpdate(){ Book book = new Book(); book.setId(3); book.setName("aaa"); book.setType("00000000000"); book.setDescription("abcdefg"); bookDao.updateById(book); } //2.4BaseMapper提供的删除数据方法 @Test void testDelete(){ bookDao.deleteById(3); } //2.5获取全部 @Test void testGetAll(){ System.out.println(bookDao.selectList(null)); } //2.6分页:需要依赖拦截器 //链接:https://www.bilibili.com/video/BV15b4y1a7yG?p=37&vd_source=3918c4e379f5f99c5ae95581d2cc8cec // @Test // void testGetPage(){ // // } //2.7按条件查询方式1 QueryWrapper @Test void testGetBy1(){ //这种方法安全性比较低,如果name写错了直接报错 QueryWrapper<Book> qw=new QueryWrapper<>(); qw.like("name","*"); System.out.println(bookDao.selectList(qw)); } //2.8按条件查询方式2 LambdaQueryWrapper @Test void testGetBy2(){ LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>(); lqw.like(Book::getName, "*"); //增加判断条件,如果val不为空则链接 // String name=null;//一般是传递过来的参数,通常使用这种方式。 // lqw.like(name!=null, Book::getName, name); System.out.println(bookDao.selectList(lqw)); } }
2.5业务层1标准开发service
BookService.java、BookServiceImpl.java、BookServiceTest.java(测试类:只一条测试)
package com.example.service; import com.example.entity.Book; import java.util.List; public interface BookService { boolean save(Book book); boolean update(Book book); boolean delete(Integer id); Book getById(Integer id); List<Book> getAll(); }
package com.example.service.impl; import com.example.dao.BookDao; import com.example.entity.Book; import com.example.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; //@Service 用来定义成业务层对应的Bean @Service public class BookServiceImpl implements BookService { //获取数据层的接口 @Autowired private BookDao bookDao; @Override public boolean save(Book book) { //bookDao.insert(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); } }
package com.example.service; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class BookServiceTest { @Autowired private BookService bookService; @Test void testGetById(){ //测试service层提供的方法 System.out.println(bookService.getById(1)); } }
2.6业务层2快速开发service
问题:开发慢,如果Book换成其他实体类,需要修改的地方过多
MyBatisPlus下提供了业务层通用接口(IService<T>)与业务层通用实现类接口(ServiceImpl<M,T>)
可以追加自己想要的方法,用回标准开发的写出该方法即可。
对应IBookService.java、BookServiceImpl.java、BookServiceTest.java
package com.example.service; import com.baomidou.mybatisplus.extension.service.IService; import com.example.entity.Book; public interface IBookService extends IService<Book> { }
package com.example.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.example.dao.BookDao; import com.example.entity.Book; import com.example.service.IBookService; import org.springframework.stereotype.Service; @Service public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService { }
package com.example.service; import com.example.entity.Book; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class BookServiceTest { @Autowired private IBookService iBookService; @Test void testGetById(){ System.out.println(iBookService.getById(1)); } @Test void save(){ Book book = new Book(); book.setName("aaa"); book.setType("数学"); book.setDescription("abcdefg"); iBookService.save(book); } @Test void testUpdate(){ Book book = new Book(); book.setId(4); book.setName("aaa"); book.setType("777777777"); book.setDescription("abcdefg"); iBookService.updateById(book); } @Test void delete(){ iBookService.removeById(3); } }
2.7表现层标准开发controller基于Restful
BookController
package com.example.controller; import com.example.entity.Book; import com.example.service.IBookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/books") public class BookController { //测试查询:需要调用业务层:注入业务层 @Autowired private IBookService iBookService; @GetMapping public List<Book> getAll(){ return iBookService.list(); } @PostMapping public Boolean save(@RequestBody Book book){ return iBookService.save(book); } @PutMapping public Boolean update(@RequestBody Book book){ return iBookService.updateById(book); } @DeleteMapping("{id}") public Boolean delete(@PathVariable Integer id){ return iBookService.removeById(id); } //http:/localhost/books/2 @GetMapping("{id}") public Book getById(@PathVariable Integer id){ return iBookService.getById(id); } }
在application运行
打开postman进行测试
2.8表现层数据的一致性处理
问题提出:返回的类型有boolean类型,写入的数据有json类型,查询全部又有数组+json类型,数据类型很多,不一致。
设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议。
先新建一个utils包,里面新建一个类模型R
package com.example.controller.utils; import lombok.Data; @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; } }
BookController1
package com.example.controller; import com.example.controller.utils.R; import com.example.entity.Book; import com.example.service.IBookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/books") public class BookController1 { //测试查询:需要调用业务层:注入业务层 @Autowired private IBookService iBookService; @GetMapping public R getAll(){ // return iBookService.list(); return new R(true,iBookService.list()); } @PostMapping public R save(@RequestBody Book book){ return new R(iBookService.save(book)); } @PutMapping public R update(@RequestBody Book book){ return new R(iBookService.updateById(book)); } @DeleteMapping("{id}") public R delete(@PathVariable Integer id){ return new R(iBookService.removeById(id)); } //http:/localhost/books/2 @GetMapping("{id}") public R getById(@PathVariable Integer id){ return new R(true,iBookService.getById(id)); } }