(最终版)Spring Boot集成Mybatis

Posted 谈技术有态度

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(最终版)Spring Boot集成Mybatis相关的知识,希望对你有一定的参考价值。


 本文主要讲述如何在Spring Boot框架中集成Mybatis框架,说明主要的关键配置点,并且通过注释向大家介绍各个配置项的作用。


话不多说,我们直接进入正题:


使用的软件环境及版本:

  • eclipse 4.6.3

  • JDK 1.8

  • Maven 3.3.3

  • Spring Boot 2.1.1.RELEASE

项目结构

首先是项目结构:

  • 构建工具maven的配置文件:pom.xml

  • Spring boot的配置文件application.properties

  • logback的配置文件logback.xml

  • mybatis的配置文件mybatis-config.xml

  • Spring Boot的启动类Main.java

  • 其余逻辑代码文件src/main/java/...

Maven 配置

本文使用spring-boot-starter-parent为父框架,配置该paren后,对应的常用依赖都会被该parent预设version,省去了逐个引入的工作量,统一控制spring boot相关组件的版本为2.1.1.RELEASE。


使用的starter为spring-boot-starter-web,后续会有文章来介绍spring boot提供的starter都有哪些,分别作用是什么。本文中的starter使用spring-boot-starter-web,可以用来开发包括restful风格的接口工程在内的web工程,使用内置的tomcat作为web容器。


pom.xml文件的配置如下:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xiaot.spring</groupId>
    <artifactId>SpringBoot</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>SpringBoot</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除log4j,使用logback记录日志 -->
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>log4j-over-slf4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 引入logback -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>

        <!-- 引入mysql的jar包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 使用阿里巴巴的数据源连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>

        <!-- json -->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        <!-- json end -->

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

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>


以上配置中需要注意几点:

a. 排除了spring boot中默认的日志框架log4j,使用logback;
b. 引入了MySQL的jar包;
c. 使用了阿里巴巴的druid作为数据库连接池框架;
d. 引入了json-lib作为json解析工具;
e. 引入mybatis的jar包;

Spring Boot 配置

其次是Spring Boot的配置文件application.xml,其中包括数据库的相关配置以及mybatis的相关配置:

server.port=8080
spring.application.name=xiaot-spring-boot

#spring datasource
spring.datasource.name=xiaot
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true&socketTimeout=60000&autoReconnectForPools=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.filters=stat
spring.datasource.maxActive=20
spring.datasource.initialSize=1
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxOpenPreparedStatements=20
spring.http.multipart.max-file-size=30Mb
spring.http.multipart.max-request-size=100Mb

#mybatis config
mybatis.config=classpath:mybatis-config.xml


spring boot的启动类Main.java:

package com.xiaot.spring.boot;

import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.xiaot.spring.boot.*.mapper")
public class Main {

    private static final Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) throws Exception {
        logger.info("Spring Boot Beginning ...");
        SpringApplication.run(Main.class, args);
    }

}


Mybatis 配置

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

    <!-- 全局参数 -->
    <settings>
        <!-- 使全局的映射器启用或禁用缓存。 -->
        <setting name="cacheEnabled" value="true"/>

        <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
        <setting name="lazyLoadingEnabled" value="true"/>

        <!-- 当启用时,有延迟加载属性的对象在被调用时将会完全加载任意属性。否则,每种属性将会按需要加载。 -->
        <setting name="aggressiveLazyLoading" value="true"/>

        <!-- 是否允许单条sql 返回多个数据集  (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>

        <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>

        <!-- 允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。  default:false  -->
        <setting name="useGeneratedKeys" value="false"/>

        <!-- 指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分  FULL:全部  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        <!-- 这是默认的执行类型  (SIMPLE: 简单; REUSE: 执行器可能重复使用prepared statements语句;BATCH: 执行器可以重复执行语句和批量更新)  -->
        <setting name="defaultExecutorType" value="SIMPLE"/>

        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!-- 设置本地缓存范围 session:就会有数据的共享  statement:语句范围 (这样就不会有数据的共享 ) defalut:session -->
        <setting name="localCacheScope" value="SESSION"/>

        <!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER,插入空值时不需要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>

    </settings>


</configuration>


Logback 配置

<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true">
    <property name="APP" value="com.xiaot.spring.boot"/>
    <property name="LOG_HOME" value="/export/logs/${APP}"/>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0} %X{ServiceId} - %m%n</pattern>
        </encoder>
    </appender>

    <appender name="DETAIL" class="ch.qos.logback.core.rolling.RollingFileAppender" additivity="false">
        <File>${LOG_HOME}/${APP}_detail.log</File>
        <encoder>
            <pattern>%d{yy-MM-dd.HH:mm:ss.SSS} [%-16t] %-5p %-22c{0} %X{ServiceId} - %m%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/${APP}_detail.log.%d{yyyyMMdd}</fileNamePattern>
        </rollingPolicy>
    </appender>

     <root level="INFO">
         <appender-ref ref="CONSOLE"/>
        <appender-ref ref="DETAIL"/>
    </root>  

</configuration>


业务逻辑代码

本文使用一个简单的例子来说明mybatis的使用。


1、持久层代码

Student实体类的代码实现:

package com.xiaot.spring.boot.student.entity;

public class Student{

    private String id;

    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


mybatis的mapper配置文件StudentMapper.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.xiaot.spring.boot.student.mapper.StudentMapper">

    <resultMap id="BaseResultMap" type="com.xiaot.spring.boot.student.entity.Student">
        <id column="id" property="id" jdbcType="VARCHAR"/>
        <result column="name" property="name" jdbcType="VARCHAR"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,
        name
    </sql>

    <!-- id主键查询线索 -->
    <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.String">
        select
        <include refid="Base_Column_List"/>
        from student
        where id = #{id,jdbcType=VARCHAR}
    </select>
</mapper>


mybatis的接口类StudentMapper.java

package com.xiaot.spring.boot.student.mapper;

import com.xiaot.spring.boot.student.entity.Student;

public interface StudentMapper {

    /**
     * 根据ID获取学生对象
     * @param id
     * @return
     * @author 
     * @date 2019年1月22日
     */

    public Student selectByPrimaryKey(String id);

}


2、Service层代码

Student接口类StudentService.java

package com.xiaot.spring.boot.student.service;

import com.xiaot.spring.boot.student.entity.Student;

/**
 * @ClassName StudentService
 * @author 
 * @date 2019年1月22日
 */

public interface StudentService {

    /**
     * 根据主键ID获取学生对象
     * @param id
     * @return
     * @throws Exception
     * @author 
     * @date 2019年1月22日
     */

    public Student findStudentById(String id) throws Exception;
}


以及实现类StudentServiceImpl.java

package com.xiaot.spring.boot.student.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xiaot.spring.boot.student.entity.Student;
import com.xiaot.spring.boot.student.mapper.StudentMapper;

/**
 * @ClassName StudentServiceImpl
 * @author
 * @date 2019年1月22日
 */

@Service
public class StudentServiceImpl implements StudentService {

    private static final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class);

    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Student findStudentById(String id) throws Exception {
        logger.info("Find Student Of Id:{}", id);
        return studentMapper.selectByPrimaryKey(id);
    }
}


3、Controller层代码

StudentController.java的代码实现为:

package com.xiaot.spring.boot.student.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xiaot.spring.boot.student.entity.Student;
import com.xiaot.spring.boot.student.service.StudentService;
import com.xiaot.spring.boot.student.service.StudentServiceImpl;

/**
 * @ClassName StudentController
 * @author
 * @date 2019年1月22日
 */

@Controller
public class StudentController {

    private static final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class);

    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Student findStudentById(@PathVariable("id") String id) {
        try {
            return studentService.findStudentById(id);
        } catch (Exception e) {
            logger.error("Exception!");
            return null;
        }

    }
}


功能验证

启动Spring Boot的项目,运行Main.java类,可以看到控制台日志输出:

19-01-23.12:23:45.896 [main            ] INFO  Main                    - Spring Boot Beginning ...

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.1.RELEASE)

19-01-23.12:23:46.500 [main            ] INFO  Main                    - No active profile set, falling back to default profiles: default
19-01-23.12:23:47.777 [main            ] INFO  TomcatWebServer         - Tomcat initialized with port(s): 8080 (http)
19-01-23.12:23:47.792 [main            ] INFO  Http11NioProtocol       - Initializing ProtocolHandler ["http-nio-8080"]
19-01-23.12:23:47.804 [main            ] INFO  StandardService         - Starting service [Tomcat]
19-01-23.12:23:47.805 [main            ] INFO  StandardEngine          - Starting Servlet Engine: Apache Tomcat/9.0.13
19-01-23.12:23:47.904 [main            ] INFO  [/]                     - Initializing Spring embedded WebApplicationContext
19-01-23.12:23:47.904 [main            ] INFO  ContextLoader           - Root WebApplicationContext: initialization completed in 1345 ms
19-01-23.12:23:48.465 [main            ] INFO  ThreadPoolTaskExecutor  - Initializing ExecutorService 'applicationTaskExecutor'
19-01-23.12:23:48.695 [main            ] INFO  Http11NioProtocol       - Starting ProtocolHandler ["http-nio-8080"]
19-01-23.12:23:48.721 [main            ] INFO  NioselectorPool         - Using a shared selector for servlet write/read
19-01-23.12:23:48.739 [main            ] INFO  TomcatWebServer         - Tomcat started on port(s): 8080 (http) with context path ''
19-01-23.12:23:48.742 [main            ] INFO  Main                    - Started Main in 2.619 seconds (JVM running for 3.342)


至此,大功告成。

一个普通的程序猿,水平一般,能力有限,文章难免出现纰漏,欢迎牺牲自己宝贵时间的读者,就本文内容直抒己见,我的目的仅仅是希望对读者有所帮助。


END


谈技术有态度

长按二维码关注!



以上是关于(最终版)Spring Boot集成Mybatis的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot简单xml配置集成mybatis

Spring Boot注解方式集成Mybatis

Spring Boot 集成Mybatis实现主从(多数据源)分离方案

Spring Boot集成Mybatis及通用Mapper

spring boot 集成 mybatis

Spring Boot集成Mybatis完整实例