学习笔记--SSMP整合案例的一些小tips
1、MyBatis-Plus的分页功能
- 分页操作需要设定分页对象Ipage
1 2 | public void test2(){ IPage page = new Page(1,5); bookDao.selectPage(page,null);< br >} |
new出来的数据Page 第一个参数是当前页,第二个参数是一页有多少条数据
- 经过MP查询完后,所有相关数据都被封装进了IPage对象中
1 2 3 4 | System.out.println(page.getCurrent());//当前页 System.out.println(page.getPages());//有多少页 System.out.println(page.getTotal());//总数据 System.out.println(page.getRecords());//查询到的数据 |
- 分页操作是在MyBatisPlus的常规操作基础上增强得到,内部是动态的拼写SQL语句,因此需要增强对应的功能,使用MyBatisPlus拦截器实现
1 2 3 4 5 6 7 8 9 10 | @Configuration public class MPConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor(){ MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor( new PaginationInnerInterceptor()); return interceptor; } } |
固定的格式。
在application配置文件中,将MP的日志打开,这样可以查看执行的sql语句方便测试
1 2 | mybatis-plus: configuration:<br> log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
2、条件查询功能
- 最简单的方法
1 2 3 4 5 6 | @Test public void test3(){ QueryWrapper<Book> qw = new QueryWrapper<>(); qw.like( "name" , "spring" ); bookDao.selectList(qw); } |
首先创建一个qw对象,然后qw.方法名,有许多条件查询的方法。
例中like方法,第一个参数是写比较的属性名,第二个是内容。意思是筛选name中含spring的数据。
但是这有一个问题,如果name打错了,会报错,能否从语法上杜绝这个可能?
- 法2
1 2 3 4 5 6 7 8 9 | @Test public void test4(){ String name = null ; LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>(); // lqw.like(Book::getName,name); lqw.like(name != null ,Book::getName,name); bookDao.selectList(lqw); } |
使用Lqw对象,对象的第一个参数改为泛型::getXXX,如果你写错了,就会直接标红提醒你。
一般来说,我们都是拿到一个string数据来筛选。
如果我们没有拿到,传进来一个null,我们筛选的时候就会查询数据中是否有null,这显然是不对的。
lqw.like函数有一个3个参数的方法,其第一个就是判断语句,通过了才执行该条件语句,这样就能杜绝这种情况。
3、业务层快速开发
1、首先还是定义业务层的接口
1 2 3 | public interface IBookService extends IService<Book> { } |
继承IService接口,里面泛型就写对应操作的实体类。
2、然后写实现类,实现接口方法,这个实现MP也帮我们完成了,只需要我们继承ServiceImpl类就行
1 2 3 4 | @Service public class BookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService { } |
这个类有2个泛型,一个是对应的dao类,另一个是实体类
- 如果通用的接口和实现类不满足需要,可以在通用类的基础上做功能重载或功能追加。
- 注意重载时不要覆盖原始操作,避免原始提供的功能丢失。
4、统一的返回值格式
1、设计统一的返回值结果类型便于前端开发读取数据。
2、返回值结果类型可以根据需求自定设定,没有固定格式。
3、返回值结果模型类用于后端与前端进行数据格式统一,也称前后端数据协议。
步骤:
1、模型类R
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @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; } } |
设计2个有参构造是为了简化代码行数。
2、控制层所有方法都返回R
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @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 ( "/{current}/{pageSize}" ) public R getPage( @PathVariable int current, @PathVariable int pageSize){ return new R( true ,bookService.getPage(current,pageSize)); } } |
数据存放在R.data里,是否成功放在R.flag里。
5、前后端协议联调
1、前端执行created函数,将列表信息载入。
2、created函数中执行this.getAll()方法,将数据得到。
3、getAll方法中利用axios得到数据,axios的格式有一点忘了,现在巩固补充。
1 2 3 4 5 6 | //列表 getAll() { axios.get( "/books" ).then((res) =>{ console.log(res.data); }) }, |
6、后端SpringMVC异常处理器
目的:很多axios的结果不仅仅有成功和失败,如果由于服务器出了问题导致返回的不再是R类型的数据时,前端很可能就会显示错误。
解决方案:
可以将所有层的异常全部向外抛,由控制层将异常抛给异常处理器,异常处理器拿到异常时返回一个R类型的数据并封装好具体的错误原因。
1 2 3 4 5 6 7 8 9 10 11 12 13 | @RestControllerAdvice public class ProjectExceptionAdvice { //拦截所有的异常信息 @ExceptionHandler public R doException(Exception ex){ // 记录日志 // 发送消息给运维 // 发送邮件给开发人员,ex对象发送给开发人员 ex.printStackTrace(); return new R( "服务器故障,请稍后再试" ); } } |
注意点:
- 使用注解@RestControllerAdvice定义SpringMVC异常处理器用来处理异常的。
- 异常处理器必须被扫描(意味着必须在Application启动类的同级或子级中)。
- 如果不想把错误信息屏蔽掉,必须加ex.printStackTrace()这个函数。
- R的相关构造方法得写。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器
· 面试官:你是如何进行SQL调优的?