首页 开发技术Java正文

【Spring Boot】4. 整合MyBatis(TK.Mybatis)

拾年之璐 Java 2020-08-22 22:08:01 132 0

Java

Spring Boot

0、配置前:

直接创建一个Spring Boot项目即可。

详情可参考上一篇文章。

1、整合Druid

1.1 关于Druid

Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成。该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,程序员可以通过定制来实现自己需要的功能。

Druid 是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括 DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid 已经在阿里巴巴部署了超过 600 个应用,经过多年生产环境大规模部署的严苛考验。Druid 是阿里巴巴开发的号称为监控而生的数据库连接池!

1.2 引入依赖

首先在pom.xml文件中引入druid-spring-boot-starter依赖:

        <!--druid依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

然后引入数据库连接依赖:

        <!--数据库连接依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

1.3 配置application

application.properties修改为application.yml,然后在其中配置数据库连接信息:

spring:
  datasource:
    druid:
      url: jdbc:mysql://127.0.0.1:3306/yourdb?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
      initial-size: 1
      min-idle: 1
      max-active: 20
      test-on-borrow: true
      # MySQL 8.x: com.mysql.cj.jdbc.Driver
      # MySQL 5.x: com.mysql.jdbc.Driver
      driver-class-namecom.mysql.cj.jdbc.Driver

这里需要注意,如果是MySQL8.X,连接URL中需要追加:serverTimezone=UTC 来设置时区,否则报错;

同时,不同数据库版本,连接类名driver-class-name也不同,均在上述源码中体现。

2、整合tk.mybatis

2.1 关于tk.mybatis

tk.mybatis 是在 MyBatis 框架的基础上提供了很多工具,让开发更加高效。通俗讲,是MyBatis的增强版,其帮你实现了众多SQL语句,让你远离SQL。

2.2 引入依赖

        <!--tk.mybatis 是在 MyBatis 框架的基础上提供了很多工具,让开发更加高效-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>

2.3 配置application

application.yml中追加以下内容:

mybatis:
  type-aliases-packagecom.cxhit.hello.spring.boot.mybatis.entity #实体类的存放路径,如:com.funtl.hello.spring.boot.entity
  mapper-locationsclasspath:mapper/*.xml #生成的xml文件放置路径(resources下)

其中第一个type-aliases-package,就是存放实体类的路径

一般是:com.yourdomain.yourprojectpackage.entity 或yom.yourdomain.yourprojectpackage.bean

第二个mapper-locations,就是生成的Mapper文件存放的路径,一般在resources下的mapper文件夹中。

以上两个文件均不需要手动添加!!!

2.4 创建一个通用的父级接口

该接口的主要作用是让 DAO 层的接口继承该接口,以达到使用 tk.mybatis 的目的。

这里注意:这个接口不能被扫描到,即不能和Main函数在相同的包(以及子包)中。

(这是因为约定大于配置的原因,使得Spring默认扫描路径为Application所在包及其子包

可以在src/main/java下新建:tk.mybatis包,将MyMapper.java放置其中。

直接右击java→new→file,输入:tk.mybatis.MyMapper.java ,回车,即可。

该接口源码如下:

package tk.mybatis;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * 创建一个通用的父级接口
 * 主要作用是让 DAO 层的接口继承该接口,以达到使用 tk.mybatis 的目的
 */


/**
 * 自己的 Mapper
 * 特别注意,该接口不能被扫描到,否则会出错
 * 【约定大于配置:Spring 默认扫描路径为Application所在包,即com.cxhit.hello.spring.boot.mybatis】
 * <p>Title: MyMapper</p>
 * <p>Description: </p>
 *
 */

public interface MyMapper<Textends Mapper<T>, MySqlMapper<T> {
}

3、整合PageHelper

3.1 关于PageHelper

PageHelper 是 Mybatis 的分页插件,支持多数据库、多数据源。可以简化数据库的分页查询操作,整合过程也极其简单,只需引入依赖即可。

3.2 注入依赖

在 pom.xml 文件中引入 pagehelper-spring-boot-starter 依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>

4、【关键】使用MyBatis的Maven插件生成代码

我们无需手动编写 实体类、DAO、XML 配置文件,只需要使用 MyBatis 提供的一个 Maven 插件就可以自动生成所需的各种文件便能够满足基本的业务需求,如果业务比较复杂只需要修改相关文件即可。

4.1 配置插件

首先在pom.xml文件中的 …… 中添加 mybatis-generator-maven-plugin 插件

具体源码如下:

            <!--增加 mybatis-generator-maven-plugin 插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
                <configuration>

                    <!--TODO 下面这个generator/generatorConfig.xml 需要自己创建-->
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>

                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>3.4.4</version>
                    </dependency>
                </dependencies>
            </plugin>

如上TODO位置处,需要自行创建/src/main/resources/generator/generatorConfig.xml 文件。

4.2 配置generatorConfig.xml文件

如上创建generatorConfig.xml文件后,在其中写入如下代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">


<generatorConfiguration>
    <!-- 引入数据库连接配置  -->

    <!--TODO 自己创建jdbc.properties(resources下)-->
    <properties resource="jdbc.properties"/>

    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <!-- 配置 tk.mybatis 插件 -->
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">

            <!--TODO 下面这个路径也需要修改-->
            <property name="mappers" value="tk.mybatis.MyMapper"/>
        </plugin>

        <!-- 配置数据库连接 -->
        <jdbcConnection
                driverClass="${jdbc.driverClass}"
                connectionURL="${jdbc.connectionURL}"
                userId="${jdbc.username}"
                password="${jdbc.password}">

            <!--<property name="nullCatalogMeansCurrent" value="true"></property>-->
        </jdbcConnection>

        <!-- 配置实体类存放路径 TODO 修改为自己的包路径 -->
        <javaModelGenerator targetPackage="com.cxhit.hello.spring.boot.mybatis.entity" targetProject="src/main/java"/>

        <!-- 配置 XML 存放路径 TODO 基本不用动 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>

        <!-- 配置 DAO 存放路径 TODO 修改为自己的包路径 -->
        <javaClientGenerator
                targetPackage="com.cxhit.hello.spring.boot.mybatis.dao"
                targetProject="src/main/java"
                type="XMLMAPPER"/>


        <!-- TODO 配置需要指定生成的数据库和表,% 代表所有表 -->
        <table catalog="mz_book_v2" tableName="%">
            <!-- mysql 配置 -->
            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

如上,第一处 TODO 位置,需要在resources文件夹下创建jdbc.properties 文件;

如上,第二处 TODO 位置,需要修改为自己项目中的MyMapper通用父级接口的位置,即2.4位置处所讲述的接口文件;

如上,第三个 TODO 位置,需要修改为自己的实体类包entity(部分习惯用Bean)计划保存路径(无需手动创建,自动生成);

如上,第四个 TODO 位置,基本不需要修改;

如上,第五个 TODO 位置,需要修改为自己的DAO计划保存路径(无需手动创建,系统自动生成);

如上,第六个 TODO 位置,修改为自己的数据库名称。

4.3 配置数据源

在 src/main/resources 下创建 jdbc.properties(对应上文第一处 TODO )

jdbc.properties中源码如下:

# MySQL 5.x: com.mysql.jdbc.Driver
# MySQL 8.x: com.mysql.cj.jdbc.Driver
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://127.0.0.1:3306/mz_book_v2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

至此,项目基本上配置完毕,初始状态如下所示:

4.4 执行自动生成命令

打开 idea 页面侧边栏(最右边)的 Maven Projects ,找到 Plugins/mybatis-generator ,双击 mybatis-generator:genetage ,即可自动完成entity、DAO、Mapper的代码生成。

双击打开任意一个entity,如本项目中的book实体,即可看到所有的属性均已经定义完毕。

注意:这里需要将所有实体的 @Table(name = "mz_book_v2..book") 中的数据库名字加多余的两个点删除

如上,修改为:

因为MySQL不支持Catalog 。详见:https://blog.csdn.net/ddfdjffd/article/details/90712080

如果不修改,则自动执行的SQL语句为:

报错。

5、测试MyBatis操作数据库

这里使用的数据库是一个书籍的数据库,两个表,一个表是图书分类表,另一个是书籍详情表。可以使用任意数据库测试。

5.1 修改入口类

需要使用 @MapperScan 注解来指定 Mapper 接口的路径

PS: 注意这里的 @MapperScan 注解是 **tk.mybatis.spring.annotation.MapperScan**; 包下的,如下所示:

5.2 创建测试类:

在 test 文件夹下的 HelloSpringBootMybatisApplicationTests 类中创建测试类,进行测试即可。

如下是测试 select 和 分页查询 的源码,以及运行结果:

package com.cxhit.hello.spring.boot.mybatis;

import com.cxhit.hello.spring.boot.mybatis.dao.BookMapper;
import com.cxhit.hello.spring.boot.mybatis.dao.CategoryMapper;
import com.cxhit.hello.spring.boot.mybatis.entity.Book;
import com.cxhit.hello.spring.boot.mybatis.entity.Category;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = HelloSpringBootMybatisApplication.class)
@Transactional
@Rollback
public class HelloSpringBootMybatisApplicationTests {

    /**
     * 注入数据查询接口
     */

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 注入数据查询接口
     */

    @Autowired
    private BookMapper bookMapper;

    @Test
    public void testSelect() {
        List<Category> categories = categoryMapper.selectAll();

        for (Category category : categories) {
            System.out.println(category.getCatName());
        }

    }

    @Test
    public void testPage() {

        PageHelper.startPage(220);
        Example example = new Example(Book.class);
        PageInfo<Book> pageInfo = new PageInfo<>(bookMapper.selectByExample(example));
        List<Book> list = pageInfo.getList();
        for (Book book : list) {
            System.out.println(book.getBookName());
        }

    }

}

测试 select 运行结果:

测试 分页查询 运行结果:

6、附录:完整源码(从上到下)

src/main/java/com.cxhit.hello.spring.boot.mybatis.HelloSpringBootMybatisApplication.java

package com.cxhit.hello.spring.boot.mybatis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan(basePackages = "com.cxhit.hello.spring.boot.mybatis.dao")
public class HelloSpringBootMybatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloSpringBootMybatisApplication.class, args);
    }

}

tk.mybatis.MyMapper.java

package tk.mybatis;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * 创建一个通用的父级接口
 * 主要作用是让 DAO 层的接口继承该接口,以达到使用 tk.mybatis 的目的
 */


/**
 * 自己的 Mapper
 * 特别注意,该接口不能被扫描到,否则会出错
 * 【约定大于配置:Spring 默认扫描路径为Application所在包,即com.cxhit.hello.spring.boot.mybatis】
 */

public interface MyMapper<Textends Mapper<T>, MySqlMapper<T> {
}

resources.generator.generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">


<generatorConfiguration>
    <!-- 引入数据库连接配置  -->

    <!--TODO 自己创建jdbc.properties(resources下)-->
    <properties resource="jdbc.properties"/>

    <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <!-- 配置 tk.mybatis 插件 -->
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">

            <!--TODO 下面这个路径也需要修改-->
            <property name="mappers" value="tk.mybatis.MyMapper"/>
        </plugin>

        <!-- 配置数据库连接 -->
        <jdbcConnection
                driverClass="${jdbc.driverClass}"
                connectionURL="${jdbc.connectionURL}"
                userId="${jdbc.username}"
                password="${jdbc.password}">

            <!--<property name="nullCatalogMeansCurrent" value="true"></property>-->
        </jdbcConnection>

        <!-- 配置实体类存放路径 TODO 修改为自己的包路径 -->
        <javaModelGenerator targetPackage="com.cxhit.hello.spring.boot.mybatis.entity" targetProject="src/main/java"/>

        <!-- 配置 XML 存放路径 TODO 基本不用动 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>

        <!-- 配置 DAO 存放路径 TODO 修改为自己的包路径 -->
        <javaClientGenerator
                targetPackage="com.cxhit.hello.spring.boot.mybatis.dao"
                targetProject="src/main/java"
                type="XMLMAPPER"/>


        <!-- 配置需要指定生成的数据库和表,% 代表所有表 -->
        <table catalog="mz_book_v2" tableName="%">
            <!--取消catelog   MySQL不支持-->
            <!--<property name="ignoreQualifiersAtRunTIme" value="true"></property>-->
            <!-- mysql 配置 -->
            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

resources.application.yml

spring:
  datasource:
    druid:
      url: jdbc:mysql://127.0.0.1:3306/mz_book_v2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root
      password: 123456
      initial-size: 1
      min-idle: 1
      max-active: 20
      test-on-borrow: true
      # MySQL 8.x: com.mysql.cj.jdbc.Driver
      # MySQL 5.x: com.mysql.jdbc.Driver
      driver-class-namecom.mysql.cj.jdbc.Driver

mybatis:
  type-aliases-package: com.cxhit.hello.spring.boot.mybatis.entity #实体类的存放路径,如:com.funtl.hello.spring.boot.entity
  mapper-locations: classpath:mapper/*.xml #生成的xml文件放置路径(resources下)

resources.jdbc.properties

# MySQL 8.x: com.mysql.cj.jdbc.Driver
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://127.0.0.1:3306/mz_book_v2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

src/main/java/com.cxhit.hello.spring.boot.mybatis.HelloSpringBootMybatisApplicationTests.java

package com.cxhit.hello.spring.boot.mybatis;

import com.cxhit.hello.spring.boot.mybatis.dao.BookMapper;
import com.cxhit.hello.spring.boot.mybatis.dao.CategoryMapper;
import com.cxhit.hello.spring.boot.mybatis.entity.Book;
import com.cxhit.hello.spring.boot.mybatis.entity.Category;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = HelloSpringBootMybatisApplication.class)
@Transactional
@Rollback
public class HelloSpringBootMybatisApplicationTests {

    /**
     * 注入数据查询接口
     */

    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 注入数据查询接口
     */

    @Autowired
    private BookMapper bookMapper;

    @Test
    public void testSelect() {
        List<Category> categories = categoryMapper.selectAll();

        for (Category category : categories) {
            System.out.println(category.getCatName());
        }

    }

    @Test
    public void testPage() {

        PageHelper.startPage(25);
        Example example = new Example(Book.class);
        PageInfo<Book> pageInfo = new PageInfo<>(bookMapper.selectByExample(example));
        List<Book> list = pageInfo.getList();
        for (Book book : list) {
            System.out.println(book.getBookName());
        }
    }

}

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.1.13.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cxhit</groupId>
    <artifactId>hello-spring-boot-mybatis</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>hello-spring-boot-mybatis</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <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>

        <!--druid依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!--数据库连接依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--tk.mybatis 是在 MyBatis 框架的基础上提供了很多工具,让开发更加高效-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.0.2</version>
        </dependency>

        <!--PageHelper 是 Mybatis 的分页插件,支持多数据库、多数据源。可以简化数据库的分页查询操作,整合过程也极其简单,只需引入依赖即可。-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

    </dependencies>


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

            <!--增加 mybatis-generator-maven-plugin 插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
                <configuration>

                    <!--TODO 下面这个generator/generatorConfig.xml 需要自己创建-->
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>

                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>${mysql.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>3.4.4</version>
                    </dependency>
                </dependencies>
            </plugin>

        </plugins>
    </build>

</project>

7、补充:

如果测试类中创建的接口有红色下划线(波浪线),如下图所示:

只需要将 DAO 接口加上注解 @Repository 即可。

该文件为系统自动生成,默认是没有该注解的。


声明:本文由作者原创发布,转载请联系原作者。

评论

关于我们
这里是网站的说明
关注本站微信号,享受更多服务!
联系方式
电话:159******00
地址:武汉市武昌区
Email:cxh@cxh.work
邮编:430000
Copyright ©2019-2020.Powered by©Z-BlogPHP&拾年之璐  鲁ICP备18018164号