SpringBoot2.1.9 Mybatis由於@Mapper註解多數據源配置不生效問題

一、場景復現

(1)項目

目錄

配置文件

spring:
  application:
    name: multi-datasource
  profiles:
    active: dev1
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/base?autoReconnect=true&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8
    username: root
    password: admin
mybatis:
  mapper-locations: classpath*:mapper/base/*.xml
  type-aliases-package: com.mk.mybatis.multidatasource
  configuration:
    map-underscore-to-camel-case: true

sys:
  one-mybatis:
    datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/man?autoReconnect=true&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8
      username: root
      password: admin
    mybatis:
      mapper-locations: classpath*:mapper/one/*.xml
      type-aliases-package: com.mk.mybatis.multidatasource.one.entity
      configuration:
        map-underscore-to-camel-case: true
  two-mybatis:
    datasource:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/person?autoReconnect=true&zeroDateTimeBehavior=convertToNull&characterEncoding=UTF-8
      username: root
      password: admin
    mybatis:
      mapper-locations: classpath*:mapper/two/*.xml
      type-aliases-package: com.mk.mybatis.multidatasource.two.entity
      configuration:
        map-underscore-to-camel-case: true

server:
  port: 8080

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.9.RELEASE</version>
        <relativePath/>
    </parent>
    <groupId>com.mk.mybatis</groupId>
    <artifactId>multi-datasource</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>multi-datasource</name>
    <description>MybatisMultiDataSource</description>

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>1.1.20</version>
                </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.persistence</groupId>
                    <artifactId>persistence-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <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.7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.mybatis.generator</groupId>
                        <artifactId>mybatis-generator-core</artifactId>
                        <version>1.3.7</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <!--允許移動生成的文件 -->
                    <verbose>true</verbose>
                    <!-- 是否覆蓋 -->
                    <overwrite>true</overwrite>
                    <!-- 自動生成的配置 -->
                    <configurationFile>
                        generatorConfig1.xml
                    </configurationFile>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

繼承mybatis生成器生成的dao類

@Mapper
public interface DaseDao extends IBaseDao {
}
@Mapper
public interface ManDao extends IManDao {
}
@Mapper
public interface PersonDao extends IPersonDao {
}

默認mybatis數據源配置

@Configuration
@MapperScan(value = "com.mk.mybatis.multidatasource.base.dao", sqlSessionTemplateRef = "baseSqlSessionTemplate")
public class BaseMybatisConfig {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSourceProperties baseDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Primary
    @Bean("datasource")
    public DataSource baseDataSource(@Qualifier("baseDataSourceProperties") DataSourceProperties dataSourceProperties) {

        DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
        return dataSource;
    }


    @Primary
    @Bean
    @ConfigurationProperties(prefix = "mybatis")
    public MybatisProperties baseMybatisProperties() {
        return new MybatisProperties();
    }

    @Primary
    @Bean
    public SqlSessionFactory baseSqlSessionFactory(@Qualifier("datasource") DataSource dataSource,
                                                   @Qualifier("baseMybatisProperties") MybatisProperties mybatisProperties) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(mybatisProperties.resolveMapperLocations());
        bean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
        bean.setConfigurationProperties(mybatisProperties.getConfigurationProperties());
        bean.setConfiguration(mybatisProperties.getConfiguration());
        bean.setConfigLocation(Optional.ofNullable(mybatisProperties.getConfigLocation()).map(location -> {
            try {
                ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
                return resourceResolver.getResource(location);
            } catch (Exception var3) {
                return null;
            }
        }).orElse(null));

        return bean.getObject();
    }


    @Primary
    @Bean
    public DataSourceTransactionManager transactionManager(@Qualifier("datasource") DataSource dataSource) {

        return new DataSourceTransactionManager(dataSource);
    }

    @Primary
    @Bean
    public SqlSessionTemplate baseSqlSessionTemplate(@Qualifier("baseSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

one mybatis數據源配置

@Configuration
@MapperScan(value = "com.mk.mybatis.multidatasource.one.dao", sqlSessionTemplateRef = "oneSqlSessionTemplate")
@Slf4j
public class OneMybatisConfig {


    @Bean
    @ConfigurationProperties(prefix = "sys.one-mybatis.datasource")
    public DataSourceProperties oneDataSourceProperties() {
        return new DataSourceProperties();
    }


    @Bean
    public DataSource oneDataSource(@Qualifier("oneDataSourceProperties") DataSourceProperties dataSourceProperties) {

        DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
        return dataSource;
    }

    @Bean
    @ConfigurationProperties(prefix = "sys.one-mybatis.mybatis")
    public MybatisProperties oneMybatisProperties(){
        return new MybatisProperties();
    }


    @Bean
    public SqlSessionFactory oneSqlSessionFactory(@Qualifier("oneDataSource") DataSource dataSource,
                                                          @Qualifier("oneMybatisProperties")MybatisProperties mybatisProperties)throws Exception{
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(mybatisProperties.resolveMapperLocations());
        bean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
        bean.setConfigurationProperties(mybatisProperties.getConfigurationProperties());
        bean.setConfiguration(mybatisProperties.getConfiguration());
        bean.setConfigLocation(Optional.ofNullable(mybatisProperties.getConfigLocation()).map(location->{
            try {
                ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
                return resourceResolver.getResource(location);
            } catch (Exception var3) {
                return null;
            }
        }).orElse(null));

        return bean.getObject();
    }



    @Bean
    public DataSourceTransactionManager oneTransactionManager(@Qualifier("oneDataSource") DataSource dataSource) {

        return new DataSourceTransactionManager(dataSource);
    }


    @Bean
    public SqlSessionTemplate oneSqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

two mybatis數據源配置

@Configuration
@MapperScan(value = "com.mk.mybatis.multidatasource.two.dao", sqlSessionTemplateRef = "twoSqlSessionTemplate")
@Slf4j
public class TwoMybatisConfig {

    @Bean
    @ConfigurationProperties(prefix = "sys.two-mybatis.datasource")
    public DataSourceProperties twoDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    public DataSource twoDataSource(@Qualifier("twoDataSourceProperties") DataSourceProperties dataSourceProperties) {
        DataSource dataSource = dataSourceProperties.initializeDataSourceBuilder().build();
        return dataSource;
    }

    @Bean
    @ConfigurationProperties(prefix = "sys.two-mybatis.mybatis")
    public MybatisProperties twoMybatisProperties() {
        return new MybatisProperties();
    }

    @Bean
    public SqlSessionFactory twoSqlSessionFactory(@Qualifier("twoDataSource") DataSource dataSource,
                                                  @Qualifier("twoMybatisProperties") MybatisProperties mybatisProperties) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(mybatisProperties.resolveMapperLocations());
        bean.setTypeAliasesPackage(mybatisProperties.getTypeAliasesPackage());
        bean.setConfigurationProperties(mybatisProperties.getConfigurationProperties());
        bean.setConfiguration(mybatisProperties.getConfiguration());
        bean.setConfigLocation(Optional.ofNullable(mybatisProperties.getConfigLocation()).map(location -> {
            try {
                ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
                return resourceResolver.getResource(location);
            } catch (Exception var3) {
                return null;
            }
        }).orElse(null));

        return bean.getObject();
    }

    @Bean
    public DataSourceTransactionManager twoTransactionManager(@Qualifier("twoDataSource") DataSource dataSource) {

        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public SqlSessionTemplate twoSqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

(2)測試類

BaseDao

    @Resource
    private DaseDao baseDao;

    @Test
    public void testBaseDao()  {
          System.out.println(baseDao.selectByPrimaryKey(1));
    }

輸出 

2020-05-04 21:03:21,174 DEBUG [main] 5363 com.mk.mybatis.multidatasource.base.base.dao.IBaseDao.selectByPrimaryKey[143]: ==>  Preparing: select id, `name` from base where id = ? 
2020-05-04 21:03:21,205 DEBUG [main] 5394 com.mk.mybatis.multidatasource.base.base.dao.IBaseDao.selectByPrimaryKey[143]: ==> Parameters: 1(Integer)
2020-05-04 21:03:21,221 DEBUG [main] 5410 com.mk.mybatis.multidatasource.base.base.dao.IBaseDao.selectByPrimaryKey[143]: <==      Total: 0
null

 debug看到的數據源

 

 PersonDao

    @Resource
    private PersonDao personDao;

    @Test
    public void testPersonDao() {
        System.out.println(personDao.selectByPrimaryKey(1));
    }

輸出 

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.mk.mybatis.multidatasource.two.dao.PersonDao.selectByPrimaryKey

	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
	at org.apache.ibatis.binding.MapperProxy.lambda$cachedMapperMethod$0(MapperProxy.java:61)
	at org.apache.ibatis.binding.MapperProxy$$Lambda$443/448131210.apply(Unknown Source)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:61)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:56)
	at com.sun.proxy.$Proxy67.selectByPrimaryKey(Unknown Source)
	at com.mk.mybatis.multidatasource.MultiDatasourceApplicationTests.testPersonDao(MultiDatasourceApplicationTests.java:34)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

debug看到的數據源 

 

ManDao

    @Resource
    private ManDao manDao;

    @Test
    public void testManDao() {
        System.out.println(manDao.selectByPrimaryKey(1));
    }

輸出:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.mk.mybatis.multidatasource.one.dao.ManDao.selectByPrimaryKey

	at org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:235)
	at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:53)
	at org.apache.ibatis.binding.MapperProxy.lambda$cachedMapperMethod$0(MapperProxy.java:61)
	at org.apache.ibatis.binding.MapperProxy$$Lambda$443/736951628.apply(Unknown Source)
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
	at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:61)
	at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:56)
	at com.sun.proxy.$Proxy68.selectByPrimaryKey(Unknown Source)
	at com.mk.mybatis.multidatasource.MultiDatasourceApplicationTests.testManDao(MultiDatasourceApplicationTests.java:40)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
	at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

debug看到的數據源 

 

 

(3)分析

從上面的測試結果來看,多數據源配置不生效。

然而去掉PersonDao和ManDao的@Mapper註解,多數據源配置就生效了

PersonDao

//@Mapper
public interface PersonDao extends IPersonDao {
}
2020-05-04 21:26:18,477 DEBUG [main] 4644 com.mk.mybatis.multidatasource.two.base.dao.IPersonDao.selectByPrimaryKey[143]: ==>  Preparing: select id, `name` from person where id = ? 
2020-05-04 21:26:18,497 DEBUG [main] 4664 com.mk.mybatis.multidatasource.two.base.dao.IPersonDao.selectByPrimaryKey[143]: ==> Parameters: 1(Integer)
2020-05-04 21:26:18,506 DEBUG [main] 4673 com.mk.mybatis.multidatasource.two.base.dao.IPersonDao.selectByPrimaryKey[143]: <==      Total: 0
null

ManDao

//@Mapper
public interface ManDao extends IManDao {
}
2020-05-04 21:31:04,470 DEBUG [main] 4413 com.mk.mybatis.multidatasource.one.base.dao.IManDao.selectByPrimaryKey[143]: ==>  Preparing: select id, `name` from man where id = ? 
2020-05-04 21:31:04,499 DEBUG [main] 4442 com.mk.mybatis.multidatasource.one.base.dao.IManDao.selectByPrimaryKey[143]: ==> Parameters: 1(Integer)
2020-05-04 21:31:04,513 DEBUG [main] 4456 com.mk.mybatis.multidatasource.one.base.dao.IManDao.selectByPrimaryKey[143]: <==      Total: 0
null

 

二、原由

由於使用了tk.mybatis的包,默認自動全包掃描@Mapper註解。tk.mybatis掃描生成的Mapper比其他自定義配置的bean生成對應的Mapper對象快,而自定義的mybatis@MapperScan後掃描,Dao Bean已經生成了,無法再指定數據源進行注入了。

 

三、解決方案

(1)去掉tk.mybatis

        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.persistence</groupId>
                    <artifactId>persistence-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

(2)不加@Mapper註解

//@Mapper
public interface PersonDao extends IPersonDao {
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章