zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

SpringBoot+mybatis-plus+mysql实现简单后台管理demo

mysqlSpringBoot后台mybatis 实现 管理 简单 Demo
2023-09-11 14:20:19 时间

使用SpringBoot+mybatis-plus+mysql实现简单demo(后台管理增删改查)

一、使用idea新建Springboot项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
选择打开方式,我这里选择新窗口打开
在这里插入图片描述
这样基础的项目创建好了。
在这里插入图片描述

二、配置pom.xml 和 application.yml

pom.xml配置如下:

 <!--web-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
     <scope>test</scope>
 </dependency>

 <!--热部署-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-devtools</artifactId>
     <scope>runtime</scope>
     <optional>true</optional>
 </dependency>
 <!--lombok-->
 <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
     <optional>true</optional>
 </dependency>
 <!--mybatis-plus自动的维护了mybatis以及mybatis-spring的依赖,
 在springboot中这三者不能同时的出现,避免版本的冲突,表示:跳进过这个坑-->
 <!--mybatis-plus-->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-boot-starter</artifactId>
     <version>3.4.3</version>
 </dependency>
 <!--mysql驱动-->
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <scope>runtime</scope>
 </dependency>
 <!-- alibaba的druid数据库连接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid</artifactId>
     <version>1.1.20</version>
 </dependency>

 <!-- alibaba的druid数据库连接池 -->
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.20</version>
 </dependency>

application.yml(若没有,则在src/main/resources/下面新建此文件):

# 服务端口
server:
  port: 8083

# 数据源配置
spring:
  datasource:
    name: test
    url: jdbc:mysql://localhost:3306/db_test?&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSl=false
    username: root
    password:
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource

    ## 配置连接池信息
    ## 初始化大小,最小,最大
    initialSize: 5
    minIdle: 5
    maxActive: 30
    ## 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

    # 超过时间限制是否回收
    removeAbandoned: true
    # 超时时间;单位为秒。180秒=3分钟
    removeAbandonedTimeout: 180
    # 关闭abanded连接时输出错误日志
    logAbandoned: true

# mybatis-plus 默认扫描mapper.xml的目录
mybatis-plus:
  mapper-locations: classpath*:/mapper/*.xml
  #配置sql打印日志
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

三、编写简单的增删改查

在src/main/java/com.example.demo新建下面几个包:
entity:实体类
controller:控制器
dao:映射文件
service:业务处理
在src/main/
以商品管理为例:
1.数据表:

CREATE TABLE `t_product` (
  `product_id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL COMMENT '标题',
  `sub_title` varchar(255) DEFAULT NULL COMMENT '副标题',
  `sale_price` decimal(10,2) DEFAULT NULL COMMENT '商品售价',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `create_by` int(11) DEFAULT NULL COMMENT '创建者',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  `update_by` int(11) DEFAULT NULL COMMENT '修改者',
  PRIMARY KEY (`product_id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COMMENT='商品表';

2.编写商品实体,使用@Data注解

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
 * @author qzz
 */
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_product")
public class Product implements Serializable {
    private  static final long serialVersionUID = 1L;
    /**
     * 商品id
     */

    @TableId(value="product_id", type = IdType.AUTO)
    private Integer product_id;
    /**
     * 商品标题
     */
    @TableField("title")
    private String title;
    /**
     * 商品标题
     */
    @TableField("sub_title")
    private String sub_title;
    /**
     * 商品售价
     */
    @TableField("sale_price")
    private Double sale_price;
    /**
     * 创建者
     */
    @TableField(value = "create_by",fill = FieldFill.INSERT)
    private Integer create_by;
    /**
     * 创建时间
     * timezone:是时间设置为东八区,避免时间在转换中有误差
     * @DateTimeFormat:从前台页面将时间类型的数据传入数据库中
     * @JsonFormat:从数据库中获取日期类型的数据传到前台展示
     */
    @TableField(value = "create_time",fill = FieldFill.INSERT)
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date create_time;
    /**
     * 修改时间
     */
    @TableField(value = "update_time",fill = FieldFill.UPDATE)
    private Date update_time;
    /**
     * 修改者id
     */
    @TableField(value = "update_by",fill = FieldFill.UPDATE)
    private Integer update_by;

}

3.编写ProductDao

package com.example.demo.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Product;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * @author qzz
 */
@Repository
public interface ProductDao extends BaseMapper<Product> {
    
    /**
     * 分页获取列表:执行自己编写的sql
     * @param page
     * @param product
     * @return
     */
    List<Map<String,Object>> getProductListByPage(Page page, @Param("product") Product product);
}

由于项目中整合了mybatis-plus,所以基本的增删改查sql不需要手动编写,只需要继承BaseMapper即可。

需要手动编写sql的需要在ProductDao 自行定义。

4.编写Service以及Service的实现类
ProductService:

package com.example.demo.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Product;
import java.util.List;
import java.util.Map;

/**
 * @author qzz
 */
public interface ProductService{


    /**
     * 添加商品信息
     * @param product
     * @return
     */
    int addProduct(Product product);

    /**
     * 编辑商品信息
     * @param product
     * @return
     */
    int updateProduct(Product product);

    /**
     * 获取商品列表信息
     * @param queryWrapper
     * @return
     */
    List<Product> selectList(Wrapper<Product> queryWrapper);

    /**
     * 获取商品列表信息
     * @param queryWrapper
     * @return
     */
    List<Map<String,Object>> selectListMaps(Wrapper<Product> queryWrapper);

    /**
     * 分页获取商品列表信息
     * @return
     */
    IPage<Map<String,Object>> selectListByPage(Page page, Wrapper<Product> queryWrapper);

    /**
     * 批量删除商品
     * @param ids
     * @return
     */
    int deleteBatchProduct(Integer[] ids);

    /**
     * 分页获取列表:执行自己编写的sql
     * @param page
     * @param product
     * @return
     */
    List<Map<String,Object>> getProductListByPage(Page page, Product product);
}

ProductServiceImpl:

package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dao.ProductDao;
import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author qzz
 */
@Service("ProductService")
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductDao productDao;


    /**
     * 添加商品信息
     * @param product
     * @return
     */
    @Override
    public int addProduct(Product product) {
        return productDao.insert(product);
    }

    /**
     * 编辑商品信息
     * @param product
     * @return
     */
    @Override
    public int updateProduct(Product product) {
        return productDao.updateById(product);
    }

    /**
     * 获取商品列表信息
     * @param queryWrapper
     * @return
     */
    @Override
    public List<Product> selectList(Wrapper<Product> queryWrapper) {
        return productDao.selectList(queryWrapper);
    }

    /**
     * 获取商品列表信息
     * @param queryWrapper
     * @return
     */
    @Override
    public List<Map<String, Object>> selectListMaps(Wrapper<Product> queryWrapper) {
        return productDao.selectMaps(queryWrapper);
    }

    /**
     * 分页获取商品列表信息
     * @return
     */
    @Override
    public IPage<Map<String,Object>> selectListByPage(Page page, Wrapper<Product> queryWrapper) {
        return productDao.selectMapsPage(page,queryWrapper);
    }

    /**
     * 批量删除商品
     * @param ids
     * @return
     */
    @Override
    public int deleteBatchProduct(Integer[] ids) {
        return productDao.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 分页获取列表:执行自己编写的sql
     * @param page
     * @param product
     * @return
     */
    @Override
    public List<Map<String,Object>> getProductListByPage(Page page,Product product) {
        return productDao.getProductListByPage(page,product);
    }


}

4.编写Controller

package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Product;
import com.example.demo.service.ProductService;
import com.example.demo.utils.PageData;
import com.example.demo.utils.Result;
import com.example.demo.utils.Tools;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @author qzz
 */
@RestController
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductService productService;


    /**
     * 分页获取商品列表
     */
    @GetMapping("/page")
    public Result page(HttpServletRequest request){
        Page<Product> page = new Page<>(1,5);
        QueryWrapper<Product> queryWrapper = new QueryWrapper();
        //分页查看商品列表
        IPage<Map<String,Object>> pageInfo = productService.selectListByPage(page,queryWrapper);
        //返回结果集
        return new Result().ok(new PageData<>(pageInfo.getRecords(),pageInfo.getTotal()));
    }

    /**
     * 根据条件获取列表
     */
    @GetMapping("/list")
    public Result getProductList(@RequestParam String title, HttpServletRequest request){
        QueryWrapper<Product> queryWrapper = new QueryWrapper();
        queryWrapper.like(Tools.notEmpty(title),"title",title);
        //此方法 sql有结果,但是返回数据除了title列,其他列都是null
        // List<Product> list = productService.selectList(queryWrapper);
        List<Map<String,Object>> list = productService.selectListMaps(queryWrapper);

        return new Result().ok(list);
    }

    /**
     * 添加商品信息
     */
    @PostMapping("add")
    public Result addProduct(@RequestBody Product product){
        product.setCreate_by(1);
        product.setCreate_time(new Date());
        int n = productService.addProduct(product);
        if(n>0){
            return new Result().ok(product.getProduct_id());
        }else{
            return new Result().error(400,"添加商品失败");
        }
    }

    /**
     * 编辑商品信息
     */
    @PostMapping("update")
    public Result updateProduct(@RequestBody Product product){
        product.setUpdate_by(1);
        product.setUpdate_time(new Date());
        int n = productService.updateProduct(product);
        if(n>0){
            return new Result();
        }else{
            return new Result().error(400,"编辑商品失败");
        }
    }

    /**
     * 根据ids删除商品信息
     */
    @PostMapping("del")
    public Result delProduct(@RequestBody Integer[] ids){
        int n = productService.deleteBatchProduct(ids);
        if(n>0){
            return new Result();
        }else{
            return new Result().error(400,"删除商品失败");
        }
    }

    /**
     * 分页获取商品列表:执行自己的sql
     * @param product  条件
     * @param currentPage 当前页
     * @param pageSize 每页个数
     * @return
     */
    @PostMapping("/productList")
    public Result productList(@RequestBody Product product ,@RequestParam Integer currentPage,@RequestParam Integer pageSize){
        Page<Product> page = new Page<>(currentPage,pageSize);
        //分页查看商品列表
        List<Map<String,Object>> list = productService.getProductListByPage(page,product);
        //返回结果集
        return new Result().ok(new PageData<>(list,page.getTotal()));
    }

}

6.在启动类上,添加dao的扫描
在这里插入图片描述
响应数据做了相关的处理:封装了一个类

package com.example.demo.utils;

import java.io.Serializable;

/**
 * 响应数据
 * @author qzz
 */
public class Result<T> implements Serializable {

    private static final long serialVersionUID=1L;

    /**
     * 编码 0:成功 其他值代表失败
     */
    private int code = 0;

    /**
     * 消息内容
     */
    private String msg = "success";

    /**
     * 响应数据
     */
    private T data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Result<T> ok (T data){
        this.setData(data);
        return this;
    }

    public Result<T> error(){
        this.code = 500;
        this.msg="网络出错,请联系系统管理员";
        return this;
    }

    public Result<T> error(int code,String msg){
        this.code = code;
        this.msg=msg;
        return this;
    }

    public boolean success(){
        return code == 0 ? true : false;
    }
}

另外,有关分页查询,mybatis-plus有提供分页插件,使用如下:
(1)添加配置类

package com.example.demo.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 新建一个MybatisPlus配置类 返回一个分页拦截器
 * @author qzz
 */
@Configuration
@MapperScan(basePackages = {"com.example.demo.dao"})
public class MybatisPlusConfig {

    /**
     * Mybatis Plus 3.4.0版本及其之后的版本采用新的分页:
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //向Mybatis过滤器链中添加分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        //还可以添加其他的拦截器
        return mybatisPlusInterceptor;
    }
}

(2)使用
在这里插入图片描述

其中分页工具类PageData:

package com.example.demo.utils;

import lombok.Data;

import java.io.Serializable;
import java.util.List;

/**
 * 分页工具类
 * @author qzz
 */
@Data
public class PageData<T> implements Serializable {

    private  static final long serialVersionUID = 1L;

    /**
     * 总记录数
     */
    private int total;
    /**
     * 列表数据
     */
    private List<T> list;

    public PageData(List<T> list, long total){
        this.list = list ;
        this.total = (int) total;
    }

}

这样一个简单的增删改查demo就编写好了。

四、测试

使用postman进行测试:

1.商品添加(product/add)
在这里插入图片描述
注意点:
请求方式:POST
请求头:Content-Type:application/json
请求参数:

在这里插入图片描述
点击测试,返回结果:
在这里插入图片描述
数据库新增了一条记录:
在这里插入图片描述
使用添加接口多添加几条数据,如下:
在这里插入图片描述
2.商品编辑(product/update)

把product_id=2的title修改为 家局创意垃圾桶。

编辑接口的请求方式和请求头 与 商品添加接口 相同。

在这里插入图片描述
数据库数据:
在这里插入图片描述
3.分页查询商品列表(product/page)
在这里插入图片描述
4.分页获取商品列表:执行自己编写的sql(product/productList)
在这里插入图片描述