【WitSystem】FastAPI目录架构最佳实践

一个“最佳”的FastAPI目录架构,核心肯定是高内聚、低耦合、可扩展性强、便于维护,并能适配从小型项目到大型企业级应用的演进。以下架构参考了FastAPI官方推荐实践、DDD(领域驱动设计)思想及工业界通用标准,同时兼顾了灵活性和规范性。

一、通用目录架构(推荐版)

适用于90%以上的场景(从小型API到中大型服务),结构清晰且无过度设计,可根据项目规模灵活增减模块。

your_project/                  # 项目根目录
├── .env                       # 环境变量(开发环境用,不提交Git)
├── .env.prod                  # 生产环境变量模板(提交Git,填占位符)
├── .gitignore                 # Git忽略文件(venv、.env、__pycache__等)
├── README.md                  # 项目说明(安装、启动、接口文档等)
├── requirements.txt           # 依赖包列表(或用pyproject.toml+poetry)
├── pyproject.toml             # 项目元信息(推荐用Poetry/Pipenv管理依赖)
├── main.py                    # 项目入口(启动服务、注册核心组件)
├── core/                      # 核心配置(全局通用、不依赖其他模块)
│   ├── __init__.py
│   ├── config.py              # 配置中心(读取环境变量、统一配置)
│   ├── exceptions.py          # 全局异常定义(自定义错误类)
│   ├── middlewares.py         # 全局中间件(日志、跨域、认证等)
│   ├── dependencies.py        # 全局依赖(如登录验证、数据库连接)
│   └── logger.py              # 日志配置(自定义日志格式、输出)
├── api/                       # 接口层(仅负责路由注册和请求/响应处理)
│   ├── __init__.py
│   ├── api_v1/                # API v1版本(支持多版本共存)
│   │   ├── __init__.py
│   │   ├── endpoints/         # 按业务模块拆分路由
│   │   │   ├── __init__.py
│   │   │   ├── user.py        # 用户相关接口(/api/v1/users/*)
│   │   │   └── item.py        # 商品相关接口(/api/v1/items/*)
│   │   └── router.py          # v1版本路由汇总(注册所有endpoints)
│   └── deps/                  # 接口层专属依赖(如某模块的权限校验)
│       ├── __init__.py
│       └── user_deps.py       # 用户接口的依赖(如“必须是管理员”)
├── app/                       # 业务逻辑层(核心业务,与接口解耦)
│   ├── __init__.py
│   ├── crud/                  # 数据操作(Create/Read/Update/Delete)
│   │   ├── __init__.py
│   │   ├── base.py            # 基础CRUD(通用增删改查,复用)
│   │   ├── crud_user.py       # 用户数据操作
│   │   └── crud_item.py       # 商品数据操作
│   ├── models/                # 数据模型(数据库模型、ORM映射)
│   │   ├── __init__.py
│   │   ├── base.py            # 基础模型(如带id、create_time的基类)
│   │   ├── user.py            # 用户数据库模型
│   │   └── item.py            # 商品数据库模型
│   ├── schemas/               # 数据校验/序列化(Pydantic模型)
│   │   ├── __init__.py
│   │   ├── base.py            # 基础Schema(如分页参数、响应基类)
│   │   ├── user.py            # 用户的请求/响应Schema(如登录请求、用户信息响应)
│   │   └── item.py            # 商品的请求/响应Schema
│   └── services/              # 业务服务(复杂逻辑封装,跨CRUD调用)
│       ├── __init__.py
│       ├── user_service.py    # 用户业务(如“注册+发送欢迎邮件”)
│       └── item_service.py    # 商品业务(如“创建商品+扣库存”)
├── utils/                     # 工具函数(通用工具,无业务逻辑)
│   ├── __init__.py
│   ├── auth.py                # 认证工具(JWT生成/验证、密码加密)
│   ├── email.py               # 邮件工具(发送邮件)
│   └── common.py              # 通用工具(如时间格式化、数据转换)
├── db/                        # 数据库连接层(与数据库交互的基础)
│   ├── __init__.py
│   ├── session.py             # 数据库会话(创建SQLAlchemy Session)
│   └── base.py                # 数据库基础(如引擎配置、Base类)
└── tests/                     # 测试用例(按模块拆分,保证代码质量)
    ├── __init__.py
    ├── conftest.py            # 测试配置(如测试数据库连接、夹具)
    ├── test_api/              # 接口测试
    │   ├── test_user_api.py
    │   └── test_item_api.py
    └── test_app/              # 业务逻辑测试
        ├── test_crud_user.py
        └── test_user_service.py

二、各目录核心职责说明

1. 根目录(your_project/

  • 入口文件main.py是服务启动的唯一入口,负责初始化FastAPI实例、注册路由、挂载中间件等,不包含业务逻辑。
    示例(main.py):
    from fastapi import FastAPI
    from core.config import settings
    from core.middlewares import add_middlewares
    from api.api_v1.router import api_router
    
    app = FastAPI(title=settings.PROJECT_NAME, version="1.0.0")
    
    # 注册中间件
    add_middlewares(app)
    
    # 注册路由(统一前缀/api/v1)
    app.include_router(api_router, prefix=settings.API_V1_STR)
    
    if __name__ == "__main__":
        import uvicorn
        uvicorn.run("main:app", host="0.0.0.0", port=settings.SERVER_PORT, reload=settings.DEBUG)
    
  • 依赖管理:推荐用pyproject.toml+Poetry(现代Python依赖管理工具),替代传统的requirements.txt,支持虚拟环境隔离和依赖锁定。

2. 核心配置层(core/

  • 存放全局通用、无业务关联的配置,是项目的“基础设施”,不依赖其他模块(避免循环导入)。
  • 关键文件:
    • config.py:用pydantic-settings读取环境变量,统一管理配置(如数据库地址、JWT密钥、服务端口),示例:
      from pydantic_settings import BaseSettings, SettingsConfigDict
      
      class Settings(BaseSettings):
          PROJECT_NAME: str = "FastAPI Project"
          API_V1_STR: str = "/api/v1"
          SERVER_PORT: int = 8000
          DEBUG: bool = False
          # 数据库配置
          DB_URL: str = "postgresql://user:password@localhost:5432/dbname"
      
          model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
      
      settings = Settings()  # 单例,全局复用
      

3. 接口层(api/

  • 职责:仅负责“路由注册”和“请求/响应转换”,不包含业务逻辑(业务逻辑交给app/services/)。
  • 版本控制:通过api_v1/api_v2/目录实现API版本共存,避免接口迭代影响旧用户。
  • 路由拆分:按业务模块拆分endpoints/(如user.pyitem.py),每个文件只处理对应模块的接口,示例(api/api_v1/endpoints/user.py):
    from fastapi import APIRouter, Depends
    from app.schemas.user import UserCreate, UserResponse
    from app.services.user_service import create_user
    from api.deps.user_deps import get_current_user
    
    router = APIRouter(tags=["users"])  # tags用于接口文档分组
    
    @router.post("/users", response_model=UserResponse, summary="创建用户")
    def create_new_user(user_data: UserCreate):
        return create_user(user_data=user_data)
    
    @router.get("/users/me", response_model=UserResponse, summary="获取当前用户信息")
    def get_current_user_info(current_user: UserResponse = Depends(get_current_user)):
        return current_user
    

4. 业务逻辑层(app/

  • 核心中的核心,与接口层解耦(即使更换接口框架,业务逻辑可复用),按功能拆分为4个子模块:
子模块职责说明
models/数据库模型(ORM层),用SQLAlchemy定义表结构,仅描述“数据存储格式”。
schemas/数据校验/序列化(Pydantic层),描述“接口请求/响应格式”,负责数据合法性校验。
crud/数据操作层,封装“单一表的增删改查”,不包含复杂业务逻辑(如“只查用户,不处理权限”)。
services/业务服务层,封装“复杂业务逻辑”(跨表操作、多步骤流程),如“注册用户=创建用户(crud)+发送邮件(utils)”。
  • 关键原则crud/只做“单表操作”,services/做“业务组合”,避免crud/中混入业务逻辑。

5. 工具层(utils/

  • 存放通用工具函数,无业务关联,可跨项目复用(如密码加密、邮件发送、JWT生成)。
  • 示例(utils/auth.py):
    from datetime import datetime, timedelta
    from jose import jwt
    from core.config import settings
    from passlib.context import CryptContext
    
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    
    def verify_password(plain_password: str, hashed_password: str) -> bool:
        """验证密码"""
        return pwd_context.verify(plain_password, hashed_password)
    
    def create_access_token(subject: str) -> str:
        """生成JWT Token"""
        expire = datetime.utcnow() + timedelta(minutes=30)
        to_encode = {"exp": expire, "sub": subject}
        return jwt.encode(to_encode, settings.JWT_SECRET_KEY, algorithm=settings.JWT_ALGORITHM)
    

6. 数据库层(db/

  • 封装数据库连接逻辑,提供“会话(Session)”供crud/使用,避免重复创建连接。
  • 示例(db/session.py):
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker
    from core.config import settings
    
    # 创建数据库引擎
    engine = create_engine(settings.DB_URL, echo=settings.DEBUG)
    
    # 创建会话工厂(每次请求生成一个新Session)
    SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
    
    # 数据库基础类(所有models继承此类)
    Base = declarative_base()
    
    def get_db():
        """依赖函数:获取数据库Session(请求结束自动关闭)"""
        db = SessionLocal()
        try:
            yield db
        finally:
            db.close()
    

7. 测试层(tests/

  • 按“接口测试”和“业务逻辑测试”拆分,保证代码正确性和可维护性。
  • pytest框架,通过conftest.py提供测试夹具(如测试数据库Session、测试用户Token),示例(tests/test_api/test_user_api.py):
    def test_create_user(client):
        """测试创建用户接口"""
        response = client.post(
            "/api/v1/users",
            json={"username": "test", "email": "test@example.com", "password": "123456"}
        )
        assert response.status_code == 200
        assert response.json()["username"] == "test"
    

三、架构扩展建议

1. 大型项目(百人团队/多领域)

若项目涉及多个独立领域(如“用户系统”“订单系统”“支付系统”),可按领域拆分目录,进一步降低耦合:

your_project/
├── main.py
├── core/                  # 全局核心(不变)
├── api/                   # 接口层(不变)
├── domains/               # 领域层(按业务领域拆分)
│   ├── user/              # 用户领域(包含该领域的models、crud、services)
│   │   ├── models.py
│   │   ├── crud.py
│   │   └── services.py
│   ├── order/             # 订单领域
│   │   ├── models.py
│   │   ├── crud.py
│   │   └── services.py
│   └── payment/           # 支付领域
├── utils/                 # 工具层(不变)
└── db/                    # 数据库层(不变)

2. 新增功能模块

当需要新增一个“商品评论”模块时,只需按以下步骤操作,符合“开闭原则”:

  1. api/api_v1/endpoints/新增comment.py(注册评论相关路由);
  2. app/models/新增comment.py(评论数据库模型);
  3. app/schemas/新增comment.py(评论请求/响应Schema);
  4. app/crud/新增crud_comment.py(评论数据操作);
  5. app/services/新增comment_service.py(评论业务逻辑);
  6. tests/新增对应测试用例。

四、核心设计原则

  1. 分层清晰:接口层(api)→ 业务层(app)→ 数据层(db),每一层只做自己的事,避免“一锅粥”。
  2. 依赖单向:底层模块(core、utils、db)不依赖上层模块(api、app),避免循环导入。
  3. 配置中心化:所有配置通过core/config.py读取,不硬编码(如数据库地址、密钥)。
  4. 可测试性:业务逻辑与接口解耦,便于单独测试(如直接测试services,无需启动服务)。

通过以上架构,FastAPI项目可以轻松应对需求迭代,同时保持代码的可读性和可维护性,可以说是目前工业界验证过的“最佳实践”之一。

F:\javaTools\jdk-1.8\bin\java.exe -javaagent:C:\Users\khy18\AppData\Local\JetBrains\IntelliJIdea2025.2\captureAgent\debugger-agent.jar=file:///C:/Users/khy18/AppData/Local/Temp/capture287826476418984209.props -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:F:\javaTools\IntelliJ IDEA 2025.2\lib\idea_rt.jar=54475" -Dkotlinx.coroutines.debug.enable.creation.stack.trace=false -Ddebugger.agent.enable.coroutines=true -Dkotlinx.coroutines.debug.enable.flows.stack.trace=true -Dkotlinx.coroutines.debug.enable.mutable.state.flows.stack.trace=true -Dfile.encoding=UTF-8 -classpath "C:\Users\khy18\.m2\repository\org\junit\platform\junit-platform-launcher\1.8.2\junit-platform-launcher-1.8.2.jar;C:\Users\khy18\.m2\repository\org\junit\platform\junit-platform-engine\1.8.2\junit-platform-engine-1.8.2.jar;C:\Users\khy18\.m2\repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;C:\Users\khy18\.m2\repository\org\junit\platform\junit-platform-commons\1.8.2\junit-platform-commons-1.8.2.jar;C:\Users\khy18\.m2\repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;F:\javaTools\IntelliJ IDEA 2025.2\lib\idea_rt.jar;F:\javaTools\IntelliJ IDEA 2025.2\plugins\junit\lib\junit5-rt.jar;F:\javaTools\IntelliJ IDEA 2025.2\plugins\junit\lib\junit-rt.jar;F:\javaTools\jdk-1.8\jre\lib\charsets.jar;F:\javaTools\jdk-1.8\jre\lib\deploy.jar;F:\javaTools\jdk-1.8\jre\lib\ext\access-bridge-64.jar;F:\javaTools\jdk-1.8\jre\lib\ext\cldrdata.jar;F:\javaTools\jdk-1.8\jre\lib\ext\dnsns.jar;F:\javaTools\jdk-1.8\jre\lib\ext\jaccess.jar;F:\javaTools\jdk-1.8\jre\lib\ext\localedata.jar;F:\javaTools\jdk-1.8\jre\lib\ext\nashorn.jar;F:\javaTools\jdk-1.8\jre\lib\ext\sunec.jar;F:\javaTools\jdk-1.8\jre\lib\ext\sunjce_provider.jar;F:\javaTools\jdk-1.8\jre\lib\ext\sunmscapi.jar;F:\javaTools\jdk-1.8\jre\lib\ext\sunpkcs11.jar;F:\javaTools\jdk-1.8\jre\lib\ext\zipfs.jar;F:\javaTools\jdk-1.8\jre\lib\javaws.jar;F:\javaTools\jdk-1.8\jre\lib\jce.jar;F:\javaTools\jdk-1.8\jre\lib\jfr.jar;F:\javaTools\jdk-1.8\jre\lib\jsse.jar;F:\javaTools\jdk-1.8\jre\lib\management-agent.jar;F:\javaTools\jdk-1.8\jre\lib\plugin.jar;F:\javaTools\jdk-1.8\jre\lib\resources.jar;F:\javaTools\jdk-1.8\jre\lib\rt.jar;F:\javaCode\mybatisplus\target\test-classes;F:\javaCode\mybatisplus\target\classes;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-starter\2.6.3\spring-boot-starter-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot\2.6.3\spring-boot-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-context\5.3.15\spring-context-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-aop\5.3.15\spring-aop-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-beans\5.3.15\spring-beans-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-expression\5.3.15\spring-expression-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-autoconfigure\2.6.3\spring-boot-autoconfigure-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-starter-logging\2.6.3\spring-boot-starter-logging-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;F:\javaTools\apache-maven\maven-repository\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;F:\javaTools\apache-maven\maven-repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.1\log4j-to-slf4j-2.17.1.jar;F:\javaTools\apache-maven\maven-repository\org\apache\logging\log4j\log4j-api\2.17.1\log4j-api-2.17.1.jar;F:\javaTools\apache-maven\maven-repository\org\slf4j\jul-to-slf4j\1.7.33\jul-to-slf4j-1.7.33.jar;F:\javaTools\apache-maven\maven-repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-core\5.3.15\spring-core-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-jcl\5.3.15\spring-jcl-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-starter-test\2.6.3\spring-boot-starter-test-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-test\2.6.3\spring-boot-test-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-test-autoconfigure\2.6.3\spring-boot-test-autoconfigure-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\com\jayway\jsonpath\json-path\2.6.0\json-path-2.6.0.jar;F:\javaTools\apache-maven\maven-repository\net\minidev\json-smart\2.4.7\json-smart-2.4.7.jar;F:\javaTools\apache-maven\maven-repository\net\minidev\accessors-smart\2.4.7\accessors-smart-2.4.7.jar;F:\javaTools\apache-maven\maven-repository\org\ow2\asm\asm\9.1\asm-9.1.jar;F:\javaTools\apache-maven\maven-repository\org\slf4j\slf4j-api\1.7.33\slf4j-api-1.7.33.jar;F:\javaTools\apache-maven\maven-repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.3\jakarta.xml.bind-api-2.3.3.jar;F:\javaTools\apache-maven\maven-repository\jakarta\activation\jakarta.activation-api\1.2.2\jakarta.activation-api-1.2.2.jar;F:\javaTools\apache-maven\maven-repository\org\assertj\assertj-core\3.21.0\assertj-core-3.21.0.jar;F:\javaTools\apache-maven\maven-repository\org\hamcrest\hamcrest\2.2\hamcrest-2.2.jar;F:\javaTools\apache-maven\maven-repository\org\junit\jupiter\junit-jupiter\5.8.2\junit-jupiter-5.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\junit\jupiter\junit-jupiter-api\5.8.2\junit-jupiter-api-5.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;F:\javaTools\apache-maven\maven-repository\org\junit\platform\junit-platform-commons\1.8.2\junit-platform-commons-1.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;F:\javaTools\apache-maven\maven-repository\org\junit\jupiter\junit-jupiter-params\5.8.2\junit-jupiter-params-5.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\junit\jupiter\junit-jupiter-engine\5.8.2\junit-jupiter-engine-5.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\junit\platform\junit-platform-engine\1.8.2\junit-platform-engine-1.8.2.jar;F:\javaTools\apache-maven\maven-repository\org\mockito\mockito-core\4.0.0\mockito-core-4.0.0.jar;F:\javaTools\apache-maven\maven-repository\net\bytebuddy\byte-buddy\1.11.22\byte-buddy-1.11.22.jar;F:\javaTools\apache-maven\maven-repository\net\bytebuddy\byte-buddy-agent\1.11.22\byte-buddy-agent-1.11.22.jar;F:\javaTools\apache-maven\maven-repository\org\objenesis\objenesis\3.2\objenesis-3.2.jar;F:\javaTools\apache-maven\maven-repository\org\mockito\mockito-junit-jupiter\4.0.0\mockito-junit-jupiter-4.0.0.jar;F:\javaTools\apache-maven\maven-repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;F:\javaTools\apache-maven\maven-repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-test\5.3.15\spring-test-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\xmlunit\xmlunit-core\2.8.4\xmlunit-core-2.8.4.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus-boot-starter\3.5.1\mybatis-plus-boot-starter-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus\3.5.1\mybatis-plus-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus-extension\3.5.1\mybatis-plus-extension-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus-core\3.5.1\mybatis-plus-core-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus-annotation\3.5.1\mybatis-plus-annotation-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\com\github\jsqlparser\jsqlparser\4.3\jsqlparser-4.3.jar;F:\javaTools\apache-maven\maven-repository\org\mybatis\mybatis\3.5.9\mybatis-3.5.9.jar;F:\javaTools\apache-maven\maven-repository\org\mybatis\mybatis-spring\2.0.6\mybatis-spring-2.0.6.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\boot\spring-boot-starter-jdbc\2.6.3\spring-boot-starter-jdbc-2.6.3.jar;F:\javaTools\apache-maven\maven-repository\com\zaxxer\HikariCP\4.0.3\HikariCP-4.0.3.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-jdbc\5.3.15\spring-jdbc-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\springframework\spring-tx\5.3.15\spring-tx-5.3.15.jar;F:\javaTools\apache-maven\maven-repository\org\projectlombok\lombok\1.18.22\lombok-1.18.22.jar;F:\javaTools\apache-maven\maven-repository\mysql\mysql-connector-java\8.0.28\mysql-connector-java-8.0.28.jar;F:\javaTools\apache-maven\maven-repository\com\baomidou\mybatis-plus-generator\3.5.1\mybatis-plus-generator-3.5.1.jar;F:\javaTools\apache-maven\maven-repository\org\freemarker\freemarker\2.3.31\freemarker-2.3.31.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit5 com.it.k.MyBatisPlusPluginsTest,test3 02:48:27.127 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate] 02:48:27.141 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)] 02:48:27.199 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.it.k.MyBatisPlusPluginsTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper] 02:48:27.221 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.it.k.MyBatisPlusPluginsTest], using SpringBootContextLoader 02:48:27.227 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.it.k.MyBatisPlusPluginsTest]: class path resource [com/it/k/MyBatisPlusPluginsTest-context.xml] does not exist 02:48:27.228 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.it.k.MyBatisPlusPluginsTest]: class path resource [com/it/k/MyBatisPlusPluginsTestContext.groovy] does not exist 02:48:27.228 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.it.k.MyBatisPlusPluginsTest]: no resource found for suffixes {-context.xml, Context.groovy}. 02:48:27.229 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.it.k.MyBatisPlusPluginsTest]: MyBatisPlusPluginsTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration. 02:48:27.306 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.it.k.MyBatisPlusPluginsTest] 02:48:27.460 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [F:\javaCode\mybatisplus\target\classes\com\it\k\MybatisplusApplication.class] 02:48:27.462 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.it.k.MybatisplusApplication for test class com.it.k.MyBatisPlusPluginsTest 02:48:27.621 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.it.k.MyBatisPlusPluginsTest]: using defaults. 02:48:27.623 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.event.ApplicationEventsTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.test.context.event.EventPublishingTestExecutionListener] 02:48:27.638 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [javax/servlet/ServletContext] 02:48:27.651 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@1cdc4c27, org.springframework.test.context.event.ApplicationEventsTestExecutionListener@77b14724, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@5d9b7a8a, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@1e8ce150, org.springframework.test.context.support.DirtiesContextTestExecutionListener@604f2bd2, org.springframework.test.context.transaction.TransactionalTestExecutionListener@1d3ac898, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@1b73be9f, org.springframework.test.context.event.EventPublishingTestExecutionListener@628c4ac0, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@7b84fcf8, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@30b19518, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@363042d7, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@366ac49b, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@6ad59d92, org.springframework.boot.test.autoconfigure.webservices.client.MockWebServiceServerTestExecutionListener@56f0cc85] 02:48:27.659 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@28e8dde3 testClass = MyBatisPlusPluginsTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6d23017e testClass = MyBatisPlusPluginsTest, locations = '{}', classes = '{class com.it.k.MybatisplusApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@61c4eee0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@548a24a, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6f53b8a, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@6cb107fd, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@57bc27f5, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@15bb6bea], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map[[empty]]], class annotated with @DirtiesContext [false] with mode [null]. 02:48:27.678 [main] DEBUG org.springframework.test.context.support.DependencyInjectionTestExecutionListener - Performing dependency injection for test context [[DefaultTestContext@28e8dde3 testClass = MyBatisPlusPluginsTest, testInstance = com.it.k.MyBatisPlusPluginsTest@24d09c1, testMethod = [null], testException = [null], mergedContextConfiguration = [MergedContextConfiguration@6d23017e testClass = MyBatisPlusPluginsTest, locations = '{}', classes = '{class com.it.k.MybatisplusApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@61c4eee0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@548a24a, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6f53b8a, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@6cb107fd, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@57bc27f5, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@15bb6bea], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]]. . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.6.3) 2025-09-04 02:48:28.260 INFO 448 --- [ main] com.it.k.MyBatisPlusPluginsTest : Starting MyBatisPlusPluginsTest using Java 1.8.0_461 on K with PID 448 (started by khy18 in F:\javaCode\mybatisplus) 2025-09-04 02:48:28.261 INFO 448 --- [ main] com.it.k.MyBatisPlusPluginsTest : No active profile set, falling back to default profiles: default Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. Registered plugin: 'com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor@60cf62ad' Parsed mapper file: 'file [F:\javaCode\mybatisplus\target\classes\mapper\UserMapper.xml]' _ _ |_ _ _|_. ___ _ | _ | | |\/|_)(_| | |_\ |_)||_|_\ / | 3.5.1 2025-09-04 02:48:30.947 INFO 448 --- [ main] com.it.k.MyBatisPlusPluginsTest : Started MyBatisPlusPluginsTest in 3.215 seconds (JVM running for 4.985) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d88f893] was not registered for synchronization because synchronization is not active 2025-09-04 02:48:31.252 INFO 448 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2025-09-04 02:48:31.611 INFO 448 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. JDBC Connection [HikariProxyConnection@1280512370 wrapping com.mysql.cj.jdbc.ConnectionImpl@489bc8fd] will not be managed by Spring ==> Preparing: SELECT id,name,price,version FROM product WHERE id=? ==> Parameters: 1(Integer) Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@d88f893] org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.product' doesn't exist ### The error may exist in com/it/k/mapper/ProductMapper.java (best guess) ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: SELECT id,name,price,version FROM product WHERE id=? ### Cause: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.product' doesn't exist ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.product' doesn't exist at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:239) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:70) at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:91) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441) at com.sun.proxy.$Proxy60.selectOne(Unknown Source) at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:160) at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:89) at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148) at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89) at com.sun.proxy.$Proxy67.selectById(Unknown Source) 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:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) at com.sun.proxy.$Proxy68.selectById(Unknown Source) at com.it.k.MyBatisPlusPluginsTest.test3(MyBatisPlusPluginsTest.java:47) 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:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:66) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:231) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55) Caused by: java.sql.SQLSyntaxErrorException: Table 'mybatis_plus.product' doesn't exist at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java:371) at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java) 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:498) at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59) at com.sun.proxy.$Proxy93.execute(Unknown Source) at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64) at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79) 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:498) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:64) at com.sun.proxy.$Proxy91.query(Unknown Source) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109) at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81) at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62) at com.sun.proxy.$Proxy90.query(Unknown Source) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76) 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:498) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427) ... 87 more 2025-09-04 02:48:31.921 INFO 448 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2025-09-04 02:48:31.935 INFO 448 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code -1
最新发布
09-05
<?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>3.5.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.test</groupId> <artifactId>test1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>test1</name> <description>test1</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>9.3.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project> 你看这有什么问题
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值