SpringBoot整合SSMP小demo

创建项目

spring web,mybatis,mysql勾选

加入mp和druid,依赖见SpringBoot基础认识_阳光明媚UPUP的博客-CSDN博客

yml数据源 

server:
  port: 81
spring:
  datasource:
    druid: #整合方式配置
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/jdbc
      username: root
      password: root123

写个数据表,写个domain包实体类。 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
    private Integer id;
    private String name;
    private String price ;//decimal
}

写个mappr包接口@Mapper生成实现类,继承mp 

@Mapper
public interface BookMapper extends BaseMapper {
}

新增报错

//mybatis-plus默认生成的id的方式为自己自订的雪花算法
//而数据库提供的id自增的方法  yml中配置id自增的方式:设置为auto自增:id-type:auto

mybatis-plus:
  global-config:
    db-config:
      id-type: auto

测试用例

@SpringBootTest
class SpringbootBeginQuickstartApplicationTests {
	@Autowired
	private BookMapper bookMapper;
	@Test
	void contextLoads() {
		System.out.println(bookMapper.selectById(1));
		System.out.println(bookMapper.insert(new Book(null,"ddd","12")));
		System.out.println(bookMapper.updateById(new Book(1,"update","12")));//返回值 成功1,失败0
		System.out.println(bookMapper.deleteById(1)); //成功1,失败0
		System.out.println(bookMapper.selectList(null));
		//mybatis-plus默认生成的id的方式为自己自订的雪花算法
		//而数据库提供的id自增的方法  yml中配置id自增的方式:设置为auto自增:id-type:auto
	}
}

开启mp日志

运行测试程序后,控制台打印sql语句和预编译参数和结果。

不开就只有结果。

mybatis-plus:
  global-config:
    db-config:
      id-type: auto
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #输出控制台

mp的分页查询

配置分页拦截: 

Mp在进行查询的时候是通过拦截器进行拼接sql语句来实现的:

我们先创建一个拦截器的包:创建一个放拦截器的配置类:MPConfig:

配置类放入引导类所在的包及子包中才能被读取加载到spring容器中:

@Configuration
public class MPConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

配置类定义详见Spring_阳光明媚UPUP的博客-CSDN博客 

会把page(1,5)拼接sql的limit

mp的Page对象

@SpringBootTest(classes = SpringbootBeginQuickstartApplication.class)
class SpringbootBeginQuickstartApplicationTests {
	@Autowired
	private BookMapper bookMapper;
	@Test
	void contextLoads() {
		Page page = new Page(1, 5);
		System.out.println(bookMapper.selectPage(page,null));
		//mybatis-plus默认生成的id的方式为自己自订的雪花算法
		//而数据库提供的id自增的方法  yml中配置id自增的方式:设置为auto自增:id-type:auto
		System.out.println(page);//com.baomidou.mybatisplus.extension.plugins.pagination.Page@6413d7e7
		System.out.println(page.getCurrent());//1
		System.out.println(page.getSize());//5
		System.out.println(page.getTotal());//13
		System.out.println(page.getPages());//3
		System.out.println(page.getRecords());//[Book(id=2, name=ghet, price=78), Book(id=3, name=ddd, price=12), Book(id=4, name=ddd, price=12), Book(id=5, name=ddd, price=12), Book(id=6, name=ddd, price=12)]
	}
}

条件查询

使用的like %预编译拼接的sql的

@SpringBootTest(classes = SpringbootBeginQuickstartApplication.class)
class SpringbootBeginQuickstartApplicationTests {
    @Autowired
    private BookMapper bookMapper;
    @Test
    void contextLoads() {
        String name="ddd";
        QueryWrapper qw = new QueryWrapper<>();
        qw.like("name", name);//实际中,name可能为null
        //qw.eq , qw.ne , lt , gt , le , ge , between , group
        List bookList = bookMapper.selectList(qw);
        System.out.println(bookList);
        //防止参数name误写错,我们可以借助lambda表达式的Qw查询:
        LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
        //if(name!=null)lqw.like(Book::getName,name);//方法引用:只要保证lambda的入参可用放入Book类的成员方法getName中的入参中即可。
        lqw.like(name != null, Book::getName, name);
        List books = bookMapper.selectList(lqw);
        System.out.println(books);
    }
}

对于上面分页查询后面也能拿国家qw或lqw

        System.out.println(bookMapper.selectPage(page,qw或lqw));

MP简化业务层Service层

普通service

@Service
public class BookServiceImpl implements BookService{
    @Autowired
    private BookMapper bookMapper;
    public Boolean save(Book book){
        return bookMapper.insert(book)>0;
    }
    public Boolean update(Book book){
        return bookMapper.updateById(book)>0;
    }
    public Boolean delete(Integer id){
        return bookMapper.deleteById(id)>0;
    }
    public Book getById(Integer id){
        return bookMapper.selectById(id);
    }
    public List getAll(Integer id){
        return bookMapper.selectList(null);
    }
    public IPage getPage(int currentPage,int pageSize){
        Page page = new Page(currentPage, pageSize);
        bookMapper.selectPage(page,null);
        return page;
    }
}

service接口层只需继承

public interface BookService extends IService {
}

impl除了实现接口层还需继承

@Service
public class BookServiceImpl extends ServiceImpl implements BookService{
}

ctrl+f12勾选第一个框,即可看到里面继承的方法

mp业务层有的方法直接用,没有的接着写。尽量不与Mp的业务层方法重名,可以使用@Override进行检查有无重名覆盖。

然后就可贼测试类注入service接口并测试了。

表现层开发

@RestController//restful风格的controller
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;
    @GetMapping
    public List getAll(){
        return bookService.list();
    }
    @PostMapping
    public Boolean save(@RequestBody Book book){//RequestBody接收json
        return bookService.save(book);
    }
    @PutMapping
    public Boolean update(@RequestBody Book book){//RequestBody接收json
        return bookService.updateById(book);
    }
    @DeleteMapping("/{id}")
    public Boolean delete(@PathVariable Integer id){//RequestBody接收json
        return bookService.removeById(id);
    }
    @GetMapping("/{id}")
    public Book getById(@PathVariable Integer id){//RequestBody接收json
        return bookService.getById(id);
    }
    @GetMapping("{currentPage}/{pageSize}")
    public IPage getPage(@PathVariable int currentPage,@PathVariable int pageSize){
        Page page = new Page<>(1,5);
        return bookService.page(page);
    }
}

postman测试

选择REST动作GET/...

POST/PUT请求body里面加上json数据{ "":"",  "":""}

DELETE请求路径传参/1

表现层消息一致性处理

查询返回list的数据、新增返回true,修改返回true,删除返回true,分页查询返回IPage

由于:

查询id不存在的数据,返回null,查询过程中抛出异常,catch中返回null。

这时:

我们就不知道这个null,是查询数据库返回的,还是报异常返回的。

我们可以设置一个flag,如果是正常查询就返回true:如果报异常没正常查询返回false:

设计表现层返回结果的模型类,用于后端与前端进行数据格式统一,也称为前后端数据协议

我们需要加一个返回结果的数据的模型类:

util包下

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R {
    private Boolean flag;
    private Object data;
    public R(Boolean flag) {
        this.flag = flag;
    }
}
@RestController//restful风格的controller
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;
    @GetMapping
    public R getAll(){
        return new R(true,bookService.list());
    }
    @PostMapping
    public R save(@RequestBody Book book){//RequestBody接收json
        R r = new R();
        boolean flag = bookService.save(book);
        r.setFlag(flag);
        return r;
    }
    @PutMapping
    public R update(@RequestBody Book book){//RequestBody接收json
        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){
        Page page = new Page<>(1,5);
        return new R(true,bookService.page(page));
    }
}

现在查询成功或失败都会有状态了。

前后端联调

先不整这块了

前后端分离结构设计中页面归属前端服务器
单体工程中页面放置在resources目录下的static目录中(建议执行clean)

异常消息处理

当抛异常就不返回R了,接着springmvc异常处理

util包下的R先加个属性private String msg;

util包下创建一个异常处理器作为springmvc异常处理器

@RestControllerAdvice
public class ProjectRxceptionAdvice {
    @ExceptionHandler
    public  R doException(Exception e){
        //记录日志
        //通知运维
        //通知开发
        e.printStackTrace();
        return new R("服务器故障,请稍后再试");
    }
}

controller的某个资源随便造一个异常,postman访问测试。

你可能感兴趣的:(spring,boot)