springboot整合mybatis查询mysql数据库教程

作者: ʘᴗʘ发布时间:2021-09-26 21:40 浏览量:496 点赞:396 售价:0
springboot整合mybatis查询mysql数据库教程
传统的Springboot教程大多是各种理论、概念的集合,新手在学习的时候往往理解吃力、容易遗忘。本教程是作者结合自己多年工作经验,通过一些常见的小项目,深入浅出的讲解Springboot的各个知识点,能够帮助初学者快速掌握Springboot。每个案例都有完整可运行的源码,可直接下载运行。
文章:5篇

前言

前面的文章中,我们创建了第一个基于thymeleaf模板引擎的网页,但是网页内并没有太多数据。本文,我们将介绍如何通过mybatis从mysql数据库中读取数据,包括简单的selectupdatedeleteinsert,也有复杂的各种多表关联查询(一对一、一对多关联等)。如果你还没有安装好mysql,可以参考我们mysql安装的相关博文。

Maven引入相关jar包

引入Mybatis

第一步当然要通过maven的pom文件引入mybatis,代码如下:

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

mybatis只是一个SQL层面的持久层框架,作用只是根据你的代码来生成SQL执行、返回结果。为了完成完整的数据库访问,我们还需要引入mysql-connector-java等完成数据库连接的新建、管理工作。

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

查询数据库的时候,难免有分页查询的需求,这时候pagehelper非常好用。

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>
引入lombok

数据库操作的时候,难免会有很多POJO类,然后类里的属性自然就会有很多get、set方法、构造方法、toString方法等等,重复劳作很累。所以引入lombok可以有效缓解这种情况。

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
完整pom文件代码
<?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.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.coderbbb</groupId>
    <artifactId>book-1</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>book-1</name>
    <description>book-1</description>
    <properties>
        <java.version>11</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-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>

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

配置mybatis和数据库连接信息

配置mybatis

接下来我们需要简单配置一下mybatis,在springboot的resources文件夹下,有application.properties配置文件,在里面添加如下Mybatis配置项:

  • mybatis.configuration.map-underscore-to-camel-case=true启用mybatis的驼峰法变量名映射。举个例子,springboot中我们有一个user类,里面有名为userAge的属性。然后在数据库中,我们存储的对应字段名为user_age。启用这个配置后,当我们查询数据,mybatis能够自动把user_ageuserAge对应起来。
  • mybatis.type-aliases-package=com.tec666.coderbbb.database.dos配置springboot中你存储数据实体POJO类的包路径。比如我们的springboot项目中,有user这个POJO类,用来定义用户的各种数据属性。类似的各种POJO统一放在一个包里面,把包路径配置给mybatis。主要作用就是,当mybatis查询出数据后,需要从这个路径下面找到对应POJO类,把mysql数据转为对应POJO类返回给我们。
  • mybatis.mapper-locations=classpath:mapper/*.xml配置mybatis的xml sql文件存放地址。通常情况下,简单的SQL我们一般以注解的形式写在mapper接口中。但是,一些比较复杂的查询SQL,比如join、in等查询,尤其是需要SQL动态拼接的查询,我们需要写在xml文件中。
配置数据库连接信息

数据库连接配置,也是配置在application.properties中。主要是配置数据库连接地址、数据库用户名、密码等。代码如下:

  • spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver顾名思义,就是配置driver-class,这个通常一直是这个配置项。只有当你改变mysql版本、多种数据源等场景时,才需要关注这个值。
  • spring.datasource.url=jdbc:mysql://localhost:3306/lesson?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false数据库连接地址,请重点关注连接地址?之后的内容。serverTimezone是时区,当你数据库中保存时间戳等时间时,有时候会发现数据库中存的时间和查询出来的不一样,通常都是时区问题造成的。autoReconnect这个是自动重连,建议配置上。useSSL代表是否使用SSL来加密连接,看你的需求。通常使用SSL加密会对性能有一些影响。
  • spring.datasource.username=zhang_san数据库用户名
  • spring.datasource.password=你的密码数据库密码
完整application.properties文件代码
server.port=8080

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/lesson?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=你的密码

mybatis.configuration.map-underscore-to-camel-case=true
mybatis.type-aliases-package=com.coderbbb.book1.database.dos
mybatis.mapper-locations=classpath:mapper/*.xml

创建POJO对象和Mysql数据表

为了演示查询,我们一共新建三个POJO对象:UserDOCarDOWifeDO。我们规定:一个user可以有多辆car,但是只能有一个wife。所以,user和car是一对多的关系,user和wife是一对一的关系。主键的话,user和wife使用bigint自增,car使用UUID生成36位字符串(为了演示,实际工作中,表的主键选择需要多种因素综合考量)。

我们在mybatis.type-aliases-package=com.coderbbb.book1.database.dos这个配置项配置的路径下,新建这个三个POJO类,代码如下:

UserDO代码
package com.coderbbb.book1.database.dos;

import lombok.Data;

@Data
public class UserDO implements Serializable {

    /**
     * 主键ID
     */
    private Long id;

    /**
     * 用户名
     */
    private String username;
  
}
CarDO代码
package com.coderbbb.book1.database.dos;

import lombok.Data;

import java.io.Serializable;

@Data
public class CarDO implements Serializable {

    /**
     * 车辆表主键
     */
    private String uuid;

    /**
     * 车辆所属用户
     */
    private Long user;

    /**
     * 车辆名称:宝马、奔驰、奥迪、雅迪~
     */
    private String name;
}
WifeDO代码
package com.coderbbb.book1.database.dos;

import lombok.Data;

import java.io.Serializable;

@Data
public class WifeDO implements Serializable {

    /**
     * 主键ID
     */
    private Long id;

    /**
     * 所属user的ID,简称:她老公
     */
    private Long user;

    /**
     * 用户名
     */
    private String username;

}
建表语句

这个没啥难度,代码如下:

UserDO对应的user表:

CREATE TABLE if not exists `user`
(
    `id`       bigint      NOT NULL auto_increment,
    `username` varchar(20) not null default '',
    PRIMARY KEY (`id`),
    KEY `idx_username` (`username`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci COMMENT ='user表';

CarDO对应的car表:

CREATE TABLE if not exists `car`
(
    `uuid` char(36)    NOT NULL,
    `user` bigint      not null,
    `name` varchar(20) not null default '',
    PRIMARY KEY (`uuid`),
    KEY `idx_name` (`name`),
    KEY `idx_user` (`user`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci COMMENT ='car表';

WifeDO对应的wife表:

CREATE TABLE if not exists `wife`
(
    `id`       bigint      NOT NULL auto_increment,
    `user`     bigint      not null,
    `username` varchar(20) not null default '',
    PRIMARY KEY (`id`),
    KEY `idx_username` (`username`),
    KEY `idx_user` (`user`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci COMMENT ='wife表';

创建Mybatis Mapper和XML构建查询

创建Mapper,使用注解形式查询

通常简单的查询,我们可以直接使用注解的方式,快速构建SQL。首先我们新建三个Mapper的interface类:UserMapperCarMapperWifeMapper,代码如下:

package com.coderbbb.book1.database.mapper;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface UserMapper {


}

上面是UserMapper,其他类似。接下来我们在UserMapper里添加一个SQL插入语句,来给Mysql数据库插入一行记录。完整代码如下:

package com.coderbbb.book1.database.mapper;

import com.coderbbb.book1.database.dos.UserDO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface UserMapper {


    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into user (username) values(#{d.username})")
    int add(@Param("d") UserDO userDO);

}

上面的代码中,@Options(useGeneratedKeys = true, keyProperty = "id")的意思是使用自增的long类型主键,名称是id。三张表里,UserWife使用的都是自增主键,Car使用的是UUID字符串主键。所以car的插入语句不需要配置这个。但是要在构造CarDO的时候,给uuid属性赋值(可以参考文章末尾,初始化数据的代码)。@Insert代表括号中的是insert插入语句。其他还有@Select@Delete@Update等,分别对应Mysql的selectdeleteupdate语句。

接下来,我们只要在springboot的controller或者service中,注入这个Mapper,然后调用对应的方法,即可完成对应的SQL操作。比如我们要插入一个User用户,使用如下代码即可。这里有一个常见问题,就是插入后,我们如何在当前方法获取到该记录在数据库中的主键?下方我们使用UserDO插入后,调用UserDOgetId()方法,你会发现Mybatis已经自动把自增的ID值填入其中了。

package com.coderbbb.book1;

import com.coderbbb.book1.database.dos.UserDO;
import com.coderbbb.book1.database.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MybatisController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping(value = "/mybatis/add", method = RequestMethod.GET)
    public String add() {

        UserDO userDO = new UserDO();
        userDO.setUsername("张三");

        if (userMapper.add(userDO) == 1) {
            return "插入成功";
        }
        return "插入失败";

    }
}
Mybatis通过XML完成一对一、一对多关联查询

注解形式的SQL查询,适合比较简单的SQL。如果比较复杂的场景,比如一对一、一对多等,使用mybatis的xml查询方式更为方便。

首先,我们构建一个名为UserDTO的POJO类,里面包含了这个user的car和wife。UserDTO这个类继承了UserDO,在UserDO的基础上增加了和它相关的car、wife等数据。代码如下:

package com.coderbbb.book1.database.dto;

import com.coderbbb.book1.database.dos.CarDO;
import com.coderbbb.book1.database.dos.UserDO;
import com.coderbbb.book1.database.dos.WifeDO;
import lombok.Data;

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

@Data
public class UserDTO extends UserDO implements Serializable {

    /**
     * 一个User有多辆车
     */
    private List<CarDO> cars;

    /**
     * 一个用户有一个wife
     */
    private WifeDO wifeDO;

}

然后,我们在前文application.properties中配置的mybatis xml路径中,新建名为UserMapper.xml的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.coderbbb.book1.database.mapper.UserMapper">

  

</mapper>

其中,namespace中的路径,是对应到UserMapper.java这个文件的。相当于在UserMapper.java中定义SQL操作的方法,然后在对应的xml中写具体的SQL代码。

我们在UserMapper.java中写一个select方法,代码如下:

package com.coderbbb.book1.database.mapper;

import com.coderbbb.book1.database.dos.UserDO;
import com.coderbbb.book1.database.dto.UserDTO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface UserMapper {


    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into user (username) values(#{d.username})")
    int add(@Param("d") UserDO userDO);

  
    List<UserDTO> selectAll();
  
}

上面的代码中,List<UserDTO> selectAll();这个方法,并没有使用@Select注解写SQL,我们要把SQL写到对应的XML中。

  1. 首先,因为UserDTO这个POJO类无法直接和数据库中的表直接对应,所以我们要在xml文件中填写一下POJO类的字段和数据表中的字段,是如何对应的。
  2. 然后,我们要在xml中写好本次多张表联合查询的SQL。

完整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.coderbbb.book1.database.mapper.UserMapper">


    <resultMap type="com.coderbbb.book1.database.dto.UserDTO" id="baseResultMap">

        <result property="id" column="id" />
        <result property="username" column="username" />

        <!--一对一-->
        <association property="wifeDO" javaType="com.coderbbb.book1.database.dos.WifeDO">
            <result column="wife_id" property="id"/>
            <result column="wife_username" property="username"/>
        </association>

        <!--一对多-->
        <collection property="cars" ofType="com.coderbbb.book1.database.dos.CarDO" column="user">

            <result column="car_uuid" property="uuid"/>
            <result column="car_name" property="name"/>

        </collection>

    </resultMap>

    <select id="selectAll" resultMap="baseResultMap">

        select u.*,w.id as wife_id,w.username as wife_username,c.uuid as car_uuid,c.name as car_name
        from user u,wife w,car c
        where u.id=w.user and u.id = c.user

    </select>
</mapper>

然后我们在controller中调用Mapper中的selectAll方法,来试试能否查询成功。代码如下:

/**
* 查询方法
* @return
*/
@RequestMapping(value = "/mybatis/select", method = RequestMethod.GET)
public List<UserDTO> select() {
    List<UserDTO> data = userMapper.selectAll();
    return data;
}

请求该controller的select方法后,返回的结果JSON如下:

[
  {
    "id": 1,
    "username": "张三",
    "cars": [
      {
        "uuid": "007df3c8-6fd3-4543-a689-450da2b19c3b",
        "user": null,
        "name": "小奔驰"
      },
      {
        "uuid": "2482485a-a69b-4ce1-a016-4692a1ddd93b",
        "user": null,
        "name": "大宝马"
      }
    ],
    "wifeDO": {
      "id": 1,
      "user": null,
      "username": "豆腐西施"
    }
  }
]

和我们预期的结构是完全一致的,查询成功!

附上Controller的完整代码,主要是有插入初始数据的代码,直接复制,省得你自己写。

package com.coderbbb.book1;

import com.coderbbb.book1.database.dos.CarDO;
import com.coderbbb.book1.database.dos.UserDO;
import com.coderbbb.book1.database.dos.WifeDO;
import com.coderbbb.book1.database.dto.UserDTO;
import com.coderbbb.book1.database.mapper.CarMapper;
import com.coderbbb.book1.database.mapper.UserMapper;
import com.coderbbb.book1.database.mapper.WifeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
public class MybatisController {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WifeMapper wifeMapper;
    @Autowired
    private CarMapper carMapper;

    @RequestMapping(value = "/mybatis/add", method = RequestMethod.GET)
    public String add() {

        UserDO userDO = new UserDO();
        userDO.setUsername("张三");

        if (userMapper.add(userDO) != 1) {
            return "插入user失败";
        }

        CarDO carDO = new CarDO();
        carDO.setName("大宝马");
        carDO.setUser(userDO.getId());
        carDO.setUuid(UUID.randomUUID().toString());

        if(carMapper.add(carDO)!=1){
            return "插入car失败";
        }
        carDO = new CarDO();
        carDO.setName("小奔驰");
        carDO.setUser(userDO.getId());
        carDO.setUuid(UUID.randomUUID().toString());

        if(carMapper.add(carDO)!=1){
            return "插入car失败";
        }

        WifeDO wifeDO = new WifeDO();
        wifeDO.setUser(userDO.getId());
        wifeDO.setUsername("豆腐西施");

        if(wifeMapper.add(wifeDO)!=1){
            return "插入wife失败";
        }

        return "插入成功";

    }

    /**
     * 查询方法
     * @return
     */
    @RequestMapping(value = "/mybatis/select", method = RequestMethod.GET)
    public List<UserDTO> select() {
        List<UserDTO> data = userMapper.selectAll();
        return data;
    }
}

版权声明:《springboot整合mybatis查询mysql数据库教程》为CoderBBB作者「ʘᴗʘ」的原创文章,转载请附上原文出处链接及本声明。

原文链接:https://www.coderbbb.com/articles/13

其它推荐: