0
点赞
收藏
分享

微信扫一扫

SpringBoot--基于SpringBoot实现的简单图书管理(CRUD操作)

以前干嘛去了 2022-03-19 阅读 52

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1. 整合Mybatis-plus

1.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>
  1. 配置文件中添加属性
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
  1. 添加实体类
  2. 编写Mapper,继承Base接口,并将泛型实例化。
@Mapper
public interface BookDao extends BaseMapper<Book> {
}

  1. 测试类中进行测试。

1.2 数据库表交互

  1. mybatis-plus对数据表进行读取时,不能读取到表的前缀,需要在配置文件中添加表前缀。
  2. 同时还需要添加自增属性,使数据能够实现自增功能,如 id属性。
  3. 开启日志属性,这样就不用采用输出语句,直接运行接口中的方法就能在控制台上直观看到数据
#配置表名前缀
mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_
      #设置自增
      id-type: auto
  configuration:
    #开启日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

2. 分页功能

  1. base接口中已经实现了分页的功能,可以直接调用方法,但是调用方法不会直接得到响应结果,需要对其进行配置。
@Test
    void testGetPage(){
        IPage page = new Page(1,5);
        bookDao.selectPage(page,null);//返回的依旧是 Ipage接口类型是数据
    }
  1. 添加配置类,将分页拦截器加载到mybatis-plus中。
@Configuration
public class MPConfig {
    //创建mybatis-plus拦截器
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //定义拦截器
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //添加分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

}
  1. 分页后可以得到很多数据,如:
    • 数据 当前页码 每页数据总量 最大页码 数据总量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZkMUREZw-1647693229509)(C:\Users\10990\AppData\Roaming\Typora\typora-user-images\image-20220318120655416.png)]

3. 条件查询

  1. 创建QueryWrapper对象,给对象添加值。
    • 缺点: 需要手动添加对象的属性值
  2. 创建LambdaQueryWrapper 对象,可以实现自动添加对象属性值,避免错误出现。
  3. 针对没有输入的空值,可以在最前面添加 判断类型。
    • 类似语法 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. 业务层快速开发

  1. 通过接口(Iservice)快读开发Service
  2. 使用通用类实现类(ServiceImpl<M,T>)快速开发ServiceImpl
  3. 可以在通用类的基础上做功能覆盖或功能追加
  4. 注意重载时不要覆盖原始操作,避免原始提供的功能丢失。
@Service
public interface IBookService extends IService<Book> {
    
}


@Service
public class IBookServiceImpl extends ServiceImpl<BookDao, Book> implements IBookService {

}

5. 前后端数据规范

  1. 后端返回的数据有的呈现Json格式输出到前端,而有的则时true false格式,对前端来说处理数据很难进行,所以需要有一套规范来使前后端数据获取时,有所关联。
  2. 创建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;
    }
}
  1. 此时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:""
            }
        },
  1. 发送异步请求
  2. .后面是请求方式,请求路径
  3. 箭头函数将得到的返回结果进行处理
  4. dataList 在表格中定义,并在Vue中定义, 直接将返回结果返回到 dataList 中
            //列表
           getAll() {
           //发送异步请求
            axios.get("/books").then((res)=>{
            console.log(res.data);
            this.dataList = res.data.data;
            })
           },

7. 弹框操作

  1. 初始Vue中定义 dialogFormVisible 为 false ,改为true 则弹出
  2. 调用resetForm 方法来重置表单
  3. resetForm 方法的实际操作就是将 formData: {},设为空。
//弹出添加窗口
            handleCreate() {
                //添加新增窗口
                this.dialogFormVisible = true;
                //重置窗口
                this.resetForm();
            },

8. 添加操作

  1. 发送post请求
  2. 携带this.formData 中的数据 res 为返回结果
  3. 具体成功的操作
    • 关闭弹窗
    • 弹出消息窗
  4. 无论处理成功与否,重新加载数据。
//添加
            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. 取消操作

  1. 关闭弹窗
  2. 弹消息窗
 //取消
            cancel(){
                this.dialogFormVisible = false;
                this.dialogFormVisible4Edit = false;
                this.$message.info("当前操作取消");
            },

10. 删除操作

  1. 调用$confirm函数,弹出消息框确实是否删除
  2. 发送异步请求,带上id
  3. 对返回的结果处理
    • 弹消息窗
  4. 重新加载
    // 删除
            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. 修改功能

  1. 加载数据

    • 发送异步请求获取到本行的数据

    • 根据返回的数据如果有数据并且数据不为空,弹窗操作,并将数据加载到消息栏中。

    • 否则表示没有数据,报错。

  2. 修改操作

    • 提交表单
    • 类似新增
//弹出编辑窗口
            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);
    }
  1. Vue中定义了分页的三个参数,分别为currentPage,pageSize,total,将当前页码,每页多少数据添加到请求中
  2. 将返回的结果赋值给数据
//分页查询
            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. 查询操作

  1. 添加到getall中, 和分页操作一起进行。

  2. 服务层代码

    • 动态按条件查询
   @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);
    }
  1. 控制层代码
 @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);
    }
  1. 查询按钮同样绑定 GetAll()函数。用于得到数据。
举报

相关推荐

0 条评论