springboot多模块项目中将dao独立成一个模块

chenxii81 / 2023-05-13 / 原文

最近因为学习消息队列和大数据的原因,搭建了一个很简单的springcloud测试项目。分了用户、商品、订单、库存等几个模块,整个项目只涉及到10张表左右,每个模块中只有简单的几个增删改查,为了不在各个模块中重复写数据库相关以及实体类的代码,于是就想着将数据库操作以及实体类抽到一个独立公共模块中。想法很简单,但是踩了很多坑,特此记录。

项目结构如下:
image

遇到的几个问题:

  1. 启动项目报错:数据源未配置
  2. 找不到 sqlSessionTemplate or sqlSessionFactory
  3. dao bean依赖注入失败

正确的做法:

  1. 在common项目中引入MyBatis依赖
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>${postgres.version}</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>${mybatis.version}</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>
  1. 如果MyBatis的xml文件也放在src/main/java目录下,则需要在pom文件中加入,将application.yml文件加上后缀(application-common.yml)也加入到pom文件的build中:
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.java</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                </includes>
            </resource>
        </resources>
    </build>
  1. 较新版本的springcloud中不能识别bootstrap.yml文件,application.yml可以识别。

  2. 如果common项目pom文件中有加打包插件,比如 spring-boot-mave-plugin,则需要删除。

  3. 在common项目中的application.yml中定义好数据源,spring.datasource相关属性以及mybatis.mapper-locations属性。

spring:
  datasource:
    url: jdbc:postgresql://vm:5432/db
    username: default
    password: mysecretsec
    driver-class-name: org.postgresql.Driver
mybatis:
  mapper-locations: classpath:*.xml
  1. 确保dao.java文件加了@Mapper或@Repository注解,确保dao.xml文件中namespace配置无误。

  2. common项目无需入口,删除CommonApplication.java文件。

  3. 在使用需要使用数据库操作的其他模块(比如User模块)中,在application.yml中引入common模块的yml:

spring:
  profiles:
    active: common

active配置项是common项目yml文件名application-后的部分,比如application-common.yml
引入之后,UserApplication启动就能加载到Common模块的数据源配置。

  1. UserApplication.java入口类需要配置包扫描的注解:
  • @ComponentScan
  • @MapperScan
    默认只会扫描启动类所在的包及子包。
@ComponentScan(basePackages = {"com.chenxii.jinghong.common", "com.chenxii.jinghong.user"})
@MapperScan(basePackages = "com.chenxii.jinghong.common")
  1. 在User模块的pom文件中加入Common模块的依赖
        <dependency>
            <groupId>com.chenxii.jinghong</groupId>
            <artifactId>jinghong-common</artifactId>
            <version>1.1.0</version>
        </dependency>
  1. 配置User模块的pom打包:
<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                    <mainClass>com.chenxii.jinghong.user.UserApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.java</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.yml</include>
                </includes>
            </resource>
        </resources>
    </build>

至此,就可以正常在User模块中使用Common模块中定义好的dao了。

最后,写个接口,引用Common模块的dao,进入到项目根目录,正常打包,启动user-1.1.0.jar就可以正常访问User模块,查询数据了。