Springboot +Mybatis 项目实战(改自白卷White-jotter项目)

开头先附上原作者原文连接
https://learner.blog.csdn.net/article/details/88925013
最近准备学习Springboot
所以就找到了大佬Evan-Nightly的“白卷”项目
里面的步骤大部分都很清晰,解释得也很到位
个别问题在评论区都有解决方案
虽然我也很赞同原作者的说法
我真是爱死 JPA 了,用 Mybatis 写 SQL 真的烦(我可不是说 Mybatis 不好用哈)。
但是毕竟刚学习了Mybatis,所以打算将这个项目改成用Mybatis来对SQL进行操作,因为原作者的项目实现了前后端分离,所以更改成Mybatis只对后端有改动,前端几乎没有改动。
另外,本人是跟着原文学到项目(十)之后才进行了更改,本博客的基础是已经实现了项目(十)之前的所有内容(包括项目(十)除了部署之后的内容)

一、导入Mybatis相关依赖

pom.xml里面添加以下代码

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

然后在pom.xml里面中<build>标签中添加以下内容,这段代码作用是防止我们资源导出失败的问题。里面的src/main/resources就是我们做项目的时候配置文件存放的地方,这段代码的大意就是在编译的时候将会带上src/main/resources里边的propertiesxmlyml文件。

<resources>
     <resource>
         <directory>src/main/resources</directory>
         <includes>
             <include>**/*.properties</include>
             <include>**/*.xml</include>
             <include>**/*.yml</include>
         </includes>
         <filtering>true</filtering>
     </resource>
 </resources>

二、修改配置文件

  1. 首先删除原来项目中的application.properties文件
  2. src/main/resources下创建配置文件application.yml,如图
    在这里插入图片描述
    里面的内容如下
spring
    profiles:
        active: dev
        #这里为什么使用dev,后面会解释
  1. 在同级目录下创建配置文件application-dev.yml
server:
  port: 8080
 
 #注意事项:1.用户名和密码改成自己数据库的用户名跟密码;2.url中的‘database’改成自己的数据库名字,“白卷”项目实战教程中的数据库名字是white_jotter
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
 
mybatis:
  mapper-locations: classpath:mapping/*.xml
  type-aliases-package: com.example.demo.entity
 
#showSql
logging:
  level:
    com.example.demo.mapper: debug

在这里补充两点小知识:
1).yml的基本语法有以下几点:对大小写很敏感;使用缩进来表示层级关系,具体缩进的空格数不重要,相同层级的元素左对齐即可(如上面中的usernamepassword);缩进不允许使用tab,只能使用空格;#用来表示注释
2)在Springboot中多环境的配置文件名都要满足格式application-{profile}.yml,上文使用到的application-dev.yml对应的是开发环境,其他的环境有:
application-test.yml 测试环境
application-prod.yml 生产环境

三、修改后端代码

修改主要涉及以下几个类和接口,为了阅读方便所以我把dao改成了mapper
在这里插入图片描述
还添加了三个映射文件
BookMapping.xml
CategoryMapping.xml
UserMaping.xml
在这里插入图片描述
不着急,我们一步步来,首先是三个接口
BookMapper.java

package com.hong.wj.mapper;

import org.apache.ibatis.annotations.Mapper;
import com.hong.wj.pojo.Book;
import com.hong.wj.pojo.Category;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @Author hong
 * @Date 2022/2/22 21:20
 * @Version 1.0
 */
 
//这里主要是添加了一个通过Id搜索book
//然后把添加book和修改book分开成了两个方法
//“按照标题或作者查找”的参数只保留了一个
@Component
@Mapper
public interface BookMapper {
    List<Book> selectByCategory(Category category);
    List<Book> selectAllByTitleLikeOrAuthorLike(String keyword1);
    public List<Book> selectAll();
    public void deleteById(int id);
    public Book selectById(int id);
    public void addBook(Book book);
    public void updateBook(Book book);
}

CategoryMapper.java

package com.hong.wj.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.data.domain.Sort;
import com.hong.wj.pojo.Category;
import org.springframework.stereotype.Component;

import java.util.List;

//这个主要是改了名字(dao -> mapper),没什么其他改动
@Component
@Mapper
public interface CategoryMapper {
    public List<Category>  selectAll(Sort sort);
    public Category SelectById(int id);
}

UserMapper.java

package com.hong.wj.mapper;

import com.hong.wj.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;

//这个接口目前只有登陆验证的作用,新添用户功能尚未实现,不过写在这里也暂时没什么影响
@Component
@Mapper
public interface UserMapper {
    User selectByUsername(String username);

    User selectByUsernameAndPassword(String username,String password);

    void addUser(User user);
}

写完这三个接口接下来我们要去编写xml映射文件了,数据库还是用原来的数据库就行,无需改动
BookMapping.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.hong.wj.mapper.BookMapper">
    <resultMap id="BookResultMap" type="com.hong.wj.pojo.Book">
        <id column="id" property="id"/>
        <result column="cover" property="cover"/>
        <result column="title" property="title"/>
        <result column="author" property="author"/>
        <result column="date" property="date"/>
        <result column="press" property="press"/>
        <result column="abs" property="abs"/>
        <association property="category" javaType="com.hong.wj.pojo.Category" column="cid">
            <id column="c_id" property="id"/>
            <result column="c_name" property="name"/>
        </association>
    </resultMap>
    <select id="selectById" parameterType="int" resultMap="BookResultMap">
        select b.id, cover, title, author, date, press, abs, c.id c_id, c.name c_name from book b
        left join category c
        on c.id = b.cid
        where b.id = #{id}
    </select>
    <select id="selectByCategory" parameterType="com.hong.wj.pojo.Category" resultMap="BookResultMap">
        select b.id, cover, title, author, date, press, abs, c.id c_id, c.name c_name from book b
        left join category c
        on c.id = b.cid
        where b.cid = #{id}
    </select>
    <!--这里使用concat来给keyword添加通配符,如果先添加通配符%再传进来的话并不能使%起到通配符的作用-->
    <select id="selectAllByTitleLikeOrAuthorLike" parameterType="String" resultMap="BookResultMap">
        select b.id, cover, title, author, date, press, abs, c.id c_id, c.name c_name from book b
        left join category c
        on c.id = b.cid
        where title like concat('%',#{keyword1},'%') or Author like concat('%',#{keyword1},'%')
    </select>
    <select id="selectAll" resultMap="BookResultMap">
        select b.id, cover, title, author, date, press, abs, c.id c_id, c.name c_name from book b
        left join category c
        on c.id = b.cid
    </select>
    <delete id="deleteById" parameterType="Integer">
        delete from book where id = #{id}
    </delete>
    <insert id="addBook" parameterType="com.hong.wj.pojo.Book">
        insert into book (cover, title, author, date, press, abs, cid)
        values (#{cover}, #{title}, #{author}, #{date}, #{press}, #{abs}, #{category.id});
    </insert>
    <update id="updateBook" parameterType="com.hong.wj.pojo.Book">
        update book set cover = #{cover}, title = #{title}, author = #{author}, date = #{date}, press = #{press}, abs = #{abs}, cid = #{category.id}
        where id = #{id}
    </update>
</mapper>

CategoryMapping.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.hong.wj.mapper.CategoryMapper">
    <select id="selectAll" resultType="com.hong.wj.pojo.Category">
        select * from category
    </select>
    <select id="SelectById" resultType="com.hong.wj.pojo.Category">
        select * from category where id = #{id}
    </select>
</mapper>

UserMapping.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.hong.wj.mapper.UserMapper">
    <select id="selectByUsername" resultType="com.hong.wj.pojo.User">
        select * from user where username = #{username}
    </select>
    <select id="selectByUsernameAndPassword" resultType="com.hong.wj.pojo.User">
        select * from user where username = #{username} and password = #{password}
    </select>
    <insert id="addUser" parameterType="com.hong.wj.pojo.User">
        insert into user(id, username, password) values (#{id}, #{username}, #{password})
    </insert>
</mapper>

之后我们要去service层实现这三个mapper,本博客里面个别方法名有一点点小改动,但都是跟映射文件里面的是对应相同的
BookService.java
这里面的有几个小改动:把addupdate分开了;search方法里面的参数有改动;名字从dao改成了mapper这个后面就不说 ;查找全部book没有了排序sort我也忘了什么时候删掉了,不管了

package com.hong.wj.service;


import com.hong.wj.mapper.BookMapper;
import com.hong.wj.pojo.Book;
import com.hong.wj.pojo.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {
    @Autowired
    BookMapper bookMapper;

    @Autowired
    CategoryService categoryService;

    //查找所有book
    public List<Book> list(){
        return bookMapper.selectAll();
    }

    //根据id查找book
    public Book selectById(int id){
        return bookMapper.selectById(id);
    }

    //添加book
    public void add(Book book){
        bookMapper.addBook(book);
    }

    //更新book
    public void updateBook(Book book){
        bookMapper.updateBook(book);
    }

    //根据id删除书籍
    public void deleteById(int id){
        bookMapper.deleteById(id);
    }

    //根据分类查找书籍
    public List<Book> listByCategory(int cid){
        Category category = categoryService.get(cid);
        System.out.println("cid = " + cid);
        return bookMapper.selectByCategory(category);
    }

    public List<Book> Search(String keyword){
        return bookMapper.selectAllByTitleLikeOrAuthorLike(keyword);
    }
}

CategoryService.java

package com.hong.wj.service;

import com.hong.wj.mapper.CategoryMapper;
import com.hong.wj.pojo.Category;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CategoryService {
    @Autowired
    CategoryMapper categoryMapper;

    //查找所有分类
    public List<Category> list(){
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return categoryMapper.selectAll(sort);
    }

    //根据id获取分类
    public Category get(int id){
        Category c = categoryMapper.SelectById(id);
        return c;
    }
}

UserService.java

package com.hong.wj.service;

import com.hong.wj.mapper.UserMapper;
import com.hong.wj.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;
    
    //判断用户是否存在
    public boolean isExist(String username){
        User user = getByName(username);
        return null!=user;
    }

    //通过用户名获取用户
    public User getByName(String username){
        return userMapper.selectByUsername(username);
    }

    //通过用户名和密码获取用户
    public User get(String username, String password){
        return userMapper.selectByUsernameAndPassword(username,password);
    }

    //添加用户
    public void add(User user){
        userMapper.addUser(user);
    }
}

service层除了BookService其他两个变化不大,
最后我们把目光放回到LibraryController,先上源码

package com.hong.wj.controller;

import com.hong.wj.pojo.Book;
import com.hong.wj.service.BookService;
import com.hong.wj.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

@RestController
public class LibraryController {
    @Autowired
    BookService bookService;

    @CrossOrigin
    @GetMapping("/api/books")
    public List<Book> list(){
        return bookService.list();
    }

    @CrossOrigin
    @PostMapping("/api/books")
    public Book addOrUpdate(@RequestBody Book book){
        if(Objects.equals(null, bookService.selectById(book.getId()))){
            bookService.add(book);
            System.out.println("add a new book");
        }
        else{
            bookService.updateBook(book);
            System.out.println("update an old book");
        }
        return book;
    }

    @CrossOrigin
    @PostMapping("/api/delete")
    public void delete(@RequestBody Book book){
        bookService.deleteById(book.getId());
    }

    @CrossOrigin
    @GetMapping("/api/categories/{cid}/books")
    public List<Book> listByCategory(@PathVariable("cid") int cid) throws Exception{
        if(0 != cid){
            return bookService.listByCategory(cid);
        }else {
            return list();
        }
    }

    @CrossOrigin
    @GetMapping("/api/search")
    public List<Book> searchResult(@RequestParam("keywords") String keywords){
        if("".equals(keywords)){
            return bookService.list();
        }else
            return bookService.Search(keywords);
    }

    @CrossOrigin
    @PostMapping("api/covers")
    public String coversUpload(MultipartFile file){
        String folder = "D:/workspace/img";
        File imageFolder = new File(folder);
        File f = new File(imageFolder, StringUtils.getRandomString(6)
                + file.getOriginalFilename()
                .substring(file.getOriginalFilename()
                        .length() - 4));
        if(!f.getParentFile().exists()){
            f.getParentFile().mkdirs();
        }
        try {
            file.transferTo(f);
            String imgURL = "http://localhost:8443/api/file/"+f.getName();
            return imgURL;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }
}

这个类最大的改动就是addOrUpdate方法,添加了一个判断逻辑:如果数据库没有这本书,就调用新增(add)方法;否则调用修改(update)方法。

四、运行测试

前后端都运行,然后打开http://localhost:8080/login
账号:admin
密码:123
在这里插入图片描述
可以成功进到首页,没有问题
在这里插入图片描述
点进图书馆,也没有问题(图书的封面名字都是乱编的,请勿在意

在这里插入图片描述
接下来按照增删改查的顺序来试一遍

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


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


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


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总体检查下来没有什么大毛病,JPA改Mybatis到此就基本成功了。其他一些项目的小毛病大家去原项目的评论区都有很好的解决方案,最后再次附上原项目链接!
https://learner.blog.csdn.net/article/details/88925013

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值