Mybatis 别名的配置 + Mybatis配置类的调查

参考资料

  1. Mybatis配置类别名
  2. mybatis-spring-boot-autoconfigure
  3. 类型别名(typeAliases)
  4. SpringBoot五步配置Mybatis超简教程
  5. 深入浅出Mybatis系列(四)—配置详解之typeAliases别名(mybatis源码篇)

目录

  • 一. 使用场景
  • 二. 前期准备
    • 2.1 实体类
    • 2.2 查询接口
  • 三. 配置方式1 配置文件的方式
    • 3.1 application.yml文件
    • 3.2 SQL的XMl文件
    • 3.3 效果
  • 四. 配置方式2 配置类的方式
    • 4.1 创建配置类,实现ConfigurationCustomizer
    • 4.2 效果
  • 五. 原理
  • 六. 注意事项


一. 使用场景

  • 如下面的代码所示,我们通过一个SQL查询数据,返回值类型为Ttag类型,我们需要通过resultType来指定Ttag类的全路径com.example.jmw.entity.alias.Ttag。一两个类还好说,如果使用的实体类数量过多,配置起来就很繁琐,我们需要为每一个类都指定全路径。
  • 这个时候,就可以用到Mybatis的别名配置,我们可以指定实体类指定别名或者指定Mybatis扫描某个包,自动为该包下面的所有实体类都起别名。

DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.jmw.mapper.alias_mapper.TtagMapper">
    <select id="queryAllTtag" resultType="com.example.jmw.entity.alias.Ttag">
        SELECT
          *
        FROM
          t_tag
    select>
mapper>

二. 前期准备

2.1 实体类

  • alias包下的实体类
package com.example.jmw.entity.alias;

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

@Data
@Alias("jmwUser")
public class EnumUser {

    private String name;

    private String sex;
}
package com.example.jmw.entity.alias;

import lombok.Data;

@Data
public class I18message {

    private String code;

    private String locale;

    private String item;
}
package com.example.jmw.entity.alias;

import lombok.Data;

@Data
public class Ttag {

    private String id;

    private String name;
}

2.2 查询接口

import com.example.jmw.entity.alias.EnumUser;
import java.util.List;

public interface EnumUserMapper {

    List<EnumUser> queryAllEnumUser();
}
import com.example.jmw.entity.alias.I18message;
import java.util.List;

public interface I18messageMapper {

    List<I18message> queryAllI18message();
}
import com.example.jmw.entity.alias.Ttag;
import java.util.List;

public interface TtagMapper {

    List<Ttag> queryAllTtag();
}

三. 配置方式1 配置文件的方式

3.1 application.yml文件

  • 如果有多个包的话,中间用分隔。
mybatis:
    type-aliases-package: com.example.jmw.entity.alias;

3.2 SQL的XMl文件

  • 我们之所以可以把resultType的值配置为jmwUser,是因为我们在EnumUser实体类上配置了@Alias("jmwUser")注解,手动指定了EnumUser实体类的别名。
<mapper namespace="com.example.jmw.mapper.alias_mapper.EnumUserMapper">
    <select id="queryAllEnumUser" resultType="jmwUser">
        SELECT
          *
        FROM
          enumuser
    select>
mapper>
  • 如果我们没有通过@Alias注解手动指定别名,默认别名为类的名称,开头字母可以大写,不过推荐使用小写。
<mapper namespace="com.example.jmw.mapper.alias_mapper.I18messageMapper">
    <select id="queryAllI18message" resultType="i18message">
        SELECT
          *
        FROM
          i18message
    select>
mapper>
  • 之前的使用全类名的方式,可以和别名的方式混用。
<mapper namespace="com.example.jmw.mapper.alias_mapper.TtagMapper">
    <select id="queryAllTtag" resultType="com.example.jmw.entity.alias.Ttag">
        SELECT
          *
        FROM
          t_tag
    select>
mapper>

3.3 效果

Mybatis 别名的配置 + Mybatis配置类的调查_第1张图片


四. 配置方式2 配置类的方式

4.1 创建配置类,实现ConfigurationCustomizer

  • MyBatis-Spring-Boot-Starter 将自动寻找实现了 ConfigurationCustomizer 接口的组件,然后会调用自定义 MyBatis 配置的方法来创建配置类。
  • 接口虽然无法直接实例化,但是可以配合函数式接口,通过lambda表达式的方式创建对象。
import org.apache.ibatis.type.TypeAliasRegistry;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class MybatisConfig {

    /*
        ConfigurationCustomizer是一个函数式接口,函数式接口只有一个方法customize(Configuration configuration)
        通过ConfigurationCustomizer来创建Mybatis的配置
    */
    @Bean
    public ConfigurationCustomizer configurationCustomizer() {

        // 下面这种写法是lambda式的简写的方式
        return configuration -> {

            // 打开别名注册类
            TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();
            // 指定包下面所有的实体类都设置别名
            typeAliasRegistry.registerAliases("com.example.jmw.entity.alias");

            // 添加拦截器
            // configuration.addInterceptor();

            // 开启驼峰命名映射
            // configuration.setMapUnderscoreToCamelCase(true);
        };
    }
}

或者可以通过实现接口这种方式

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;

@org.springframework.context.annotation.Configuration
public class MybatisConfig implements ConfigurationCustomizer {

    @Override
    public void customize(Configuration configuration) {
        // 打开别名注册类
        TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();
        // 指定包下面所有的实体类都设置别名
        typeAliasRegistry.registerAliases("com.example.jmw.entity.alias");
        
		// 添加拦截器
        // configuration.addInterceptor();

        // 开启驼峰命名映射
        // configuration.setMapUnderscoreToCamelCase(true);
    }
}

4.2 效果

Mybatis 别名的配置 + Mybatis配置类的调查_第2张图片


五. 原理

由下面的源码截图可知,Mybatis读取我们指定的包的路径,将包中所有的类都添加到别名的HashMap中。

Mybatis 别名的配置 + Mybatis配置类的调查_第3张图片
Mybatis 别名的配置 + Mybatis配置类的调查_第4张图片


六. 注意事项

之前在写这个demo时,遇到通过配置文件和配置类指定别名的时候,无法生效的问题。经过调查之后,发现自己在工程中还配置了Mybatis的拦截器,代码如下:

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.mybatis.spring.SqlSessionFactoryBean;
//import org.mybatis.spring.boot.autoconfigure.SqlSessionFactoryBeanCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    // 注入数据源
    @Resource
    private DataSource dataSource;

    // 注入自定义参数拦截器
    @Resource
    private MybatisParamInterceptor paramInterceptor;

    @Bean
    public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        // 设置数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 设置拦截器(可设置多个)
        Interceptor[] plugins = {paramInterceptor};
        sqlSessionFactoryBean.setPlugins(plugins);
        return sqlSessionFactoryBean.getObject();
    }
}


在此配置类中,我们使用了SqlSessionFactory 来添加Interceptor,将SqlSessionFactory添加到Spring的IOC容器中的这种方式,会导致Mybatis的配置文件或配置类失效。因为无论配置文件还是配置类,最终都是加载到SqlSessionFactory中,如果我们自己手动new一个SqlSessionFactory到Bean中的话,相当于重置了Mybatis为我们自动配置好的SqlSessionFactory。


官方给我们提供了SqlSessionFactoryBeanCustomizer接口来实现
Mybatis 别名的配置 + Mybatis配置类的调查_第5张图片

你可能感兴趣的:(#,Mybatis,mybatis)