Bootstrap

Spring boot 整合mybatis 对数据库进行增删改查操作——test类测试+实体类测试

      作为一个早早就随波逐流并不自量力出来实习的卷狗,公司里随便一个小项目的分项目都可以把我整破防,我更加深刻的感觉到计算机教学的质量的低下并对未来深感担忧,这里就简单记录一下我从0开始接触spring boot的相关历程吧——当然,参考了无数别人的文章,并遇到了众多玄学的bug.


不说废话了,至于如何创建springboot项目和如何为项目添加数据库,我这里就不介绍了,其他博文介绍的很详细,接下来上正文


1:在test类下进行增删改查操作

 A:这里是我的结构目录

如果是新手的化按照这样来就好了,如果有所了解了的,就当是个对照吧。

B:这里是我的  .properties文件的内容

#server
server.port= 8080

#datasource bendi
spring.datasource.url= jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true
spring.datasource.username= root
spring.datasource.password=passwd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver



mybatis.type-aliases-package=com.example.simple2.pojo
mybatis.mapper-locations= classpath:/mappers/*.xml
mybatis.configuration.call-setters-on-nulls=true
mybatis.configuration.map-underscore-to-camel-case=true

这里第一段是设置端口,默认是这个就行了,不写也没问题;

第二段是设置本地数据库相关的设置,这里用的是demo数据库,除了修改用户名和密码外,其他的不用变;

第三段是设置mybatis相关的东西,尤其要注意第一行和第二行,前者是存放数据库表名的包,后者是配置数据库语言的文件的,特别注意的是,如果你之前重来没有设置过数据库方言,建议去找一下相关教程把全局方言设置一下,不然就凉凉了。

C:POM.XML配置文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>simple2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>simple2</name>
    <description>simple2</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>


    <dependencies>

        <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--导入mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--springBoot数据库连接  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <!--支持热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>



    </dependencies>



    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

依赖项直接可以 用,不过建议一个一个复制,看多了有些东西自然就明白是怎么一回事了。

D:pojo层,存放数据表表头数据的类——以User.java为例子

package com.example.simple2.pojo;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class User
{
    private Integer id;
    private String name;
    private String sex;
    private Integer age;
    
}

一点要注意的就是这个里面的变量名称要和相应数据库里面的数据表表头名称一 一对应

E:mapper层,放置相关功能的接口——这里以UserMapper.java为例子

package com.example.simple2.mapper;

import com.example.simple2.pojo.User;
import org.springframework.stereotype.Controller;

import java.util.List;

@Controller
public interface UserMapper
{
    //查询所有数据
    List<User> getAll();
    //根据ID动态查询
    List<User> selectbyid(Integer ID);
    //修改操作
    int updatebyid();
    int updatebyname(String name,String sex);
    //增加操作
    int insertUser(Integer id);
    //删除操作
    int deleteUserById(int id);



}

F:resource层下的mappers层——放置相关数据库操作的文件,与mapper层之间有着紧密的联系,这里以UserMapper.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.example.simple2.mapper.UserMapper">
    <!--查询所有数据-->
    <select id="getAll" resultType="User">
        select * from user
    </select>
    <select id="selectbyid" resultType="User">
        select * from user where id=#{id}
    </select>
    <update id="updatebyid">
       update user set sex='女' where id=2
    </update>
    <update id="updatebyname">
        update user set sex=#{sex} where name=#{name}
   </update>
    <insert id="insertUser">
        insert into user (id) values (#{id});
    </insert>
    <delete id="deleteUserById" parameterType="Integer">
        delete from user where id=#{id}
    </delete>

</mapper>

特别注意的是namespace要严格对应到相关的接口文件(可以简单的理解为有@Mapper注解的文件)

其次是数据库的一些语法主要不要出错

特别提到的,如果idea里面提供的xml模板不是这样或者想要的类型,直接去自己创造一个模板就行了,具体的其他人的博客里有详细的介绍,这里只是提一嘴。

G;最后就是test目录下的test文件了

package com.example.simple2;

import com.example.simple2.mapper.UserMapper;
import com.example.simple2.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Scanner;

@SpringBootTest
class Simple2ApplicationTests {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void getAll(){
        List<User> all = userMapper.getAll();
        for (User user:all){
            System.out.println(user);
        }
    }
    @Test
    public void selectbyid(){
        List<User> users=userMapper.selectbyid(2);
        for(User user:users)
        {
            System.out.println(user);
            System.out.println();
        }
    }

    @Test
    public void updatebyid(){
        int i=userMapper.updatebyid();
        if(i>0)
        {
            System.out.println("successfully"+"\n");
        }
        else
        {
            System.out.println("fail");
        }
    }
    @Test
    public void updatebyname()
    {
        int index=userMapper.updatebyname("王祖荣","无");
        if(index>=0)
        {
            System.out.println("成功修改"+index+"条数据");
        }
        else {
            System.out.println("fail to update");
        }
    }
    @Test
    public void insertUser()
    {
        int y=userMapper.insertUser(8);
        if(y>=0)
        {
            System.out.println("successfully to insert");
        }
        else
        {
            System.out.println("fail to insert");
        }
    }
    @Test
    public void delete()
    {
        int y=userMapper.deleteUserById(8);
        if(y>=0)
        {
            System.out.println("successfully to delete");
        }
        else
        {
            System.out.println("fail to delete");
        }

    }




}

运行下来相当的哇塞,不出意外的化是不会有bug的,当然如果有意外,那就要着重检查注释,配置文件这些。

 以上就是在test类下测试的全部内容了


 然而,在实际的项目中,我们更希望可以把这些玩意放到端口上去,这里不得不推荐一款国产的免费端口调试工具Apipost6,用着比较舒服,个人认为比Postman好用得多,好了,下面进入正文。


 

2:在实体类中进行增删改查操作

前言:

说实话我在模仿这个玩意的时候是比较崩溃的,但好在结果是好的,收获颇多。

首先来看一下我用来操作原数据表和本次的结构目录

 还是老话,啥都不知道的按照这个照搬就ok了,一点点弄过来自然就会了。

A:  关于.properties文件的配置:

server.port= 8080

spring.datasource.url= jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=passwd
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

mybatis.type-aliases-package=com.example.simple3.entity
mybatis.mapper-locations= classpath:mappers/*.xml
mybatis.configuration.call-setters-on-nulls=true
mybatis.configuration.map-underscore-to-camel-case=true

注意事项参考上文

B:关于pom.xml文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>simple3</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>simple3</name>
    <description>simple3</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>


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

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

注意事项参考上文

C:entity层下的 User.java

package com.example.simple3.entity;

public class User {
    private int id;
    private String name;
    private String sex;
    private int age;
    public void setid(int id)
    {
        this.id=id;
    }
    public int getid()
    {
        return id;
    }
    public void setname(String name)
    {
        this.name=name;
    }
    public String getname()
    {
        return name;
    }

    public void setsex(String sex)
    {
        this.sex=sex;
    }
    public String getsex()
    {
        return sex;
    }

    public void setage(int age)
    {
        this.age=age;
    }
    public int getage()
    {
        return age;
    }

}

有一点很重要,就是你设置的这些变量都有有配备的set和get方法,我当时就是不理解这个有什么用处,觉得没有就没写,而后也是一个一直报错的点,这里涉及到了底层代码的设计了,具体不解释了,知道有这么回事就OK 了

D:Dao层下的UserDao.java,——提供与数据库对应的方法的接口

package com.example.simple3.dao;

import com.example.simple3.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
@Mapper
public interface UserDao {
    public List<User> findAllUser();
    public User findUserById(int id);
    public boolean updateUserById(User user);
    public boolean insertUser(User user);
    public boolean deleteById(int id);
}

除了一个注释倒是没有什么要注意的地方。

E:service层——提供在实体类里实现操作的接口类和方法。

Userservice.java接口:

  你可能会觉得这些方法好眼熟啊,不是在在Dao层里出现过吗,其实他们除了名字类似,实际上是没有啥太大关系的,如果非要扯上关系,就是实例化的时候会调用Dao 层里面的方法。

package com.example.simple3.service;

import com.example.simple3.entity.User;

import java.util.List;

public interface UserService
{
    public List<User> getUsers();
    public User findUserById(int id);
    public boolean updateUserById(User user);
    public boolean insertUser(User user);
    public boolean deleteById(int id);
}

UserSeriveImpl.java实例化类

package com.example.simple3.service.impl;

import com.example.simple3.dao.UserDao;
import com.example.simple3.entity.User;
import com.example.simple3.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class UserServiceImpl implements UserService
{
    @Autowired
    private UserDao userDao;
    @Override
    public List<User> getUsers()
    {// TODO Auto-generated method stub
        return userDao.findAllUser();
    }

    @Override
    public User findUserById(int id) {
        return userDao.findUserById(id);
    }
    @Override
    public boolean updateUserById(User user) {
        // TODO Auto-generated method stub
        userDao.updateUserById(user);
        return true;
    }

    public boolean insertUser(User user) {
        // TODO Auto-generated method stub
        userDao.insertUser(user);
        return true;
    }
    @Override
    public boolean deleteById(int id) {
        // TODO Auto-generated method stub
        userDao.deleteById(id);
        return true;
    }



}

F:resource目录下的Usermapper.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.example.simple3.dao.UserDao">
    <!--查询表中所有元素-->
    <select id="findAllUser" resultType="User">
        select id,name,sex,age from user
    </select>

    <select id="findUserById" resultType="User">
        select name,sex,age from user where id = #{id}
    </select>

    <update id="updateUserById" parameterType="User">
        update user set name = #{name},sex=#{sex},age=#{age} where id = #{id}
    </update>

    <insert id="insertUser" parameterType="User">
        insert into user(id,name,sex,age) values (#{id},#{name},#{sex},#{id})
    </insert>
    <delete id="deleteById" parameterType="java.lang.Integer">
        delete from user where id = #{id}
    </delete>

</mapper>

注意事项参考上文

G:最后最重要的来了,controller层下的UserController.java

package com.example.simple3.controller;

import com.example.simple3.entity.User;
import com.example.simple3.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@RestController
@RequestMapping("/user")
@ResponseBody
public class UserController
{
    @Autowired
    private UserService userService;

    @RequestMapping("/getUser")
    @ResponseBody
    public List<User> getUsers(){
        return userService.getUsers();
    }

    @RequestMapping("/getUserOne")
    public User getUserOne(HttpServletRequest request) {
        int id = Integer.parseInt(request.getParameter("id"));
        return userService.findUserById(id);
    }
    @RequestMapping("/updateUser")
    public  List<User> updateUser(HttpServletRequest request) {
        String name = request.getParameter("name");
        String sex = request.getParameter("sex");
        int age = Integer.parseInt(request.getParameter("age"));
        int id = Integer.parseInt(request.getParameter("id"));
        User user = new User();
        user.setname(name);
        user.setsex(sex);
        user.setage(age);
        user.setid(id);
        userService.updateUserById(user);//更新
        return userService.getUsers();//查看
    }

    @RequestMapping("/addUser")
    public List<User> addUser(HttpServletRequest request) {
        String name = request.getParameter("name");
        String sex = request.getParameter("sex");
        int age = Integer.parseInt(request.getParameter("age"));
        int id = Integer.parseInt(request.getParameter("id"));
        User user = new User();
        user.setname(name);
        user.setsex(sex);
        user.setage(age);
        user.setid(id);
        userService.insertUser(user);
        return userService.getUsers();//查看
    }
    @RequestMapping("/deleteUser")
    public List<User> deleteUser(HttpServletRequest request) {
        int id = Integer.parseInt(request.getParameter("id"));
        userService.deleteById(id);
        return userService.getUsers();//查看
    }
}

这里对于初次上手的人来说,会遇到一个相当棘手的问题,那就是一个报null的异常,至于如何解决,也十分简单,就是直接在测试的url后面加上要传入的参数的值,传参的个数和数据库里的#{}相互对应,下面进行演示。

1:查询操作

由于形参是空,所以直接访问端口就好:

 可以看到这里的信息和我之前展示的数据表完全一致

2:改操作

与上图对比,id为8的user信息被修改

3:查操作

 查找到了id为3的用户

4:插入操作

 插入了一个id为99的用户信息

5:删除操作

 删除了一个id为99的用户信息


以上就是整个流程了,整理之前其实还有许多没想通的地方,整理之后思路总算是豁然开朗,为了避免睡一觉后什么都忘记,就趁热打铁整理出来吧


 整体结构之间的内在关系(个人理解版)

 

至此,总算是可以圆满入门了,头大呀

;