书城管理系统(后端接口)

      基于最近帮助朋友做毕设的时候给我整崩溃了,没有java开发工具,不会SpringBoot+vue写前后端增删改查,不会用人人开源框架和若以框架等等。。。。。。。。。

 所以,出一套超级简单的java开发教程。帮助那些编码能力差的人理解SpringBoot+Vue开发,这套教程与我之前写的那套有所不同的是,这套上一套更精细,更简单,更容易理解,功能更强大。

 实现效果

总之是适合给哪些会一些ssm框架,懂一点js和vue的朋友学习参考(*^▽^*)

准备工作:

java开发工具百度网盘地址:

链接:https://pan.baidu.com/s/18gH-6AsQtHtIIyJNxJPl9w?pwd=1111 
提取码:1111

mysql、数据库可视化工具Navicat、新版idea、vscode、node.js 18和16版本运行文件、破解文件甚至jdk我都给你准备好了。

网上有破解教程,你找一个教程安装就行了。真的不会的话你在下面留言,我看到了跟你联系。

开发工具:

idea 2021.1.3           maven 3.8.1           node 16         vscode 17

jdk 1.8                        mysql 8.0             Navicat 16       

项目Gitee仓库地址:超级简单的前后端SpringBoot+Vue练手项目: 项目架构为前后端分离模式,使用SpringBoot框架和Vue框架进行开发的书城管理系统,可以实现书城书本图片上传,修改等crud操作。 (gitee.com)

开发步骤:

1、sql

CREATE TABLE `book` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '序号',
  `picture` varchar(2000) DEFAULT NULL COMMENT '图片',
  `name` varchar(200)  DEFAULT NULL COMMENT '书本名称',
  `introduce` varchar(200)  DEFAULT NULL COMMENT '介绍',
  `publish` varchar(200)  DEFAULT NULL COMMENT '出版社',
  `auth` varchar(200)  DEFAULT NULL COMMENT '作者',
  `price` double DEFAULT NULL COMMENT '价格',
  `is_deleted` tinyint unsigned DEFAULT '0' COMMENT '逻辑删除 1(true)已删除, 0(false)未删除',
  `gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
  `gmt_modified` datetime DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=8 COMMENT='书本信息表';

2、用idea新建一个SpringBoot项目

 然后点击下一步选择依赖,这里我们选择一个web的就行,其他的我们稍后配置。我这里的SpringBoot版本是2.6.13

 3、添加pom依赖和修改application.properties配置文件

添加pom依赖

<dependencies>
        <!--spring 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>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>

        <!--spring2.X集成redis所需common-pool12-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.6.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.4.12</version>
        </dependency>
    </dependencies>

因为我们想实现书本图片上传、修改、和展示,而且力求一种最简单的方式,那我们只能在本地新建一个文件夹专门用来存放图片,到时在配置一个映射关系让用户访问就行。我这里是在E盘新建了一个images文件夹专门存放图片

# 应用服务 WEB 访问端口
server.port=8785
server.tomcat.uri-encoding=UTF-8

# 应用连接数据库
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/book?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# mybatis-plus 配置
# 配置mapper.xml文件位置
mybatis-plus.mapper-locations=classpath:/mapper/**/*.xml
# 配置mybatis打印SQL
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 全局配置mybatis主键自增策略
mybatis-plus.global-config.db-config.id-type=auto

#文件上传地址
file-save-path=E:/images/


# 数据库时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=Asia/Shanghai

 然后把项目框架搭建好就是entity,mapper,service,controller,config,utils目录建好,然后把原来自带的web和static删掉

 entity包下存放实体类,book实体类实现Serializable接口实现序列化,@Data,@TableName,@TableId和@TableFiled注解是mybatis-plus提供的,@TableName用来标注你映射的是哪张表,@TableId用来映射表的主键和主键自增策略,我这里用的是整型自增。剩下的也是这个道理。

@Data
@TableName("book")
public class Book implements Serializable{

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    /**
     * 书本图片
     */
    @TableField("picture")
    private String picture;

    /**
     * 书本名称
     */
    @TableField("name")
    private String name;

    /**
     * 书本介绍
     */
    @TableField("introduce")
    private String introduce;

    /**
     * 出版社
     */
    @TableField("publish")
    private String publish;

    /**
     * 作者
     */
    @TableField("auth")
    private String auth;

    /**
     * 价格
     */
    @TableField("price")
    private Double price;

    /**
     * 删除标志
     */
    @TableField("is_deleted")
    private Integer isDeleted;

    /**
     * 创建时间
     */
    @TableField("gmt_create")
    private Date gmtCreate;

    /**
     * 修改时间
     */
    @TableField("gmt_modified")
    private Date gmtModified;
}

utils包下存放的是一些用具类和封装好的统一请求API返回类型

public class Code {
    //系统业务执行成功
    public static final String WORK_OK = "00000";

    //系统业务出错
    public static final String WORK_ERR = "A0001";

    //业务执行中
    public static final String WORKING = "A0002";
}
public class R {

    private String code;
    private String message;
    private Object data;

    public R() {
    }

    public R(String code, String message) {
        this.code = Code.WORK_OK;
        this.message = message;
    }

    public R(String code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }


    public String getCode() {
        return code;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

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


}
public class TimeUtil {

    public static Date getTime(){
        Date date = new Date();
        return date;
    }
}

然后在config文件夹下编写几个配置类,来实现一共mybatis-plus的分页,web映射,跨域

 CorsConfig配置跨域

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOriginPatterns("*")
            .allowCredentials(true)
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .maxAge(3600);
    }
}

 MybatisPlusConfig实现分页插件配置,这里还可以配置mybatis-plus其他优秀插件

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

 WebConfig配置映射资源

@Configuration
public class WebConfig implements WebMvcConfigurer {
    /**
     * 图片保存路径,自动从yml文件中获取数据
     *   示例: E:/images/
     */
    @Value("${file-save-path}")
    private String fileSavePath;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        /**
         * 配置资源映射
         * 意思是:如果访问的资源路径是以“/images/”开头的,
         * 就给我映射到本机的“E:/images/”这个文件夹内,去找你要的资源
         * 注意:E:/images/ 后面的 “/”一定要带上
         */
        registry.addResourceHandler("/images/**")
                .addResourceLocations("file:"+fileSavePath);
    }
}

接着编写controller层接口,BookController这里一共有6个接口

BookController

@RestController
@RequestMapping("book")
public class BookController {

    @Autowired
    private BookService bookService;

    /**
     * 时间格式化
     */
    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd/");

    /**
     * 图片保存路径
     */
    @Value("${file-save-path}")
    private String fileSavePath;

    /**
     * 图片上传
     *
     * @param file
     * @param request
     * @return
     */
    @PostMapping("/upload")
    public R uploadPicture(@RequestParam("file") MultipartFile file, HttpServletRequest request) {

        String directory = simpleDateFormat.format(TimeUtil.getTime());


        /**
         * 文件保存目录 E:/images/2020/03/15/
         * 如果目录不存在,则创建
         */
        File dir = new File(fileSavePath + directory);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        System.out.println("图片上传,保存的位置:" + fileSavePath + directory);

        /**
         * 给文件重新设置一个名字
         * 后缀
         */
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String newFileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;

        //4.创建这个新文件
        File newFile = new File(fileSavePath + directory + newFileName);
        //5.复制操作
        try {
            file.transferTo(newFile);
            //协议 :// ip地址 :端口号 / 文件目录(/images/2020/03/15/xxx.jpg)
            String url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/images/" + directory + newFileName;
            System.out.println("图片上传,访问URL:" + url);
            return new R(Code.WORK_OK, "上传成功", url);
        } catch (IOException e) {
            return new R(Code.WORK_ERR, "IO异常");
        }
    }


    /**
     * 书城条件分页查询
     * @param current
     * @param pageSize
     * @param book
     * @return
     */
    @PostMapping("/list/{current}/{pageSize}")
    public R selectPage(@PathVariable("current") long current,@PathVariable("pageSize") long pageSize,
                        @RequestBody Book book){
        //mybatis-plus分页
        Page<Book> page = new Page<>(current, pageSize);
        QueryWrapper<Book> wrapper = new QueryWrapper<>();

        String name = book.getName();
        if (!StringUtils.isEmpty(name)){
            wrapper.like("name",name);
        }
        wrapper.eq("is_deleted","0");
        wrapper.orderByDesc("gmt_modified");

        Page<Book> result = bookService.selectPage(page, wrapper);
        if (StringUtils.isEmpty(String.valueOf(result.getRecords()))){
            return new R(Code.WORK_ERR,"查询为空");
        }
        return new R(Code.WORK_OK,"操作成功",result);
    }

    /**
     * 书城新增一本书
     * @param book
     * @return
     */
    @PostMapping("/add-one-book")
    public R addBookInfo(@RequestBody Book book){
        int flag = bookService.addBookInfo(book);
        if (flag != 1){
            return new R(Code.WORK_ERR,"新增书本信息失败!");
        }else {
            return new R(Code.WORK_OK,"新增书本信息成功!");
        }
    }

    /**
     * 根据id获取书本信息
     * @param id
     * @return
     */
    @GetMapping("/get-one-book/{id}")
    public R getOneBook(@PathVariable("id") Integer id){
        Book result = bookService.getOneBook(id);
        if (!Strings.isNotEmpty(result.getName())){
            return new R(Code.WORK_ERR,"根据id获取书本信息失败!");
        }
        return new R(Code.WORK_OK,"获取书本信息成功",result);
    }

    /**
     * 修改一本书的信息
     * @param book
     * @return
     */
    @PostMapping("/upd-one-book")
    public R updOneBook(@RequestBody Book book){
        int flag = bookService.updOneBook(book);
        if (flag != 1){
            return new R(Code.WORK_ERR,"新增书本信息失败!");
        }else {
            return new R(Code.WORK_OK,"新增书本信息成功!");
        }
    }

    /**
     * 删除一本书
     * @param book
     * @return
     */
    @PostMapping("/delete-one-book")
    public R deleteOneBook(@RequestBody Book book){
        int flag = bookService.deleteOneBook(book);
        if (flag != 1){
            return new R(Code.WORK_ERR,"新增书本信息失败!");
        }else {
            return new R(Code.WORK_OK,"新增书本信息成功!");
        }
    }
}

Service层接口

BookService

public interface BookService {

    /**
     * 书城条件分页查询
     * @param page
     * @param wrapper
     * @return
     */
    Page<Book> selectPage(Page<Book> page, QueryWrapper<Book> wrapper);

    /**
     * 增加一本书的信息
     * @param book
     * @return
     */
    int addBookInfo(Book book);

    /**
     * 根据id获取书本信息
     * @param id
     * @return
     */
    Book getOneBook(Integer id);

    /**
     * 删除一本书
     * @param book
     * @return
     */
    int deleteOneBook(Book book);

    /**
     * 修改一本书的信息
     * @param book
     * @return
     */
    int updOneBook(Book book);
}

BookServiceImpl

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookMapper bookMapper;

    /**
     * 书城条件分页查询
     *
     * @param page
     * @param wrapper
     * @return
     */
    @Override
    public Page<Book> selectPage(Page<Book> page, QueryWrapper<Book> wrapper) {
        return bookMapper.selectPage(page,wrapper);
    }

    /**
     * 增加一本书的信息
     *
     * @param book
     * @return
     */
    @Override
    public int addBookInfo(Book book) {
        Book entity = new Book();
        entity.setId(book.getId());
        entity.setPicture(book.getPicture());
        entity.setName(book.getName());
        entity.setIntroduce(book.getIntroduce());
        entity.setPublish(book.getPublish());
        entity.setAuth(book.getAuth());
        entity.setPrice(book.getPrice());
        entity.setIsDeleted(0);
        entity.setGmtCreate(TimeUtil.getTime());
        entity.setGmtModified(TimeUtil.getTime());
        return bookMapper.insert(entity);
    }

    /**
     * 根据id获取书本信息
     *
     * @param id
     * @return
     */
    @Override
    public Book getOneBook(Integer id) {
        Book book = bookMapper.selectById(id);
        return book;
    }

    /**
     * 删除一本书
     *
     * @param book
     * @return
     */
    @Override
    public int deleteOneBook(Book book) {
        Book entity = new Book();
        entity.setId(book.getId());
        entity.setIsDeleted(1);
        entity.setGmtModified(TimeUtil.getTime());
        return bookMapper.updateById(entity);
    }

    /**
     * 修改一本书的信息
     *
     * @param book
     * @return
     */
    @Override
    public int updOneBook(Book book) {
        Book entity = new Book();
        entity.setId(book.getId());
        entity.setPicture(book.getPicture());
        entity.setName(book.getName());
        entity.setIntroduce(book.getIntroduce());
        entity.setPublish(book.getPublish());
        entity.setAuth(book.getAuth());
        entity.setPrice(book.getPrice());
        entity.setGmtModified(TimeUtil.getTime());
        return bookMapper.updateById(entity);
    }
}

 BookMapper

@Mapper
public interface BookMapper extends BaseMapper<Book> {
}

 BookMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.czy.booktest02.demos.mapper.BookMapper">


</mapper>

 因为咱们整合了mybatis-plus,而且项目也都是正常的crud操作,所以BookMapper.xml基本上就没写啥sql语句,等后期做好玩的功能了,我在给补上。

这样后端接口就开发好了,我一会另起一页写前端。

猜你喜欢

转载自blog.csdn.net/weixin_46511995/article/details/130210762