从零创建SpringBoot简单模板后台:增删改查与分页

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


零、前言

本文记录如果从零开始创建一个包含增删改查的简单入门SpringBoot例子,如有错误,敬请指正(学习来自某SpringBoot视频)


一、创建项目

1.创建SpringBoot项目,选择JDK1.8
在这里插入图片描述
2.Java Version选择8
在这里插入图片描述
3.选择创建模板
在这里插入图片描述
4.设置项目名称和项目路径
在这里插入图片描述


二、在.pom文件中导入依赖

1.导入MP依赖(MyBatis-Plus)

在这里插入图片描述

2.导入Druid依赖(数据库连接池)

在这里插入图片描述

3.导入lombok依赖(用于方便实体类的创建)

由于父类声明了版本,这里就不用设置版本
在这里插入图片描述

4.导入Swagger依赖(方便调试方法)

在这里插入图片描述


三、创建数据库(表)

1.SQL语句如下

DROP TABLE IF EXISTS `tbl_book`;
CREATE TABLE `tbl_book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(20) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `description` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

创建完成后就是这个样子
在这里插入图片描述


四、编写配置文件(.yml格式)

SpringBoot默认.properties类型,我们把它改成.yml
在这里插入图片描述
文件内容具体如下

spring:
  datasource:
    druid:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://localhost:3306/guli?serverTimezone=UTC #你的数据库名称
      username: root #你的mysql账号
      password: 123456 #你的mysql密码
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

mybatis-plus:
  global-config:
    db-config:
      table-prefix: tbl_ #实体类前加上前缀,因为我的表名是tbl_book,实体类叫做Book,因为要保持一致,就得加前缀
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #日志,控制台显示输出的sql语句,和查询的结果

五、创建配置类

1.MyBatis-Plus分页插件配置类

先在项目目录下创建一个config包
在这里插入图片描述
在包下创建一个MPConfig配置类

代码如下

@Configuration
public class MPConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}

2.Swagger配置类

在包下创建一个SwaggerConfig配置类

代码如下

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket webApiConfig(){
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")
                //调用apiInfo方法,创建一个ApiInfo实例,
                // 里面是展示在文档页面信息内容
                .apiInfo(webApiInfo())
                .select()
                .paths(Predicates.not(PathSelectors.regex("/admin/.*")))
                .paths(Predicates.not(PathSelectors.regex("/error.*")))
                .build();

    }
    // api文档的详细信息
    private ApiInfo webApiInfo(){

        return new ApiInfoBuilder()
                .title("API文档接口测试")    //标题
                .description("本文档描述接口测试用例")  //描述
                .version("1.0")  //版本
                .contact(new Contact("java", "http://baidu.com", "123@qq.com"))
                .build();
    }
}

六、创建实体类(Book)

先在项目主目录下创建一个叫pojo的包,再到里面创建一个Book类和BookSearch类(这个类用于封装查询条件)
在这里插入图片描述
代码如下

@Data
public class Book {
    @TableId(value = "id", type = IdType.ID_WORKER_STR)
    private String id;
    private String type;
    private String name;
    private String description;
}
@Data
public class BookSearch {
    private String type;
    private String name;
    private String description;
}

七、创建数据层(Mapper)

创建BookMapper接口(本文没有用到自己写的SQL语句,故没有.xml文件)
在这里插入图片描述
继承BaseMapper即可

@Mapper
public interface BookMapper extends BaseMapper<Book> {

}

八、创建业务层(Service)

这里提供两种方式,但本文使用的是第二种
在这里插入图片描述

1.业务层标准创建

BookService接口代码如下

public interface BookService {
	//添加
    Boolean save (Book book);
    //更新
    Boolean update(Book book);
    //删除
    Boolean delete(String id);
    //单个查询
    Book getById(String id);
    //查询全部
    List<Book> getAll();
    //分页查询
    IPage<Book> PageGet(int current, int size);
}

BookService实现类代码如下

@Service
public class BookServiceImpl implements BookService {
@Autowired
    BookMapper bookMapper;
//添加
    @Override
    public Boolean save(Book book) {
        return bookMapper.insert(book) >0;
    }
//更新
    @Override
    public Boolean update(Book book) {
        return bookMapper.updateById(book) >0;
    }
//删除
    @Override
    public Boolean delete(String id) {
        return bookMapper.deleteById(id) >0;
    }
//查询单个
    @Override
    public Book getById(String id) {
        return bookMapper.selectById(id);
    }
//查询全部
    @Override
    public List<Book> getAll() {
        return bookMapper.selectList(null);
    }
//分页查询
    @Override
    public IPage<Book> PageGet(int current, int size) {
        Page page = new Page(current,size);
        return bookMapper.selectPage(page,null);
    }
}

2.业务层快速创建

接口继承IService
BookService2接口代码如下

public interface BookService2 extends IService<Book> {
    Boolean deleteBook(String id);
}

实现类继承ServiceImpl
BookService2实现类代码如下

@Service
public class BookServiceImpl2 extends ServiceImpl<BookMapper, Book> implements BookService2 {
    @Autowired
    BookMapper bookMapper;
    @Override
    public Boolean deleteBook(String id) {
        return bookMapper.deleteById(id)>0;
    }
}

九、统一数据

1.统一结果返回(返回给前端的数据要统一格式,不能一会是Integer,一会是String)

创建以下类
在这里插入图片描述
代码如下

@Data
public class R {
    @ApiModelProperty(value = "是否成功")
    private Boolean success;
    @ApiModelProperty(value = "返回码")
    private Integer code;
    @ApiModelProperty(value = "返回消息")
    private String message;
    @ApiModelProperty(value = "返回数据")
    private Map<String, Object> data = new HashMap<String, Object>();
    private R(){

    }
    //成功静态方法
    public static R ok(){
        R r = new R();
        r.setSuccess(true);
        r.setCode(20000);
        r.setMessage("成功");
        return r;
    }
    //失败静态方法
    public static R error(){
        R r = new R();
        r.setSuccess(false);
        r.setCode(20001);
        r.setMessage("失败");
        return r;
    }
    public R success(Boolean success){
        this.setSuccess(success);
        return this;
    }
    public R message(String message){
        this.setMessage(message);
        return this;
    }
    public R code(Integer code){
        this.setCode(code);
        return this;
    }
    public R data(String key, Object value){
        this.data.put(key, value);
        return this;
    }
    public R data(Map<String, Object> map){
        this.setData(map);
        return this;
    }


}

2.统一异常处理(抛出异常时也得统一返回数据)

创建下图所示的类
在这里插入图片描述
代码如下

@RestControllerAdvice
public class ProjectExceptionAdvice {
    //拦截所有异常信息
    @ExceptionHandler
    public R doException(Exception e){
        e.printStackTrace();
        return R.error().message("执行了全局异常处理");
    }
}

十、创建控制层

在这里插入图片描述

@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    BookService2 bookService2;
    //查询全部数据
    @GetMapping()
    public R getAll() {
        return R.ok().data("allBooks", bookService2.list(null));
    }
    @GetMapping("{id}")
    public R getById(@PathVariable String id) {
        if(bookService2.getById(id) != null) {
            return R.ok().data("book",bookService2.getById(id));
        }else{
            return R.error();
        }
    }
    //添加数据
    @PostMapping
    public R save(@RequestBody Book book)  {
        if (bookService2.save(book)) {
            return R.ok();
        } else {
            return R.error();
        }
    }
//更新数据
    @PutMapping()
    public R update(@RequestBody Book book) {
        if (bookService2.updateById(book)) {
            return R.ok();
        } else {
            return R.error();
        }
    }
//删除数据
    @DeleteMapping("{id}")
    public R delete(@PathVariable String id) {
        if (bookService2.deleteBook(id)) {
            return R.ok();
        } else {
            return R.error();
        }
    }
//分页+条件查询
    @PostMapping("{current}/{size}")
    public R getByPage(@PathVariable int current, @PathVariable int size , @RequestBody(required = false)BookSearch bookSearch) {
        QueryWrapper<Book> wrapper = new QueryWrapper<>();
        String name = bookSearch.getName();
        String type = bookSearch.getType();
        String description = bookSearch.getDescription();
        if(Strings.isNotEmpty(name)){
            wrapper.like("name",name);
        }
        if(Strings.isNotEmpty(type)){
            wrapper.like("type",type);
        }
        if(Strings.isNotEmpty(description)){
            wrapper.like("description",description);
        }
        Page<Book> page = new Page<>(current, size);
        return R.ok().data("page", bookService2.page(page, wrapper));
    }
}

十一、启动类

@SpringBootApplication
@ComponentScan(basePackages = {"com.xsk"})//你的包名
public class Mydemo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Mydemo1Application.class, args);
    }

}

十二、前端的主要JS代码(主要是我不太会)

如有需要所有代码,可以私信博主

<script>
    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: 10,//每页显示的记录数
                total: 0,//总记录数

            },
            bookSearch: {

            }
        },
        //钩子函数,VUE对象初始化完成后自动执行
        created() {
            this.getAll();
        },
        methods: {
            //列表
            // getAll() {
            //     axios.get("/books").then(res => {
            //         this.dataList = res.data.data.allBooks;
            //     })
            // },
            //弹出添加窗口
            handleCreate() {
                this.dialogFormVisible = true;
                this.resetForm();
            },
            //重置表单
            resetForm() {
                this.formData = {}
            },
            //添加
            handleAdd() {
                axios.post("/books",this.formData).then(res =>{
                    if(res.data.code == 20000){
                        this.dialogFormVisible = false;
                        this.$message.success('添加成功');
                    }else{
                        this.$message.error('添加失败');
                    }

                }).finally(() =>{
                    this.getAll();
                })
            },
            //取消
            cancel() {
                this.dialogFormVisible = false;
                this.dialogFormVisible4Edit = false;
                this.$message.info('当前操作取消');
            },
            // 删除
            handleDelete(row) {
                console.log(row.id)

                this.$confirm("此操作永久删除当前信息,是否继续?","提示",{type:"info"}).then(() =>{
                    axios.delete("/books/"+row.id).then(res =>{
                        if(res.data.code == 20000){
                            this.$message.success('删除成功');
                        }else{
                            this.$message.error('数据同步失败,自动刷新');
                        }
                    }).finally(() =>{
                        this.getAll();
                    })
                }).catch(() =>{;
                    this.$message.info('取消操作');
                })
            },
            //弹出编辑窗口
            handleUpdate(row) {
                    axios.get("/books/"+row.id).then(res =>{
                        if(res.data.code == 20000){
                            this.dialogFormVisible4Edit = true;
                            this.formData = res.data.data.book;
                        }else{
                            this.$message.error('数据同步失败');
                        }
                    })

            },
            //修改
            handleEdit() {
                axios.put("/books",this.formData).then(res =>{
                    if(res.data.code == 20000){
                        this.dialogFormVisible4Edit = false;
                        this.$message.success('修改成功');
                    }else{
                        this.$message.error('修改失败');
                    }
                }).finally(() =>{
                    this.getAll();
                })
            },
            //分页条件查询
            getAll(page = 1) {
                this.pagination.currentPage = page;
                axios.post("/books/"+this.pagination.currentPage+"/"+this.pagination.pageSize,this.bookSearch).then(res => {
                    this.dataList = res.data.data.page.records;
                    this.pagination.total = res.data.data.page.total;
                })
            }
        }
    })

</script>

十三、结果

在这里插入图片描述


总结、

但愿吉祥

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值