Spring Boot整合MyBatis

目录

1.MyBatis的配置

2.Spring Boot整合MyBatis


MyBatis已经成为移动互联网时代的主流持久层框架,在移动互联网和一些新兴的项目中MyBatis的占有率不断升高。MyBatis是一个不屏蔽SQL且提供动态SQL、接口式编程和简易SQL绑定POJO的半自动化框架,它的使用十分简单,而且能够非常容易定制SQL,以提高网站性能。

MyBatis是基于一种SQL到POJO的模型,它需要我们提供SQL、映射关系(XML或者注解)和POJO。

1.MyBatis的配置

首先我们引入MyBatis的starter,配置如下:

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

        <!--定义MySql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

然后需要配置数据库的相关信息,在默认情况下,Spring Boot会使用其绑定的Tomcat数据源,我们可以对其进行配置。在jdbc.properties文件中配置如下:

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
#最大等待连接中的数量,设置0表示不限制
spring.datasource.tomcat.max-idle=10
#最大连接活动数
spring.datasource.tomcat.max-active=50
#最大等待毫秒数,超过时间会出错误信息
spring.datasource.tomcat.max-wait=3000
#数据库连接池初始化连接数
spring.datasource.tomcat.initial-size=5

MyBatis是一个基于SQLSessionFactory构建的框架。对于SqlSessionFactory而言,它的作用是生成SqlSession接口对象,这个接口对象是MyBatis操作的核心。而在MyBatis-Spring中的整合中,一般会"擦除"该对象,“擦除”以后就只剩下业务代码,这样就可以使得代码更具有可读性了。构建SqlSessionFactory是通过配置类完成的,因此对于mybatis-spring-boot-starter,它会给予我们在配置文件(application.properties)进行Configuration配置的相关内容。Configuration可以配置以下内容:

下面我们来看一个简单的例子:

创建数据库表并定义DO:

CREATE TABLE `user` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(20) NOT NULL,
  `sex` tinyint(2) NOT NULL,
  `note` varchar(40) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
package com.martin.config.chapter5.pojo;

import lombok.Data;
import org.apache.ibatis.type.Alias;

/**
 * @author: martin
 * @date: 2019/11/3 10:44
 * @description:
 */
@Alias(value = "user")//MyBatis指定别名
@Data
public class User {
    private Long id;
    private String userName;
    private String note;
    /**
     * 定义了性别的枚举,可以通过typeHandler转换
     */
    private SexEnum sex;
}

这里加入了加粗的注解@Alias,并且指定它的别名为“user”。这里定义了一个性别枚举,在MyBatis中,枚举可以通过typeHandler进行转换。因此这里开发了一个typeHandler:

package com.martin.config.chapter5.typehandler;

import com.martin.config.chapter5.pojo.SexEnum;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author: martin
 * @date: 2019/11/3 10:58
 * @description:
 */
@MappedJdbcTypes(JdbcType.INTEGER)
@MappedTypes(SexEnum.class)
public class SexTypeHandler extends BaseTypeHandler<SexEnum> {
    /**
     * 设置非空的性别参数
     *
     * @param preparedStatement
     * @param idx
     * @param object
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int idx, SexEnum sexEnum, JdbcType jdbcType)
            throws SQLException {
        preparedStatement.setInt(idx, sexEnum.getCode());
    }

    /**
     * 根据列名读取性别
     *
     * @param resultSet
     * @param col
     * @return
     * @throws SQLException
     */
    @Override
    public SexEnum getNullableResult(ResultSet resultSet, String col) throws SQLException {
        return getSexEnum(resultSet.getInt(col));
    }

    /**
     * 根据下标读取姓名
     *
     * @param resultSet
     * @param i
     * @return
     * @throws SQLException
     */
    @Override
    public SexEnum getNullableResult(ResultSet resultSet, int idx) throws SQLException {
        return getSexEnum(resultSet.getInt(idx));
    }

    /**
     * 通过存储过程读取性别
     *
     * @param callableStatement
     * @param idx
     * @return
     * @throws SQLException
     */
    @Override
    public SexEnum getNullableResult(CallableStatement callableStatement, int idx) throws SQLException {
        return getSexEnum(callableStatement.getInt(idx));
    }

    private static SexEnum getSexEnum(int sex) {
        if (sex != 1 && sex != 2) {
            return null;
        }
        return SexEnum.getEnumById(sex);
    }
}

在MyBatis中对于typeHandler的要求是实现TypeHandler<T>接口,而它为了更加方便也通过抽象类BaseTypeHandler<T>实现了TypeHandler<T>接口,所以这里直接继承抽象类BaseTypeHandler<T>就可以了。注解@MappedJdbcTypes声明JdbcType为数据库的整型,@MappedTypes声明Java 类型为SexEnum,这样MyBatis就可以进行类型转换了。

为了将这个POJO能够与数据库的数据对应,还需要提供一个映射文件:

<?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.martin.config.chapter5.dao.UserMapper">
    <select id="getUser" parameterType="long" resultType="user">
        select id,user_name as userName,sex,note  from user where id = #{id}
    </select>
</mapper>

<mapper>元素的namespace属性,它指定一个接口;接着定义一个<select>元素,它代表着一个查询语句;默认情况下,MyBatis会启动自动映射,将SQL中的列映射到POJO上,有时候我们也可以启动驼峰映射,这样就可以不启用别名了。<mapper>元素的namespace属性定义的MyBatisUserDao代码实现如下:

package com.martin.config.chapter5.dao;

import com.martin.config.chapter5.pojo.User;
import org.springframework.stereotype.Repository;

/**
 * @author: martin
 * @date: 2019/11/3 12:00
 * @description:
 */
@Mapper
public interface UserMapper {
    User getUser(Long id);
}

该接口中的方法getUser和映射文件中定义的查询SQL的id是保持一致的,参数也是如此,这样就能够定义一个查询方法了。最后,需要对映射文件、POJO的别名和typeHandler进行配置,配置文件application.properties中加入如下代码:

#MyBatis映射文件统配
mybatis.mapper-locations=classpath:mapper/*.xml
#MyBatis扫描别名包(注解@Alias)
mybatis.type-aliases-package=com.martin.config.chapter5.pojo
#配置typeHandler的扫描包
mybatis.type-handlers-package=com.martin.config.chapter5.typehandler
#日志级别配置
logging.level.root=DEBUG
logging.level.org.springframework=DEBUG
logging.level.org.mybatis=DEBUG

这里我们配置了我们的映射文件、别名文件和typeHandler,这样就可以让MyBatis扫描它们了。日志级别设置为DEBUG级别,是为了更好的观察测试结果。其他的都不需要进行配置,因为mybatis-spring-boot-starter对MyBatis启动做了默认的配置。配置完成MyBatis以后,接下来我们开始讨论在Spring Boot中如何整合它。

2.Spring Boot整合MyBatis

MyBatis提供了注解@MapperScan,能够将MyBatis所需的对应接口扫描装配到Spring IOC容器中。代码如下:

package com.martin.config;

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

/**
 * 配置启动类
 *
 * @author martin
 * @create 2019-01-03 下午 11:20
 **/
@SpringBootApplication
@MapperScan(
        //指定扫描包
        basePackages = "com.martin.config.chapter5.*",
        //指定SqlSessionFactory,sqlSessionTemplate被指定,则作废
        sqlSessionFactoryRef = "sqlSessionFactory",
        //指定sqlSessionTemplate,将忽略sqlSessionFactory的配置
        sqlSessionTemplateRef = "sqlSessionTemplate",
        //指定扫描的注解Mapper
        annotationClass = Mapper.class
)
public class SpringBootConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootConfigApplication.class, args);
    }
}

@MapperScan允许我们通过扫描加载MyBatis的Mapper,如果Spring Boot中不存在多个SqlSessionFactory或者SqlSessionTemplate,那么完全可以不配置sqlSessionFactoryRef 和sqlSessionTemplateRef 。但是如果是存在多个时,就需要我们制定了,另外需要注意的是sqlSessionTemplateRef的优先权大于sqlSessionFactoryRef。最后,我们选择使用注解@Mapper作为限定,这是一个Spring对持久层的注解。

至此,一个Spring Boot整合MyBatis的程序就完成了,启动应用程序,在浏览器中输入:

http://localhost:8080/index

可以看到下图的效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值