Mybatis探究

Mybatis探究

mybatis应用十分广泛,也十分简单,通过mybatis-generator反射生成对应的model与mapper即可直接使用。hibernate也有一套类似的工具,但使用起来没有mybatis方便:hibernate tools。

mybatis应用

从使用的角度看,我们会先建表(举例):
CREATE SCHEMA IF NOT EXISTS SYSTEM DEFAULT CHARACTER SET utf8 ;
USE SYSTEM ;
DROP TABLE IF EXISTS about ;
CREATE TABLE IF NOT EXISTS about (
ID CHAR(21) NOT NULL,
NAME VARCHAR(128) NOT NULL,
UPDATE_USER CHAR(21) NOT NULL,
CREATE_USER CHAR(21) NOT NULL,
CREATE_TIME DATETIME(3) NOT NULL,
UPDATE_TIME DATETIME(3) NOT NULL,
PRIMARY KEY (ID))
ENGINE = InnoDB;
然后在服务中引入如下三个依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-core</artifactId>
</dependency>

mysql-connector-java:数据源为mysql(使用其他数据源需要更改为对应的依赖)
mybatis-spring-boot-starter:mybatis依赖(springboot集成的依赖,非springboot需引入相应的版本)
mybatis-generator-core:mybatis-generator生成器(mybatis反射生成必须引入的依赖)
然后配置mybatis-generator.xml配置反射生成的参数配置
最后执行生成对应的接口与实体

1. mybatis-generator

这里先说下mybatis-generator:

配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <properties resource="mybatis.yml"/>
    <context id="MysqlTables" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <property name="autoDelimitKeywords" value="true" />
        <property name="javaFileEncoding" value="utf-8" />
        <property name="beginningDelimiter" value="`" />
        <property name="endingDelimiter" value="`" />
        <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
        <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
        <commentGenerator >
            <property name="suppressAllComments" value="false"/><!-- 是否取消注释 -->
            <property name="suppressDate" value="true" /> <!-- 是否生成注释代时间戳-->
        </commentGenerator>
        <jdbcConnection driverClass="${driver-class-name}"   connectionURL="${url}"
                        userId="${data-username}"   password="${data-password}" />
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <javaModelGenerator targetPackage="com.spring.framework.user.database.po"  targetProject="src/main/java" >
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <sqlMapGenerator targetPackage="com.spring.framework.user.database.mapper"
                         targetProject="src/main/resources" >
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>
        <javaClientGenerator targetPackage="com.spring.framework.user.database.mapper"
                             targetProject="src/main/java"  type="XMLMAPPER" >
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <table tableName="%"  enableCountByExample="true"  enableUpdateByExample="true"
               enableDeleteByExample="true"  enableSelectByExample="true"  selectByExampleQueryId="true">
            <property name="useActualColumnNames" value="false" />
            <generatedKey column="id" sqlStatement="Mysql" identity="true" />
        </table>
    </context>
</generatorConfiguration>

说明:
首先xml规范格式使用的是引入mybatis官网dtd文件,然后往下是generatorConfiguration生成器配置,主要包含数据库的基础配置(autoDelimitKeywords-自动识别关键字,javaFormatter格式化、大小写处理等)、生成实体接口的包路径与对应的表结构配置。

执行器:

配置文件的加载应用通过请求执行开始:
在这里插入图片描述
入口:org.mybatis.generator.api.ShellRunner
此类主要功能为执行前的校验(配置文件的格式,必要参数是否存在等),最终会创建生成器执行。
方法主体:
在这里插入图片描述
1.加载配置:

    String configfile = arguments.get(CONFIG_FILE);
    File configurationFile = new File(configfile);

2.读取配置:

    Configuration config = cp.parseConfiguration(configurationFile);

3.创建并执行生成器:

    MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, shellCallback, warnings);
    myBatisGenerator.generate(progressCallback, contexts, fullyqualifiedTables);

4.执行器:
4.1读取配置内容:
在这里插入图片描述
4.2数据库映射:
在这里插入图片描述
introspectTables()方法:
依据jdbcConnection的配置链接数据库,然后依据table表名配置与数据源schemal配置获取对应信息:
在这里插入图片描述
4.3 接口与实体内容的生成:
在这里插入图片描述
详细生成方法:
在这里插入图片描述
新版本与旧版本的兼容:
在这里插入图片描述
会将读取的数据库sqMap信息格式化存储到对象中:
在这里插入图片描述
4.4 结果文件生成:
依据获取的数据库信息在配置的文件路径下生成对应的类文件:
分为java类与xml类:
在这里插入图片描述
在往下就是底层的文件格式内容读取、校验,然后排版布局、写入等操作。
最终会生成我们熟悉的mapper接口与xml的sqlMap类。

ps:mybatis-generator提供很多功能,以及生成器也有很多内容,这里不赘述,这里仅列下流程,详细大家可以跟进。

2. mybatis

mybatis在应用时,首先是服务启动加载mapper,然后是使用时注入mapper。

mapper加载:

springcloud(springboot)整合mybatis的情况下,启动服务会加载mapperscan:

  @Documented
  @Import(MapperScannerRegistrar.class)
  public @interface MapperScan {...

通过该注解,在服务启动的时候,实现registerBeanDefinitions()接口:

  public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
  ...
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  ...

此方法会定义一个类扫描器对指定路径下的包进行扫描,放入spring容器中:

  ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry)
  ...
  scanner.registerFilters();
  scanner.doScan(StringUtils.toStringArray(basePackages));

其中registerFilters()设置过滤器,doScan()方法就是将class文件放入bean中,这个bean就是mapperFactoryBean:

  private MapperFactoryBean<?> mapperFactoryBean = new MapperFactoryBean<Object>();
  ...
  definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); // issue #59
  definition.setBeanClass(this.mapperFactoryBean.getClass());
mapper应用:

由上面在服务加载时将mapper交由mapperFactoryBean管理,那我们可知mapperFactoryBean继承了SqlSessionDaoSupport并实现了getObject()接口:

  public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
  ...
  @Override
  public T getObject() throws Exception {
      return getSqlSession().getMapper(this.mapperInterface);
  }
  ...

那么这里说明下:
1.接口InitializingBean在服务启动后进行实例化所有的bean,接口DaoSupport实现了该bean接口,并进行了sqlsession初始化校验,而我们的MapperFactoryBean又继承了SqlSessionDaoSupport,SqlSessionDaoSupport继承了DaoSupport,故服务加载时会对sqlsession进行初始化并管理mapper:

  @Override
  protected void checkDaoConfig() {
    super.checkDaoConfig();

    notNull(this.mapperInterface, "Property 'mapperInterface' is required");

    Configuration configuration = getSqlSession().getConfiguration();
    if (this.addToConfig && !configuration.hasMapper(this.mapperInterface)) {
      try {
        configuration.addMapper(this.mapperInterface);
      } catch (Exception e) {
        logger.error("Error while adding the mapper '" + this.mapperInterface + "' to configuration.", e);
        throw new IllegalArgumentException(e);
      } finally {
        ErrorContext.instance().reset();
      }
    }
  }

2.sqlsessionTemplate:
sqlsession初始化时会创建sqlsessionTemplate对象对session工厂进行管理:

  public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    if (!this.externalSqlSession) {
      this.sqlSession = new SqlSessionTemplate(sqlSessionFactory);
    }
  }

sqlsessionTemplate核心代码:
在这里插入图片描述
sqlSessionProxy生成代理对象,所有的接口方法CURD都会通过该代理进行处理。
然后当我们请求mapper接口操作时会首先被SqlSessionInterceptor拦截处理:
在这里插入图片描述
大致都会经历四步:
1.获取sqlsession
2.根据请求方法进行反射找到具体的方法
3.提交session请求
4.关闭sqlsession

2020!
大家新年快乐呀~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值