案例实现方案分析
实体类开发————使用Lombok快速制作实体类
Dao开发————整合MyBatisPlus,制作数据层测试类
Service开发————基于MyBatisPlus进行增量开发,制作业务层测试类
Controller开发————基于Restful开发,使用PostMan测试接口功能,前后端开发协议制作
页面开发————基于VUE+ElementUI制作,前后端联调,页面数据处理,页面消息处理
列表、新增、修改、删除、分页、查询
项目异常处理
按条件查询————页面功能调整、Controller修正功能、Service修正功能
数据库创建
实体类开发
@Data public class Book { private Integer id; private String type; private String name; private String description; }
数据层开发
基本开发
@Mapper public interface BookDao extends BaseMapper<Book> { }
MyBatisPlus
Druid – 默认使用的是日本的一个叫做 光 的数据库
手工导入两个坐标
<!-- 使用mp--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3</version> </dependency> <!-- 使用druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version> </dependency>
配置文件
server: port: 80 spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC username: root password: 123456 mybatis-plus: global-config: db-config: table-prefix: tbl_ id-type: auto
继承BaseMapper并指定泛型
@Mapper就可以不用写实体类,编译运行的时候就会自动生成 继承 extends BaseMapper 里面要写对应实体类 就是要操作哪一个bean对象。 @Repository // 这个注释就是将bean对象存放到Spring容器中 @Mapper // 这个注解就是编译的时候会自动生成实体类 public interface BookDao extends BaseMapper<Book> { }
开发流程
手工导入starter坐标(2个) 一个是mp坐标,一个是druid
配置数据源与MyBatisPlus对应的配置 – 配置坐标不知道的信息,比如哪一个数据库,数据库账号和密码
开发Dao接口(继承BaseMapper)-- 继承这个类之后,就相当于产生了很多种已经写好的方法了。直接调用即可。
制作测试类测试Dao功能是否有效
为方便调试可以开启MyBatisPlus的日志
mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
分页功能
分页操作需要设定分页对象IPage
@Test void testGetPage(){ IPage page = new Page(1,5); bookDao.selectPage(page,null); }
bookDao中有一个方法叫做selectPage的方法,就可以实现分页效果,一个参数是Ipage对象,一个参数对象是null;
Ipage对象的参数是 第一个参数指的是显示第几页信息,第二个参数指的是一页展示几条数据。
selectPage返回对象就是上面定义的page对象。
System.out.println(page.getRecords());
还需要注意的是,需要再写一个拦截器。分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现。
package com.itheima.config; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MPConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } }
查询功能
推荐使用LambdaQueryWrapper对象,所有查询操作封装成方法调用
// 条件查询功能 @Test void testGetByCondition() { LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper(); String name = "Spring"; lqw.like(name != null ,Book::getName , name); bookDao.selectList(lqw); }
还有一个方法就是可以通过id直接查询到对象信息。
// 测试通过id进行查询 @Test void contextLoads() { System.out.println(bookDao.selectById(1)); }
还有一个获取全部信息的功能。
// 获取数据库的全部资料 @Test void testGetAll() { System.out.println(bookDao.selectList(null)); }
增删改
增
// 测试增加数据 @Test void testSave() { Book book = new Book(); book.setType("测试"); book.setName("测试"); book.setDescription("测试"); bookDao.insert(book); }
删除 – 通过id进行数据删除
// 通过id删除数据 @Test void testDelete() { bookDao.deleteById(10); }
更新 – 通过id修改数据信息,参数是Book对象,但是修改是通过id索引的。所以必须要写出id。
// 测试修改数据 @Test void testUpdate() { Book book = new Book(); book.setId(10); book.setType("测试"); book.setName("测试"); book.setDescription("测试"); bookDao.updateById(book); }
业务层开发
使用MyBatisPlus提供有业务层通用接口(ISerivce)与业务层通用实现类(ServiceImpl,在通用类基础上做功能重载或功能追加。
接口
public interface IBookService extends IService<Book> { // 自己写的方法 Book findById(Integer id); // 自己写的分页方法 IPage<Book> getPage(int currentPage , int pageSize); }
实体类
@Service public class BookServlceImpl extends ServiceImpl<BookDao, Book> implements IBookService { @Autowired private BookDao bookDao; @Override public Book findById(Integer id) { return bookDao.selectById(id); } @Override public IPage<Book> getPage(int currentPage, int pageSize) { IPage page = new Page(currentPage,pageSize); bookDao.selectPage(page,null); return page; } }
增删改
增
// 测试增加数据 @Test void testSave() { Book book = new Book(); book.setType("测试"); book.setName("测试"); book.setDescription("测试"); iBookService.save(book); }
删
// 通过id删除数据 @Test void testDelete() { iBookService.removeById(8); }
改
// 测试修改数据 @Test void testUpdate() { Book book = new Book(); book.setId(11); book.setType("测试"); book.setName("测试"); book.setDescription("测试"); boolean b = iBookService.updateById(book); }
查
查询所有信息
// 获取数据库的全部资料 @Test void testGetAll() { System.out.println(iBookService.list()); }
通过id进行查询
@Test void testGetById() { System.out.println(iBookService.getById(1)); }
分页
// 分页效果 @Test void testGetPage() { IPage page = new Page(1,5); iBookService.page(page); }
业务层总结
- 使用通用接口**(ISerivce)**快速开发Service
- 使用通用实现类**(ServiceImpl)**快速开发ServiceImpl
- 可以在通用接口基础上做功能重载或功能追加
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失
表现层开发
表现层消息一致性处理
设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议
@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; } }
增加信息
post提交方式,前端传送的是json数据,需要使用@RequestBody
@PostMapping public R save(@RequestBody Book book) { return new R(bookService.save(book)); }
删除信息
Delete提交方式,只需要提交一个参数id给后端,需要url有一个占位符。
// 删除操作 @DeleteMapping("{id}") public R delete(@PathVariable Integer id) { return new R(bookService.removeById(id)); // return bookService.removeById(id); }
改
使用Put提交数据,前端需要传入json格式给后端,
// 更新数据操作 @PutMapping public R update(@RequestBody Book book) { // return bookService.update(book,null); return new R(bookService.updateById(book)); }
查
不需要添加任何东西
查询所有信息
// 查询所有的信息 @GetMapping public R getAll() { return new R(true,bookService.list()); // return bookService.list(); }
根据id进行查询
// 根据id进行查询 @GetMapping("{id}") public R getById(@PathVariable Integer id) { return new R(true,bookService.getById(id)); // return bookService.getById(id); }
分页查询时自己写的
public interface IBookService extends IService<Book> { // 自己写的方法 Book findById(Integer id); // 自己写的分页方法 IPage<Book> getPage(int currentPage , int pageSize);
@Service public class BookServlceImpl extends ServiceImpl<BookDao, Book> implements IBookService { @Autowired private BookDao bookDao; @Override public Book findById(Integer id) { return bookDao.selectById(id); } @Override public IPage<Book> getPage(int currentPage, int pageSize) { IPage page = new Page(currentPage,pageSize); bookDao.selectPage(page,null); return page; } }
// 分页查询 @GetMapping("{currentPage}/{pageSize}") public R getPage(@PathVariable int currentPage ,@PathVariable int pageSize) { // return bookService.getPage(currentPage,pageSize); return new R(true,bookService.getPage(currentPage,pageSize)); }
需要注意的是,增删改返回结果都是布尔值,所以只需要使用一个参数的构造器,但是查询需要使用两个参数的构造器,这两个参数第一个参数都是true,第二个参数是获取的数据。
前端请求分为两种,一种是参数多的时候需要采用json格式,第二种是参数较少的时候采用url占位符书写。