
 
 
1. 整合Mybatis-plus
1.1 基础配置
- 手动添加依赖 数据池依赖和mybatis-plus依赖
 
       <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>
 
- 配置文件中添加属性
 
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/ssm_db?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8
      username: root
      password: root
 
- 添加实体类
 - 编写Mapper,继承Base接口,并将泛型实例化。
 
@Mapper
public interface BookDao extends BaseMapper<Book> {
}
 
- 测试类中进行测试。
 
1.2 数据库表交互
- mybatis-plus对数据表进行读取时,不能读取到表的前缀,需要在配置文件中添加表前缀。
 - 同时还需要添加自增属性,使数据能够实现自增功能,如 id属性。
 - 开启日志属性,这样就不用采用输出语句,直接运行接口中的方法就能在控制台上直观看到数据
 
#配置表名前缀
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      #设置自增
      id-type: auto
  configuration:
    #开启日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 
2. 分页功能
- base接口中已经实现了分页的功能,可以直接调用方法,但是调用方法不会直接得到响应结果,需要对其进行配置。
 
@Test
    void testGetPage(){
        IPage page = new Page(1,5);
        bookDao.selectPage(page,null);//返回的依旧是 Ipage接口类型是数据
    }
 
- 添加配置类,将分页拦截器加载到mybatis-plus中。
 
@Configuration
public class MPConfig {
    //创建mybatis-plus拦截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //定义拦截器
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}
 
- 分页后可以得到很多数据,如: 
  
- 数据 当前页码 每页数据总量 最大页码 数据总量
 
 
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZkMUREZw-1647693229509)(C:\Users\10990\AppData\Roaming\Typora\typora-user-images\image-20220318120655416.png)]
3. 条件查询
- 创建QueryWrapper对象,给对象添加值。 
  
- 缺点: 需要手动添加对象的属性值
 
 - 创建LambdaQueryWrapper 对象,可以实现自动添加对象属性值,避免错误出现。
 - 针对没有输入的空值,可以在最前面添加 判断类型。 
  
- 类似语法 if(…){}
 
 
   @Test
    void testGetBy(){
//        QueryWrapper<Book> qw = new QueryWrapper<>();
//        qw.like("type","说");
//        bookDao.selectList(qw);
        String name = null;
        LambdaQueryWrapper<Book> lqw = new LambdaQueryWrapper<>();
        //lqw.like(Book::getName,"三");
        lqw.like(name!=null,Book::getName,name);
        bookDao.selectList(lqw);
    }
}
 
4. 业务层快速开发
- 通过接口(Iservice)快读开发Service
 - 使用通用类实现类(ServiceImpl<M,T>)快速开发ServiceImpl
 - 可以在通用类的基础上做功能覆盖或功能追加
 - 注意重载时不要覆盖原始操作,避免原始提供的功能丢失。
 
@Service
public interface IBookService extends IService<Book> {
    
}
@Service
public class IBookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {
}
 
5. 前后端数据规范
- 后端返回的数据有的呈现Json格式输出到前端,而有的则时true false格式,对前端来说处理数据很难进行,所以需要有一套规范来使前后端数据获取时,有所关联。
 - 创建Msg类,其中包括状态码,返回信息Object,以及携带的信息
 
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Msg {
    private Boolean flag;
    private Object data;
    private  String message;
    public Msg(Boolean flag) {
        this.flag = flag;
    }
    public Msg(Boolean flag,Object data){
        this.flag = flag;
        this.data = data;
    }
    public Msg(Boolean flag,String message){
        this.flag = flag;
        this.message = message;
    }
}
 
- 此时Controller层处理数据就可以直接返回Msg,前端直接通过Msg取值
 
   @Autowired
   private IBookService service;
    @GetMapping
    public Msg getAll(){
        return new Msg(true,service.list());
    }
    @PostMapping
    public Msg save(@RequestBody Book book) throws IOException {
        boolean flag = service.save(book);
        return new Msg(flag,flag ? "添加成功^_^":"添加失败-_-!");
    }
    @PutMapping
    public Msg update(@RequestBody Book book){
        return new Msg(service.modify(book));
    }
    @DeleteMapping("/{id}")
    public Msg delete(@PathVariable("id") Integer id){
        return new Msg(service.delete(id));
    }
 
6. Axios 发送异步请求
6.1 Vue中代码
 var vue = new Vue({
        el: '#app',
        data:{
            dataList: [],//当前页要展示的列表数据
            dialogFormVisible: false,//添加表单是否可见
            dialogFormVisible4Edit:false,//编辑表单是否可见
            formData: {},//表单数据
            rules: {//校验规则
                type: [{ required: true, message: '图书类别为必填项', trigger: 'blur' }],
                name: [{ required: true, message: '图书名称为必填项', trigger: 'blur' }]
            },
            pagination: {//分页相关模型数据
                currentPage: 1,//当前页码
                pageSize:5,//每页显示的记录数
                total:0,//总记录数
                type:"",
                name:"",
                description:""
            }
        },
 
- 发送异步请求
 - .后面是请求方式,请求路径
 - 箭头函数将得到的返回结果进行处理
 - dataList 在表格中定义,并在Vue中定义, 直接将返回结果返回到 dataList 中
 
            //列表
           getAll() {
           //发送异步请求
            axios.get("/books").then((res)=>{
            console.log(res.data);
            this.dataList = res.data.data;
            })
           },
 
7. 弹框操作
- 初始Vue中定义 dialogFormVisible 为 false ,改为true 则弹出
 - 调用resetForm 方法来重置表单
 - resetForm 方法的实际操作就是将 formData: {},设为空。
 
//弹出添加窗口
            handleCreate() {
                //添加新增窗口
                this.dialogFormVisible = true;
                //重置窗口
                this.resetForm();
            },
 
8. 添加操作
- 发送post请求
 - 携带this.formData 中的数据 res 为返回结果
 - 具体成功的操作 
  
- 关闭弹窗
 - 弹出消息窗
 
 - 无论处理成功与否,重新加载数据。
 
//添加
            handleAdd () {
                //发送请求
                axios.post("/books",this.formData).then((res)=>{
                    //判断当前操作是否成功
                    if(res.data.flag) {
                        //1.关闭弹层
                        this.dialogFormVisible = false;
                        //弹消息窗
                        this.$message.success(res.data.message);
                    }else {
                        this.$message.error(res.data.message);
                    }
                }).finally(()=> {
                    //2.重新加载数据
                    this.getAll();
                });
            },
 
9. 取消操作
- 关闭弹窗
 - 弹消息窗
 
 //取消
            cancel(){
                this.dialogFormVisible = false;
                this.dialogFormVisible4Edit = false;
                this.$message.info("当前操作取消");
            },
 
10. 删除操作
- 调用$confirm函数,弹出消息框确实是否删除
 - 发送异步请求,带上id
 - 对返回的结果处理 
  
- 弹消息窗
 
 - 重新加载
 
    // 删除
            handleDelete(row) {
                this.$confirm("此操永久删除信息,是否继续?","提示",{type: "info"}).then(()=>{
                    axios.delete("/books/"+row.id).then((res)=>{
                        if(res.data.flag) {
                            //弹消息窗
                            this.$message.success("删除成功");
                        }else {
                            this.$message.error("删除失败");
                        }
                    }).finally(()=> {
                        //2.重新加载数据
                        this.getAll();
                    });
                }).catch(()=>{
                    this.$message.info("取消删除");
                })
            },
 
11. 修改功能
-  
加载数据
-  
发送异步请求获取到本行的数据
 -  
根据返回的数据如果有数据并且数据不为空,弹窗操作,并将数据加载到消息栏中。
 -  
否则表示没有数据,报错。
 
 -  
 -  
修改操作
- 提交表单
 - 类似新增
 
 
//弹出编辑窗口
            handleUpdate(row) {
                axios.get("/books/"+row.id).then((res)=>{
                    if(res.data.flag && res.data.data!=null){
                        this.dialogFormVisible4Edit = true;
                        this.formData = res.data.data;
                    }else {
                        this.$message.error("数据同步失败,自动刷新");
                    }
                }).finally(()=> {
                    //2.重新加载数据
                    this.getAll();
                });;
            },
            //修改
            handleEdit() {
                //发送请求
                axios.put("/books",this.formData).then((res)=>{
                    //判断当前操作是否成功
                    if(res.data.flag) {
                        //1.关闭弹层
                        this.dialogFormVisible4Edit = false;
                        //弹消息窗
                        this.$message.success("修改成功");
                    }else {
                        this.$message.error("修改失败");
                    }
                }).finally(()=> {
                    //2.重新加载数据
                    this.getAll();
                });
            },
 
12. 分页操作
业务层操作:返回的是page对象,其中携带了 currentPage,pageSize,total 等数据。
@GetMapping("/{currentPage}/{pageSize}")
    public Msg getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){
        IPage<Book> page = service.getPage(currentPage, pageSize,book);
        //如果当前页码值大于总页码值,重新执行操作查询操作,使用最大页码值作为当前页码值
        if(currentPage > page.getPages()){
            page = service.getPage((int) page.getPages(), pageSize,book);
        }
        return new Msg(true,page);
    }
 
- Vue中定义了分页的三个参数,分别为currentPage,pageSize,total,将当前页码,每页多少数据添加到请求中
 - 将返回的结果赋值给数据
 
//分页查询
            getAll(){
                param="?type="+this.pagination.type;
                param+="&name="+this.pagination.name;
                param+="&description="+this.pagination.description;
                   axios.get("/books/"+this.pagination.currentPage+"/"
                             +this.pagination.pageSize+param).then((res)=>{
                        //console.log(res.data);
                       this.pagination.currentPage=res.data.data.current;
                       this.pagination.pagesize = res.data.data.size;
                       this.pagination.total=res.data.data.total;
                       this.dataList = res.data.data.records;
                   })
            },
            //切换页码
            handleCurrentChange(currentPage) {
                //修改页码值当前选中的页码值
                this.pagination.currentPage = currentPage;
                this.getAll();
            },
 
13. 查询操作
-  
添加到getall中, 和分页操作一起进行。
 -  
服务层代码
- 动态按条件查询
 
 
   @Override
    public IPage<Book> getPage(int currentPage, int pageSize, Book book) {
        IPage<Book> page = new Page<>(currentPage,pageSize);
        //动态条件查询
        LambdaQueryWrapper<Book> 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());
        return bookDao.selectPage(page,lqw);
    }
 
- 控制层代码
 
 @GetMapping("/{currentPage}/{pageSize}")
    public Msg getPage(@PathVariable int currentPage,@PathVariable int pageSize,Book book){
        IPage<Book> page = service.getPage(currentPage, pageSize,book);
        //如果当前页码值大于总页码值,重新执行操作查询操作,使用最大页码值作为当前页码值
        if(currentPage > page.getPages()){
            page = service.getPage((int) page.getPages(), pageSize,book);
        }
        return new Msg(true,page);
    }
 
- 查询按钮同样绑定 GetAll()函数。用于得到数据。
 










