转载

从mybatis到mybatis-spring再到mybatis-springboot-starter

mybatis使用入门、springboot整合,以及整合后的事务管理原理

mybatis

mybatis是一款支持自定义SQL、存储过程和高级映射的持久化框架。通过封装几乎消除了使用者编写JDBC、手动设置参数和检索结果的代码,其底层实现通过XML配置文件、Java注解的方式来配置,将Mapper接口和POJO类映射到数据库

基本使用

核心配置

  1. 使用XML配置
  • 第一步:配置mybatis的运行环境

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
        <properties resource="db.properties" />
    
        <settings>
            <setting name="logImpl" value="LOG4J"/>
            <setting name="mapUnderscoreToCamelCase" value="true" />
        </settings>
    
        <!--包别名,便于在mapper xml文件中简写resultType-->
        <typeAliases>
            <package name="com.luhc.mybatis.simple.model" />
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="UNPOOLED">
                    <property name="url" value="${db.connectionURL}"/>
                    <property name="driver" value="${db.driverClass}"/>
                    <property name="username" value="${db.userName}"/>
                    <property name="password" value="${db.password}"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <!-- 配置Mapper接口 -->
            <mapper resource="com/luhc/mybatis/simple/mapper/UserMapper.xml"/>
        </mappers>
    </configuration>
    
  • 第二步:根据配置文件来创建SqlSessionFactoryBuilder、创建SqlsessionFactory、SqlSession、从SqlSession中获取Mapper接口代理类对象

    @Test
    public void testXMLConfig() throws IOException {
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.findAll();
        Assert.assertFalse(users.isEmpty());
    
        User user = userMapper.findByKey(1L);
        Assert.assertNotNull(user);
    }
    
  1. 使用java code配置
    @Test
    public void testCodeConfig() throws IOException {
        // 从properties文件中加载配置
        Properties properties = new Properties();
        properties.load(Resources.getResourceAsStream("db.properties"));
        Properties configProperties = new Properties();
        String connectUrl = properties.getProperty("db.connectionURL");
        String driverClass = properties.getProperty("db.driverClass");
        String userName = properties.getProperty("db.userName");
        String password = properties.getProperty("db.password");
        configProperties.setProperty("url", connectUrl);
        configProperties.setProperty("driver", driverClass);
        configProperties.setProperty("username", userName);
        configProperties.setProperty("password", password);
    
        // 配置数据源
        UnpooledDataSourceFactory unpooledDataSourceFactory = new UnpooledDataSourceFactory();
        unpooledDataSourceFactory.setProperties(configProperties);
        DataSource dataSource = unpooledDataSourceFactory.getDataSource();
    
        // 配置事务工厂
        TransactionFactory transactionFactory = new JdbcTransactionFactory();
        // 配置Enviroment对象
        Environment environment = new Environment("development", transactionFactory, dataSource);
    
        // 配置Configuration对象
        Configuration configuration = new Configuration(environment);
        
        // 配置mapper
        configuration.addMapper(UserMapper.class);
        
        // 创建SqlSessionFactory实例,用于获取SqlSession
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
        
        // 创建SqlSession实例,用于获取Mapper接口的代理实例
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        // 执行Mapper接口的方法,进行实际的查询
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.findAll();
        Assert.assertFalse(users.isEmpty());
    
        User user = userMapper.findByKey(1L);
        Assert.assertNotNull(user);
    }
    

Mapper接口的配置

  1. XML方式
  • 定义XML文件

    <?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.luhc.mybatis.simple.mapper.UserMapper">
        <!--id对应接口中的方法名; resultType为映射的POJO类-->
        <select id="findAll" resultType="com.luhc.mybatis.simple.model.User">
          select * from user
        </select>
    
        <select id="findByKey" resultType="com.luhc.mybatis.simple.model.User">
            select * from user where id = #{id}
        </select>
    
    </mapper>
    
  • 定义接口:类名与XML中的namespace一致,方法名与XML中的id一致

    public interface UserMapper {
    
        List<User> findAll();
    
        User findByKey(Long id);
    }
    
  1. Java注解方式
  • 注解方式只需要定义接口
    public interface UserMapper {
    
        @Select("select * from user")
        List<User> findAll();
    
        @Select("select * from user where id = #{id}")
        User findByKey(Long id);
    }
    

常用功能

  • environment

    实现多数据源,通过在配置中定义多个environment实例,在创建SqlSessionFactory的时候,传入指定的environment来实现多数据源并存的功能

  • 类型转换

    用于实现Jdbc数据类型Java类型之间的相互转换,通过实现接口TypeHandler来实现,mybatis提供了抽象类BaseTypeHandler来方便我们实现该接口。可参考文档 typeHandler

  • 插件

    用于拦截mybatis底层代码执行的机制,可参考文档 plugin 。 PageHelper

参考文档

官方文档

mybatis-spring

mybatis-spring是一个使mybatis和spring无缝集成的库,由mybatis社区开发。主要作用:

  1. 使mybatis参与spring的事务管理
  2. 负责创建SqlSession和mybatis映射器,并且可以在其他bean中注入
  3. 转换mybatis的异常为spring的异常体系(DataAccessException)

基本使用

  1. 在spring中配置DataSource

    @Configuration
    @PropertySource({"classpath:/db.properties"})
    public class DataSourceConfig {
    
        @Value("${db.connectionURL}")
        private String jdbcUrl;
    
        @Value("${db.driverClass}")
        private String driverClass;
    
        @Value("${db.userName}")
        private String userName;
    
        @Value("${db.password}")
        private String password;
    
        @Bean
        public DataSource masterDataSource() {
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setUrl(jdbcUrl);
            druidDataSource.setDriverClassName(driverClass);
            druidDataSource.setUsername(userName);
            druidDataSource.setPassword(password);
    
            return druidDataSource;
        }
    
    }
    
  2. 定义对应的Mapper接口和POJO模型类

    @Mapper
    public interface CountryMapper {
        @Delete({
            "delete from country",
            "where id = #{id,jdbcType=INTEGER}"
        })
        int deleteByPrimaryKey(Integer id);
    }
    
    @Data
    public class Country {
        // ...
    }
    
  3. 在spring中配置SqlSessionFactory

    @Configuration
    @MapperScan("com.luhc.mapper")  // 扫描
    public class MybatisConfig {
    
        @Bean
        @Autowired
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
    
            return sqlSessionFactoryBean.getObject();
        }
    }
    

与直接使用mybatis的差别

在直接使用mybatis的场景中,SqlSessionFactory通过SqlSessionFactoryBuilder来构建,在mybatis-spring集成环境中通过SqlSessionFactoryBean来构建,这是一个实现了spring接口FactoryBean、InitializingBean的类。在应用启动时会创建一个SqlSessionFactory的实例,并以sqlSessionFactory保存在spring IOC容器中。

mybatis-spring中mybatis是如何参与spring事务管理的

解开这个问题需要回到SqlSessionFactoryBean在应用启动时创建SqlSessionFactory的过程

从mybatis到mybatis-spring再到mybatis-springboot-starter

可以看出,经过这一个流程后,返回的SqlSessionFactory实现类为DefaultSqlSessionFactory,可以通过它获取其内部的SpringManagedTransactionFactory。

我们再来看看在DefaultSqlSessionFactory中是如何创建SqlSession的。

public class DefaultSqlSessionFactory implements SqlSessionFactory {
    @Override
  public SqlSession openSession() {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }
  
  private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      // 调用的是SpringManagedTransactionFactory#newTransaction方法
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      final Executor executor = configuration.newExecutor(tx, execType);
      // 获取到的SqlSession
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
}

通过DefaultSqlSessionFactory创建的SqlSession为DefaultSqlSession,其内部包含了Executor实例(内部包含了上一步中TransactionFactory创建的Transaction对象),追踪到DefaultSqlSession内部

public class DefaultSqlSession implements SqlSession {
  @Override
  public void commit(boolean force) {
    try {
      // 委托给Executor实例来进行实际的提交
      executor.commit(isCommitOrRollbackRequired(force));
      dirty = false;
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }
}

追踪到Executor内部、其实现类有SimpleExecutor(一般使用这个)、BatchExecutor(批量处理)、ReuseExecutor(?)

public abstract class BaseExecutor implements Executor {

  @Override
  public void commit(boolean required) throws SQLException {
    if (closed) {
      throw new ExecutorException("Cannot commit, transaction is already closed");
    }
    clearLocalCache();
    flushStatements();
    if (required) {
      // 委托给Transaction实例处理
      transaction.commit();
    }
  }
}

到了这一步,对应的Transaction实例为SpringManagedTransaction

public class SpringManagedTransaction implements Transaction {


  @Override
  public Connection getConnection() throws SQLException {
    if (this.connection == null) {
      openConnection();
    }
    return this.connection;
  }
  
  
  private void openConnection() throws SQLException {
    // 用Spring的DataSourceUtils工具类获取链接
    this.connection = DataSourceUtils.getConnection(this.dataSource);
    this.autoCommit = this.connection.getAutoCommit();
    this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);

    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug(
          "JDBC Connection ["
              + this.connection
              + "] will"
              + (this.isConnectionTransactional ? " " : " not ")
              + "be managed by Spring");
    }
  }
  
  @Override
  public void commit() throws SQLException {
    if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Committing JDBC Connection [" + this.connection + "]");
      }
      this.connection.commit();
    }
  }
}

使用SqlSessionTemplate替代代码中使用SqlSession的代码

SqlSessionTemplate利用动态代理生成SqlSession接口的代理对象,通过SqlSessionInterceptor拦截了方法执行,在获取SqlSession的时候委托给Spring的TransactionSynchronizationManager#getResource方法来获取(底层为ThreadLocal原理实现)

使用SqlSessionDaoSupport抽象类创建数据访问层

提供了便利的实现方式,让直接使用SqlSession的数据访问层可以使用SqlSessionTemplate来保证线程安全和委托spring事务管理

Mapper接口的注册

  • 第一种,手动注册

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
      SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
      sqlSessionFactory.setDataSource(dataSource());
      return (SqlSessionFactory) sqlSessionFactory.getObject();
    }
    
    @Bean
    public UserMapper userMapper() throws Exception {
      SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
      return sessionTemplate.getMapper(UserMapper.class);
    }
    
  • 第二种,自动扫描

  1. 使用@MapperScan注解,查看注解源码,发现可以指定要使用的SqlSessionFactory bean的名称

    @Configuration
    @MapperScan("com.luhc.mapper")
    public class MybatisConfig {
    
        @Bean
        @Autowired
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
    
            return sqlSessionFactoryBean.getObject();
        }
    
        @Bean
        @Autowired
        public PlatformTransactionManager dataSourceTransactionManager(DataSource dataSource) {
            DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
            dataSourceTransactionManager.setDataSource(dataSource);
    
            return dataSourceTransactionManager;
        }
    }
    
  2. 注册一个MapperScannerConfigurer实例

    MapperScannerConfigurer实现了接口BeanDefinitionRegistryPostProcessor,在实例化时,spring框架会回调方法MapperScannerConfigurer#postProcessBeanDefinitionRegistry,进行mapper接口的扫描

mybatis-spring-boot-starter

mybatis-spring-boot-starter为了快速在springboot中集成mybatis,使用这个库,我们将消除模板式的xml配置代码,更少的XML配置。

基本使用

  1. 直接引入依赖

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    
  2. 定义mapper接口

    @Mapper
    public interface CityMapper {
    
        @Select("SELECT * FROM CITY WHERE state = #{state}")
        City findByState(@Param("state") String state);
    
    }
    
  3. springboot启动类

    @SpringBootApplication
    public class SampleMybatisApplication implements CommandLineRunner {
    
        private final CityMapper cityMapper;
    
        public SampleMybatisApplication(CityMapper cityMapper) {
            this.cityMapper = cityMapper;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SampleMybatisApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            System.out.println(this.cityMapper.findByState("CA"));
        }
    
    }
    

引入依赖后,应用启动后将自动将DataSource实例注入并创建SqlSessionFactory、自动创建SqlSessionTemplate实例、自动扫描mapper接口并为其关联SqlSessionTemplate实例(保证SqlSession线程安全)。其内部默认会扫描到@Mapper注解标记的接口,如果需要更改这个机制,需要使用@MapperScan注解来配置

常用工具

代码生成器(mybatis-generator)

通过简单的XML配置,可以根据数据库表生成POJO映射类、XML mapper文件、Java mapper接口。而且对XML mapper文件不会覆盖掉自定义过的内容,只是写入自动生成有变动的部分,对于Java mapper接口文件则会直接覆盖。

这里提供一个在maven运行插件的方式,包含了常用配置的配置样例, 更多的配置详情请自行到官网挖掘

  • maven插件配置

    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.7</version>
        <configuration>
            <verbose>true</verbose>
            <overwrite>true</overwrite>
        </configuration>
        <executions>
            <execution>
                <id>Generate MyBatis Artifacts</id>
                <goals>
                    <goal>generate</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--生成lombok形式的java bean-->
            <dependency>
                <groupId>com.softwareloop</groupId>
                <artifactId>mybatis-generator-lombok-plugin</artifactId>
                <version>1.0</version>
            </dependency>
    
        </dependencies>
    </plugin>
    
  • generatorConfig.xml配置

    <?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配置文件-->
        <properties resource="db.properties" />
    
        <!--defaultModelType=flat,设置一个表只生成一个java实体类-->
        <context id="MySQL" targetRuntime="MyBatis3" defaultModelType="flat">
            <!--定义分隔符-->
            <property name="autoDelimitKeywordss" value="true" />
            <property name="beginningDelimiter" value="`" />
            <property name="endingDelimiter" value="`" />
            <property name="javaFileEncoding" value="UTF-8" />
    
            <!--生成lombok形式的java bean-->
            <plugin type="com.softwareloop.mybatis.generator.plugins.LombokPlugin" />
    
            <!--注释管理器-->
            <commentGenerator>
                <!--阻止生成注释-->
                <!--<property name="suppressAllComments" value="true" />-->
    
                <!--阻止生成的注释信息包含时间戳-->
                <property name="suppressDate" value="true" />
                <!--注释带上数据库表的注释信息-->
                <property name="addRemarkComments" value="true" />
            </commentGenerator>
    
            <!--jdbc连接器-->
            <jdbcConnection connectionURL="${db.connectionURL}"
                            driverClass="${db.driverClass}"
                            userId="${db.userName}"
                            password="${db.password}">
            </jdbcConnection>
    
            <!--jdbc类型与java类型转换器-->
            <javaTypeResolver >
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <javaModelGenerator targetPackage="com.luhc.mybatis.simple.model" targetProject="src/main/java">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
                <!--从数据库查询的值不必去除空格-->
                <property name="trimStrings" value="false" />
            </javaModelGenerator>
    
            <sqlMapGenerator targetPackage="com.luhc.mybatis.simple.mapper" targetProject="src/main/resources">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
            </sqlMapGenerator>
    
            <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.luhc.mybatis.simple.mapper" targetProject="src/main/java">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
    
            <table schema="mybatis" tableName="country" >
                <!--参考配置说明http://www.mybatis.org/generator/configreference/generatedKey.html-->
                <generatedKey column="id" sqlStatement="SELECT LAST_INSERT_ID()" type="post" identity="true"/>
            </table>
            <!-- 生成多张表 -->
            <table schema="mybatis" tableName="user">
                <!--参考配置说明http://www.mybatis.org/generator/configreference/generatedKey.html-->
                <generatedKey column="id" sqlStatement="SELECT LAST_INSERT_ID()" type="post" identity="true"/>
                <!-- 指定该字段对应的Java类型 -->
                <columnOverride column="sex" property="sex" javaType="com.luhc.mybatis.simple.model.SexEnum" />
            </table>
    
        </context>
    </generatorConfiguration>
    

tkmapper(通用mapper)

预定义了基本的单表CRUD操作方法,减少了手动编写CRUD的工作。

  • 引入依赖

    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>2.1.5</version>
    </dependency>
    
  • maven插件配置,mybatis generator代码生成器

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
    
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
                <executions>
                    <execution>
                        <id>Generate MyBatis Artifacts</id>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>6.0.6</version>
                    </dependency>
                    <!--生成lombok形式的java bean-->
                    <dependency>
                        <groupId>com.softwareloop</groupId>
                        <artifactId>mybatis-generator-lombok-plugin</artifactId>
                        <version>1.0</version>
                    </dependency>
                    <dependency>
                        <groupId>tk.mybatis</groupId>
                        <artifactId>mapper</artifactId>
                        <version>4.1.5</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    
  • generatorConfig配置

    <?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>
    
        <!--defaultModelType=flat,设置一个表只生成一个java实体类-->
        <context id="MySQL" targetRuntime="MyBatis3Simple" defaultModelType="flat">
            <!--定义分隔符-->
            <property name="autoDelimitKeywordss" value="true" />
            <property name="beginningDelimiter" value="`" />
            <property name="endingDelimiter" value="`" />
            <property name="javaFileEncoding" value="UTF-8" />
    
            <!--生成lombok形式的java bean。与通用Mapper插件冲突-->
            <!--<plugin type="com.softwareloop.mybatis.generator.plugins.LombokPlugin" />-->
            <!--通用mapper插件-->
            <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
                <!--生成的Mapper会继承这里指定的类-->
                <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
                <property name="caseSensitive" value="true"/>
                <property name="forceAnnotation" value="true"/>
                <property name="beginningDelimiter" value="`"/>
                <property name="endingDelimiter" value="`"/>
                <property name="needsData" value="true" />
            </plugin>
            <!--注释管理器-->
            <commentGenerator>
                <!--阻止生成注释-->
                <!--<property name="suppressAllComments" value="true" />-->
    
                <!--阻止生成的注释信息包含时间戳-->
                <property name="suppressDate" value="true" />
                <!--注释带上数据库表的注释信息-->
                <property name="addRemarkComments" value="true" />
            </commentGenerator>
    
            <!--jdbc连接器-->
            <jdbcConnection connectionURL="jdbc:mysql://111.230.14.116:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"
                            driverClass="com.mysql.cj.jdbc.Driver"
                            userId="用户"
                            password="密码">
            </jdbcConnection>
    
            <!--jdbc类型与java类型转换器-->
            <javaTypeResolver >
                <property name="forceBigDecimals" value="false" />
            </javaTypeResolver>
    
            <javaModelGenerator targetPackage="com.treeinsea.glimmer.model" targetProject="src/main/java">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
                <!--从数据库查询的值不必去除空格-->
                <property name="trimStrings" value="false" />
            </javaModelGenerator>
    
            <sqlMapGenerator targetPackage="com.treeinsea.glimmer.mapper" targetProject="src/main/resources">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
            </sqlMapGenerator>
    
            <javaClientGenerator type="XMLMAPPER" targetPackage="com.treeinsea.glimmer.mapper" targetProject="src/main/java">
                <!--不根据database划分不同的包-->
                <property name="enableSubPackages" value="false" />
            </javaClientGenerator>
    
            <!--catalog指定表所在的数据库,避免了同名表的问题-->
            <table tableName="country" catalog="mybatis" >
                <property name="ignoreQualifiersAtRuntime" value="true" />
                <!--参考配置说明http://www.mybatis.org/generator/configreference/generatedKey.html-->
                <generatedKey column="id" sqlStatement="SELECT LAST_INSERT_ID()" type="post" identity="true"/>
            </table>
            <table tableName="user" catalog="mybatis" >
                <property name="ignoreQualifiersAtRuntime" value="true" />
                <!--参考配置说明http://www.mybatis.org/generator/configreference/generatedKey.html-->
                <generatedKey column="id" sqlStatement="SELECT LAST_INSERT_ID()" type="post" identity="true"/>
            </table>
    
        </context>
    </generatorConfiguration>
    
  • application.yaml指定扫描的基接口

    mapper:
      mappers:
        - tk.mybatis.mapper.common.Mapper
      not-empty: true
    
原文  https://blog.luhuancheng.com/2019/03/26/从mybatis到mybatis-spring再到mybatis-springboot-starter/
正文到此结束
Loading...