聊聊、手写Mybatis SpringBoot Starter

导航: 

聊聊、Mybatis API 

聊聊、Mybatis XML

聊聊、Mybatis集成Spring XML 方式

聊聊、Mybatis集成Spring 注解方式 

聊聊、手写Mybatis XML配置方式  

聊聊、手写Mybatis 注解配置方式  

 

SpringBoot 现在应该很多公司都用到了,在它出现之前呢,我们用 Spring 要写很多的配置文件,各种各样的 XML 文件。而且我们在引入 Spring 的时候,会加入很多的 jar 包,很多时候会由于版本不匹配问题,而导致启动失败。在配置好文件和正确引入各种 jar 以后,我们需要将项目打包成 war,然后放到 web 服务器。

SpringBoot 是发展趋势,那么它有哪些特性呢?或者它能帮我们做什么呢?

 

SpringBoot特性 


1.能够快速的创建项目,利用 Spring initializr 快速创建项目,平时我们用到的开发工具也集成了这些插件,所以非常方便

2.通过 jar 来启动项目,也就是内嵌的 web 服务器

3.通过 starter 来管理依赖,解决版本不匹配问题,零配置文件

4.可以检查程序健康状况,度量标准

 

创建 mybatis-spring-boot-starter  


关于 starter 的命名,如果是我们自己创建 starter,一般是 项目名称-spring-boot-starter,这个和官网的 starter 不一样,官网的是将项目名称放最后,例如:spring-boot-starter-web

我创建的是 mybatis,所以是 mybatis-spring-boot-starter

   

 

 

 

自己写 SpringBoot Starter 必须要知道 EnableAutoConfiguration,SpringBoot 自动配置就是通过它来实现。SpringBoot 在启动的时候会去 META-INF 包下面读取 spring.factories 文件。

例如:mybatis-spring-boot-starter

 spring.factories:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.rockcode.mybatis.configurations.MybatisAutoConfiguration

这里告诉 SpringBoot 我的自动配置类是 MybatisAutoConfiguration

 

MybatisAutoConfiguration


@Configuration
@EnableConfigurationProperties(MybatisProperties.class)
public class MybatisAutoConfiguration {

@Autowired
private MybatisProperties mybatisProperties;

@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
  SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  sqlSessionFactoryBean.setDataSource(dataSource);
  return sqlSessionFactoryBean;
}

@Bean
public DataSource dataSource(){
  DruidDataSource driverManagerDataSource = new DruidDataSource();
  driverManagerDataSource.setDriverClassName(mybatisProperties.getDriver());
  driverManagerDataSource.setUrl(mybatisProperties.getUrl());
  driverManagerDataSource.setUsername(mybatisProperties.getUsername());
  driverManagerDataSource.setPassword(mybatisProperties.getPassword());
  return driverManagerDataSource;
}
}

 

MybatisProperties 


@ConfigurationProperties(prefix = "mybatis.database")

public class MybatisProperties {
  private String driver;
  private String url;
  private String username;
  private String password;

  // getter setter 方法忽略
} 

 

上面有两个 SpringBoot 知识点,@ConfigurationProperties(prefix = "mybatis.database"),@EnableConfigurationProperties(MybatisProperties.class),这两个在 SpringBoot 用的非常多,它们的好处是,你可以直接

@Autowired
private MybatisProperties mybatisProperties;

这样你就可以获取到所有的属性值,也就是生成了 Bean 对象。例如我想获取 url,那么直接 mybatisProperties.getUrl() 就行。这两个类会在后面的 SpringBoot 源码系列 文章里面聊。

其他的类,跟《聊聊、手写Mybatis 注解配置方式》里面的内容一样。 

 

AccountMapperFactoryBean 


public class AccountMapperFactoryBean extends SqlSessionDaoSupport implements FactoryBean {


private Class mapperInterface;

public void setMapperInterface(Class mapperInterface) {
this.mapperInterface = mapperInterface;
}

@Autowired
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}

@Override
protected void checkDaoConfig() {
super.checkDaoConfig();
notNull(this.mapperInterface, "Property 'mapperInterface' is required");
Configuration configuration = getSqlSession().getConfiguration();
configuration.addMapper(this.mapperInterface);
}

@Override
public Object getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}

@Override
public Class<?> getObjectType() {
return this.mapperInterface;
}
}

  

AccountMapperScan 


@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.TYPE)
@Documented
@Import(AccountImportBeanDefinitionRegistrar.class)
public @interface AccountMapperScan {

String[] value() default {};

String[] basePackages() default {};

}

  

AccountImportBeanDefinitionRegistrar 


public class AccountImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {


@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {

Map<String, Object> annotationAttributes = annotationMetadata.getAnnotationAttributes(AccountMapperScan.class.getName());
String[] value = (String[]) annotationAttributes.get("value");
String packages = value[0];

AccountClassPathMapperScanner myClassPathBeanDefinitionScanner = new AccountClassPathMapperScanner(beanDefinitionRegistry);
myClassPathBeanDefinitionScanner.registerFilters();
myClassPathBeanDefinitionScanner.scan(packages);
}

} 

 

AccountClassPathMapperScanner 


public class AccountClassPathMapperScanner extends ClassPathBeanDefinitionScanner {


public AccountClassPathMapperScanner(BeanDefinitionRegistry registry) {
super(registry, false);
}

public void registerFilters() {
addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return true;
}
});
}

@Override
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitionHolders = super.doScan(basePackages);
GenericBeanDefinition definition;
for (BeanDefinitionHolder holder : beanDefinitionHolders) {
definition = (GenericBeanDefinition) holder.getBeanDefinition();
String beanClassName = definition.getBeanClassName();
try {
Class<?> clazz = Class.forName(beanClassName);
definition.setBeanClass(AccountMapperFactoryBean.class);
definition.getPropertyValues().add("mapperInterface", clazz);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return beanDefinitionHolders;
}

@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
}
}

  

application.properties 


mybatis.database.driver = com.mysql.jdbc.Driver
mybatis.database.url = jdbc:mysql://127.0.0.1:3306/test?useSSL=false
mybatis.database.username = root
mybatis.database.password = root 

 

pom.xml 


<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.rockcode</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mybatis-spring-boot-starter</name>
<description>mybatis-spring-boot-starter</description>

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

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
</dependencies> 

 

上面就是所有的代码和配置了,然后打包成 mybatis-spring-boot-starter-0.0.1-SNAPSHOT.jar。

在其他的项目中,我们只需要引用就可以。

<dependency>
<groupId>com.rockcode</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency> 

 

好了,Mybatis 系列文章就到这里结束了。源码地址:https://github.com/xumiaoshun/mybatis-spring-boot-starter.git。

 

posted @ 2020-04-10 10:21  香农随笔  阅读(1279)  评论(0编辑  收藏  举报