在 Feat Cloud 中接入 MyBatis
This content is not available in your language yet.
这一页不再试图做一份“所有 MyBatis 配置项大全”。
它只回答一个更实际的问题:如果你已经能写 Feat Cloud 控制器,现在要把数据库接进来,应该按什么顺序做。
仓库里已经有一套完整示例,可以直接对照阅读:
demo/mybatis/src/main/java/tech/smartboot/feat/demo/mybatis/Bootstrap.javademo/mybatis/src/main/java/tech/smartboot/feat/demo/mybatis/controller/UserController.javademo/mybatis/src/main/java/tech/smartboot/feat/demo/mybatis/service/UserService.javademo/mybatis/src/main/java/tech/smartboot/feat/demo/mybatis/mapper/UserMapper.javademo/mybatis/src/main/resources/feat.yamldemo/mybatis/src/main/resources/mybatis/mybatis-config.xml
下面这篇文档会严格按这套结构来讲。
你最终会得到什么
Section titled “你最终会得到什么”一个最小的 CRUD 链路:
- 访问
/users能查到所有用户 - 访问
/users/{username}能查到单个用户 POST /users能创建用户PUT /users能更新用户DELETE /users/{username}能删除用户
第一步:加依赖
Section titled “第一步:加依赖”在 pom.xml 中引入 feat-cloud-starter、mybatis 和数据库驱动。
示例项目里使用的是 H2 内存数据库:
<dependency> <groupId>tech.smartboot.feat</groupId> <artifactId>feat-cloud-starter</artifactId> <version>${feat.version}</version></dependency>
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.15</version></dependency>
<dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.224</version></dependency>第二步:把 MyBatis 配置接到 Feat Cloud 启动流程
Section titled “第二步:把 MyBatis 配置接到 Feat Cloud 启动流程”在 src/main/resources/feat.yaml 里声明两件事:
feat: mybatis: path: mybatis/mybatis-config.xml initial-sql: mybatis/ddl/schema.sql这里的含义很直接:
path:告诉 Feat Cloud 去哪里读 MyBatis 主配置initial-sql:告诉它启动时顺手执行数据库初始化脚本
这就是示例项目为什么一启动就能直接查到用户数据,而不需要你手写额外初始化逻辑。
第三步:准备 MyBatis 配置和表结构
Section titled “第三步:准备 MyBatis 配置和表结构”demo/mybatis 的 mybatis-config.xml 很克制,只做了三件事:
- 打开 SQL 日志
- 配置 H2 数据源
- 注册 mapper 包
<configuration> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="h2_mem"> <environment id="h2_mem"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="org.h2.Driver"/> <property name="url" value="jdbc:h2:mem:feat-demo;NON_KEYWORDS=value;mode=mysql;"/> </dataSource> </environment> </environments> <mappers> <package name="tech.smartboot.feat.demo.mybatis.mapper"/> </mappers></configuration>而 schema.sql 负责建表并插入几条初始数据。
这一步让后面的 Controller 和 Service 能立刻验证,不需要再手动准备数据库。
第四步:启动应用
Section titled “第四步:启动应用”示例里的启动类非常简单:
import tech.smartboot.feat.cloud.FeatCloud;import tech.smartboot.feat.cloud.annotation.Bean;
@Beanpublic class Bootstrap { public static void main(String[] args) { FeatCloud.cloudServer().listen(); }}这个类本身几乎没做业务事,但它给了 Feat Cloud 一个明确的启动入口。
MyBatis 的配置接入,主要是靠前面的 feat.yaml 和资源文件完成的。
第五步:定义 Mapper
Section titled “第五步:定义 Mapper”在示例里,Mapper 就是标准 MyBatis 注解接口:
import org.apache.ibatis.annotations.Delete;import org.apache.ibatis.annotations.Insert;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Param;import org.apache.ibatis.annotations.Select;import org.apache.ibatis.annotations.Update;
@Mapperpublic interface UserMapper {
@Select("SELECT * FROM user_info WHERE username = #{username}") User selectByUsername(@Param("username") String username);
@Select("SELECT * FROM user_info") List<User> selectAll();
@Insert("INSERT INTO user_info(username, password, `desc`, role) VALUES(#{username}, #{password}, #{desc}, #{role})") int insert(User user);
@Update("UPDATE user_info SET password=#{password}, `desc`=#{desc}, role=#{role} WHERE username=#{username}") int update(User user);
@Delete("DELETE FROM user_info WHERE username = #{username}") int deleteByUsername(@Param("username") String username);}这里最重要的不是注解语法本身,而是:
- Mapper 仍然是纯 MyBatis 思维
- Feat Cloud 负责把它接进应用上下文
第六步:在 Service 里使用 Mapper
Section titled “第六步:在 Service 里使用 Mapper”示例项目没有直接在 Controller 里操作 Mapper,而是先过一层 Service:
import tech.smartboot.feat.cloud.annotation.Autowired;import tech.smartboot.feat.cloud.annotation.Bean;
@Beanpublic class UserService {
@Autowired private UserMapper userMapper;
public User findByUsername(String username) { return userMapper.selectByUsername(username); }
public List<User> findAll() { return userMapper.selectAll(); }}这一步的意义很简单:
- Controller 负责 HTTP
- Service 负责业务动作
- Mapper 负责数据库访问
这样后面继续扩展权限、事务、校验时,结构不会乱。
第七步:暴露 HTTP 接口
Section titled “第七步:暴露 HTTP 接口”最后在 Controller 里把这条链路接到 HTTP 上:
import tech.smartboot.feat.cloud.RestResult;import tech.smartboot.feat.cloud.annotation.Autowired;import tech.smartboot.feat.cloud.annotation.Controller;import tech.smartboot.feat.cloud.annotation.PathParam;import tech.smartboot.feat.cloud.annotation.RequestMapping;import tech.smartboot.feat.cloud.annotation.RequestMethod;
@Controllerpublic class UserController {
@Autowired private UserService userService;
@RequestMapping("/users") public RestResult<List<User>> getAllUsers() { return RestResult.ok(userService.findAll()); }
@RequestMapping("/users/{username}") public RestResult<User> getUserByUsername(@PathParam("username") String username) { User user = userService.findByUsername(username); return user != null ? RestResult.ok(user) : RestResult.fail("User not found"); }
@RequestMapping(value = "/users", method = RequestMethod.POST) public RestResult<String> createUser(User user) { return userService.insert(user) ? RestResult.ok("User created successfully") : RestResult.fail("Failed to create user"); }}到这一步,链路已经完整了:
HTTP -> Controller -> Service -> Mapper -> DB
怎么验证这套链路
Section titled “怎么验证这套链路”启动 demo/mybatis 后,可以先验证读接口:
curl http://localhost:8080/userscurl http://localhost:8080/users/featcurl http://localhost:8080/users/role/admin再验证写接口:
curl -X POST http://localhost:8080/users \ -H 'Content-Type: application/json' \ -d '{"username":"new_user","password":"123456","desc":"created from docs","role":"user"}'如果这些请求都能返回合理结果,说明:
- Feat Cloud 启动成功
- MyBatis 配置被正确读取
- 初始化 SQL 生效
- Mapper / Service / Controller 整条链路都打通了
一个重要的认识
Section titled “一个重要的认识”在 Feat Cloud 里,MyBatis 集成的体验更像“编译期接线”而不是“运行时手工拼装”。
这也是它和很多传统 Spring/MyBatis 示例在阅读感受上的区别。
接口能启动,但一访问就报数据库相关错误
Section titled “接口能启动,但一访问就报数据库相关错误”优先检查:
feat.yaml里的feat.mybatis.path是否指向了真实文件mybatis-config.xml里的 mapper 包是否正确schema.sql是否真的被打进了资源目录
查不到初始化数据
Section titled “查不到初始化数据”优先检查:
feat.mybatis.initial-sql是否写对- SQL 脚本是否在启动时成功执行
- 你当前使用的是否真的是同一个数据源配置
为什么文档不推荐一上来就讲多数据源
Section titled “为什么文档不推荐一上来就讲多数据源”因为大多数第一次接入的人还没把“单数据源链路”走通。
先把单条 CRUD 线打通,再讨论多数据源,排错成本更低。
- CloudOptions 配置指南:继续理解 Cloud 启动阶段的配置能力
- Controller 开发实践:回头补齐控制器层的绑定和映射细节
- 打包与部署:把这套链路带到真实环境里