springBoot整合通用Mapper插件的源码简单解读

本文探讨通用Mapper的实现原理,而非整合教程。通过分析@MapperScan注解及引入的类,揭示其如何将Mapper接口放入IOC容器,并详细解析MapperFactoryBean类的关键逻辑,如何处理通用Mapper的抽象方法生成SQL。相比mybatis-plus,通用Mapper具有更低的侵入性和独立于MyBatis版本的优势,但功能相对较少,更易于学习和扩展。
摘要由CSDN通过智能技术生成

本篇主要是简单讲解,通用Mapper的实现原理,不是整合教程。每次学习一个新的框架/插件的时候,我们一开始都是按照官方示例写代码,达到了会用的目的。等用一段时候之后,就应该学习源码,学习它是如何设计的,为啥,简简单单的一个配置就可以完成很多事情。 

示例代码来自插件自带的springBoot整合示例代码:

  //简单的依赖,一个starter,一个h2内存数据库
    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
package tk.mybatis.sample.domain;

import org.apache.ibatis.type.JdbcType;
import tk.mybatis.mapper.annotation.ColumnType;

import javax.persistence.Id;
import java.io.Serializable;

/**
 * Description: Country
 * Author: liuzh
 * Update: liuzh(2014-06-06 13:38)
 */
public class Country implements Serializable {
    private static final long serialVersionUID = 6569081236403751407L;
    @Id
    @ColumnType(jdbcType = JdbcType.BIGINT)
    private Long   id;
    private String countryname;
    private String countrycode;

    public Long getId() {
        return id;
    }

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

    public String getCountryname() {
        return countryname;
    }

    public void setCountryname(String countryname) {
        this.countryname = countryname;
    }

    public String getCountrycode() {
        return countrycode;
    }

    public void setCountrycode(String countrycode) {
        this.countrycode = countrycode;
    }
}

package tk.mybatis.sample.mapper;

import org.apache.ibatis.annotations.Mapper;
import tk.mybatis.sample.domain.Country;

@Mapper
public interface CountryMapper extends tk.mybatis.mapper.common.Mapper<Country> {

}
package tk.mybatis.sample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.sample.domain.Country;
import tk.mybatis.sample.mapper.CountryMapper;
import tk.mybatis.spring.annotation.MapperScan;

import java.util.List;

@MapperScan(basePackages = "tk.mybatis.sample.mapper")
@SpringBootApplication
public class SampleMapperApplication implements CommandLineRunner {

    @Autowired
    private CountryMapper countryMapper;

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

    @Override
    public void run(String... args) throws Exception {
        List<Country> countries = countryMapper.selectAll();
        for (Country country : countries) {
            System.out.println("Country Name: " + country.getCountryname());
        }
    }

}

 首先,和普通boot项目没有啥区别,就是多了一个注解@MapperScan。我们先看下这个注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(tk.mybatis.spring.annotation.MapperScannerRegistrar.class)
public @interface MapperScan {
。。。
}

使用了@Import注解,作用就是初始化类放入spring的ioc容器中,那我们就去看看引入的这个类


package tk.mybatis.spring.annotation;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.spring.mapper.ClassPathMapperScanner;
import tk.mybatis.spring.mapper.MapperFactoryBean;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
    public static final Logger LOGGER = LoggerFactory.getLogger(MapperScannerRegistrar.class);

    private ResourceLoader resourceLoader;

    private Environment environment;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
        // this check is needed in Spring 3.1
        if (resourc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值