1、创建模块,勾选
2、配置pom.xml
springboot_08_ssmp
springboot_08_ssmp
com.baomidou
mybatis-plus-boot-starter
3.4.3
com.alibaba
druid-spring-boot-starter
1.2.6
3、实体类开发
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
org.projectlombok
lombok
@Data
public class Book {
private Integer id;
private String type;
private String name;
private String description;
}
4、数据层开发
spring:
datasource:
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/ssm_crud?serverTimezone=UTC
username: root
password: 123abc
#设置mp相关配置
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
@Mapper
public interface BookDao extends BaseMapper {
}
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #设置表名通用前缀
id-type: auto #设置主键id字段的生成策略为参照数据库设定的策略,当前数据库设置id生成策略为自增
@SpringBootTest
public class BookDaoTestCase {
@Autowired
private BookDao bookDao;
@Test
void testGetById(){
System.out.println(bookDao.selectById(1));
}
@Test
void testSave(){
Book book=new Book();
book.setType("测试123");
book.setName("测试123");
book.setDescription("测试123");
bookDao.insert(book);
}
@Test
void testUpdate(){
Book book=new Book();
book.setId(53);
book.setType("测试53");
book.setName("测试123");
book.setDescription("测试123");
bookDao.updateById(book);
}
@Test
void testDelete(){
bookDao.deleteById(53);
}
@Test
void testGetAll(){
System.out.println(bookDao.selectList(null));
}
}
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_ #设置表名通用前缀
id-type: auto #设置主键id字段的生成策略为参照数据库设定的策略,当前数据库设置id生成策略为自增
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台输出
总结:
手工导入starter坐标(2个),mysql驱动(1个)
配置数据源与MyBatisPlus对应的配置
开发Dao接口(继承BaseMapper)
制作测试类测试Dao功能是否有效
使用配置方式开启日志,设置日志输出方式为标准输出即可查阅SQL执行日志
@Configuration //配置类
public class MyConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
//创建MP的拦截器
MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
//添加分页拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
@Test
void testGetPage(){
IPage page=new Page(1,5);
bookDao.selectPage(page,null);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
总结:
使用IPage封装分页数据
分页操作依赖MyBatisPlus分页拦截器实现功能
借助MyBatisPlus日志查阅执行SQL语句
@Test
void testGetBy2(){
String name=null;
LambdaQueryWrapper lqw=new LambdaQueryWrapper<>();
//name为空时查询全部,不为空时按条件查询
lqw.like(name!=null,Book::getName,name); //API接口提供控制开关
bookDao.selectList(lqw);
}
总结:
使用QueryWrapper对象封装查询条件
推荐使用LambdaQueryWrapper对象
所有查询操作封装成方法调用
查询条件支持动态条件拼装
5、业务层开发
public interface BookService {
Boolean save(Book book);
Boolean update(Book book);
Boolean delete(Integer id);
Book getById(Integer id);
List getAll();
IPage getPage(int currentPage,int pageSize);
}
@Service //定义成业务层对应的bean
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 getAll() {
return bookDao.selectList(null);
}
@Override
public IPage getPage(int currentPage, int pageSize) {
IPage iPage=new Page<>(currentPage,pageSize);
bookDao.selectPage(iPage,null); //返回的类型还是iPage
return iPage;
}
}
@SpringBootTest
public class BookServiceTestCase {
//注入业务层对象
@Autowired
private BookService bookService;
@Test
void testGetById(){
System.out.println(bookService.getById(1));
}
@Test
void testSave(){
Book book = new Book();
book.setType("测试aaa");
book.setName("测试aaa");
book.setDescription("测试aaa");
bookService.save(book);
}
@Test
void testDeleteById(){
bookService.delete(54);
}
@Test
void testGetAll(){
bookService.getAll();
}
@Test
void testUpdate(){
Book book = new Book();
book.setId(13);
book.setType("测试bbb");
book.setName("测试aaa");
book.setDescription("测试aaa");
bookService.update(book);
}
@Test
void testGetPage(){
IPage page = bookService.getPage(2, 5);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
}
总结:
Service接口名称定义成业务名称,并与Dao接口名称进行区分
制作测试类测试Service功能是否有效
6、业务层快速开发
public interface IBookService extends IService {
//添加非通用操作API接口
}
@Service
public class BookServiceImpl extends ServiceImpl implements IBookService {
@Autowired
private BookDao bookDao;
//添加非通用操作API
}
@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.setType("测试ccc");
book.setName("测试aaa");
book.setDescription("测试aaa");
bookService.save(book);
}
@Test
void testDeleteById(){
bookService.removeById(14);
}
@Test
void testGetAll(){
bookService.list();
}
@Test
void testUpdate(){
Book book = new Book();
book.setId(13);
book.setType("测试ddd");
book.setName("测试aaa");
book.setDescription("测试aaa");
bookService.updateById(book);
}
@Test
void testGetPage(){
IPage page=new Page<>(2,5);
bookService.page(page);
System.out.println(page.getCurrent());
System.out.println(page.getSize());
System.out.println(page.getTotal());
System.out.println(page.getPages());
System.out.println(page.getRecords());
}
}
总结:
使用通用接口(ISerivce
使用通用实现类(ServiceImpl
可以在通用接口基础上做功能重载或功能追加
注意重载时不要覆盖原始操作,避免原始提供的功能丢失
7、表现层开发
@RestController
@RequestMapping("/books")
public class BookController {
//注入业务层
@Autowired
private IBookService bookService;
@GetMapping
public List getAll(){
return bookService.list();
}
@PostMapping
public Boolean save(@RequestBody Book book){
return bookService.save(book);
}
//传json数据要用@RequestBody
@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);
}
}
总结:
基于Restful制作表现层接口
新增:POST
删除:DELETE
修改:PUT
查询:GET
接收参数
实体数据:@RequestBody
路径变量:@PathVariable
8、表现层消息一致性处理
@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;
}
}
@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));
}
//传json数据要用@RequestBody
@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));
}
}
总结:
设计统一的返回值结果类型便于前端开发读取数据
返回值结果类型可以根据需求自行设定,没有固定格式
返回值结果模型类用于后端与前端进行数据格式统一,也称为前后端数据协议
9、业务消息一致性处理
@Data
public class R {
private Boolean flag;
private Object data;
private String msg;
public R(Boolean flag,String msg){
this.flag=flag;
this.msg=msg;
}
public R(String msg){
this.flag=false;
this.msg=msg;
}
@RestControllerAdvice
public class ProjectExceptionAdvice {
//拦截所有的异常信息
@ExceptionHandler(Exception.class)
public R doException(Exception ex){
//记录日志
//通知运维
//通知开发
ex.printStackTrace();
return new R("服务器故障,请稍后再试!");
}
}
@PostMapping
public R save(@RequestBody Book book) throws IOException {
if(book.getName().equals("123")) throw new IOException();//模拟失败
boolean flag = bookService.save(book);
return new R(flag,flag?"添加成功^_^":"添加失败-_-!");
}
//添加
handleAdd () {
//发送ajax请求
axios.post("/books",this.formData).then((res)=>{
//如果操作成功,关闭弹层,显示数据
if(res.data.flag){
this.dialogFormVisible = false;
this.$message.success(res.data.msg);
}else {
this.$message.error(res.data.msg); //消息来自于后台传递过来,而非固定内容
}
}).finally(()=>{
//2.重新加载数据
this.getAll();
});
},
10、删除功能维护
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize){
IPage page = bookService.getPage(currentPage, pageSize);
//如果当前页码值大于了总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if( currentPage > page.getPages()){
page = bookService.getPage((int)page.getPages(), pageSize);
}
return new R(true, page);
}
11、条件查询
@GetMapping("{currentPage}/{pageSize}")
public R getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){
IPage page = bookService.getPage(currentPage, pageSize,book);
//如果当前页码值大于总页码值,那么重新执行查询操作,使用最大页码值作为当前页码值
if(currentPage>page.getPages()){
page = bookService.getPage((int) page.getPages(), pageSize,book);
}
return new R(true,page);
}
public interface IBookService extends IService {
IPage getPage(int currentPage,int pageSize);
IPage getPage(int currentPage, int pageSize, Book book);
}
@Service
public class BookServiceImpl extends ServiceImpl implements IBookService {
@Autowired
private BookDao bookDao;
@Override
public IPage getPage(int currentPage, int pageSize) {
IPage page=new Page<>(currentPage,pageSize);
bookDao.selectPage(page,null);
return page;
}
@Override
public IPage getPage(int currentPage, int pageSize, Book book) {
LambdaQueryWrapper lqw=new LambdaQueryWrapper<>();
lqw.like(Strings.isNotEmpty(book.getType()),Book::getType,book.getType());
lqw.like(Strings.isNotEmpty(book.getName()),Book::getName,book.getName());
lqw.like(Strings.isNotEmpty(book.getDescription()),Book::getDescription,book.getDescription());
IPage page=new Page<>(currentPage,pageSize);
bookDao.selectPage(page,lqw);
return page; }
}
基于SpringBoot的SSMP整合案例总结:
-----------------基于黑马Spring Boot2基础篇的整理-----------------