1.2 环境搭建与第一台完整手术


文档摘要

1.2 环境搭建与第一台完整手术 本节摘要:搭建 MyBatis 运行环境的完整五件套——Maven 依赖、全局配置、库表、实体与映射文件、运行入口。本节以"查出一个用户"为病例,走完背景、操作、结果、解读、变式的全过程,并给出首跑最常见的三类报错对照表。 上一节看清了要替代什么,这一节把替代品装起来。目标很小:往数据库插一条数据再查出来,但五脏俱全。 病例背景 我们维护一个用户模块,表结构如下(MySQL 语法,其他数据库只需调整类型名): 操作分五步:引依赖、写全局配置、建实体、写映射、跑入口。 操作一:引入依赖 Maven 工程在依赖管理中加两样东西:MyBatis 本体与数据库驱动。

1.2 环境搭建与第一台完整手术

本节摘要:搭建 MyBatis 运行环境的完整五件套——Maven 依赖、全局配置、库表、实体与映射文件、运行入口。本节以"查出一个用户"为病例,走完背景、操作、结果、解读、变式的全过程,并给出首跑最常见的三类报错对照表。

上一节看清了要替代什么,这一节把替代品装起来。目标很小:往数据库插一条数据再查出来,但五脏俱全。

病例背景

我们维护一个用户模块,表结构如下(MySQL 语法,其他数据库只需调整类型名):

-- 建表:用户表 CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, -- 自增主键 username VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, created DATETIME DEFAULT CURRENT_TIMESTAMP ); -- 准备一条测试数据 INSERT INTO users (username, email) VALUES ('zhangsan', 'zhangsan@example.com'); -- 执行后确认:SELECT * FROM users; -- id=1, username=zhangsan, email=zhangsan@example.com

操作分五步:引依赖、写全局配置、建实体、写映射、跑入口。

操作一:引入依赖

Maven 工程在依赖管理中加两样东西:MyBatis 本体与数据库驱动。

<!-- 只需两个坐标:框架本体 + 数据库驱动 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.16</version> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.4.0</version> </dependency>

日志实现建议同时引入(如 slf4j 加任意实现),否则你将完全看不到 MyBatis 打印的 SQL——这对调试是致命的,第 6 章排错一节会反复用到它。

操作二:全局配置文件

在资源目录下放全局配置(约定俗成命名为 mybatis-config.xml,内容如下):

<?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> <settings> <!-- 下划线列名自动映射到驼峰属性:created_time -> createdTime --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 控制台打印 SQL 与参数,学习期必开,上生产再收敛 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <environments default="dev"> <environment id="dev"> <!-- 事务交给 JDBC 的 Connection 管理 --> <transactionManager type="JDBC"/> <!-- POOLED:内置连接池,重复利用连接 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis_db?useSSL=false&amp;serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="root123"/> </dataSource> </environment> </environments> <mappers> <!-- 注册映射文件:类路径下的 XML --> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>

三个配置块的分工:environments 管连接到哪个库、用不用池;settings 管框架行为开关;mappers 管"手术方案登记册"——没登记的映射文件等于不存在。

操作三:实体与映射文件

实体类就是普通 Java 类,属性名与列名对齐:

// 实体类:属性与列名一一对应(驼峰对下划线由开关处理) public class User { private Integer id; private String username; private String email; private Date created; // 省略 getter 与 setter:MyBatis 通过反射走 setter 装配属性 }

映射文件的 namespace 必须是接口全限定名,1.5 节会解释为什么:

<?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.example.mapper.UserMapper"> <select id="findById" parameterType="int" resultType="com.example.entity.User"> SELECT id, username, email, created FROM users WHERE id = #{id} </select> </mapper>

配套的接口只声明方法,方法名与语句 id 一致,返回类型与 resultType 对齐:

package com.example.mapper; import com.example.entity.User; public interface UserMapper { User findById(int id); // 与 XML 中 id="findById" 对应 }

操作四:运行入口

// 运行入口:构建工厂 -> 开会话 -> 取代理 -> 执行 -> 关会话 public class Bootstrap { public static void main(String[] args) throws Exception { try (InputStream in = Resources.getResourceAsStream("mybatis-config.xml")) { // 工厂全局只建一次(演示代码写在 main 里) SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); try (SqlSession session = factory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); User u = mapper.findById(1); System.out.println(u); } } } }

结果与解读

控制台输出分两段。第一段是日志(开了 STDOUT_LOGGING 才有):

==> Preparing: SELECT id, username, email, created FROM users WHERE id = ? ==> Parameters: 1(Integer) <== Total: 1

第二段是业务输出:

User{id=1, username='zhangsan', email='zhangsan@example.com', created=...}

解读三件事:日志里的问号证明参数走的是预编译通道(PreparedStatement);Parameters 行显示值与类型,这是参数装配是否正确的直接证据;Total 行是命中行数,为 0 时结果就是 null——它和 SQL 错误是两类不同的问题。

首跑三类高发报错对照表

报错关键词 根因 处置
ClassNotFound(驱动类) 驱动依赖缺失或版本过老 确认驱动坐标;MySQL 8 用 com.mysql.cj.jdbc.Driver
Access denied / Communications link failure 账号密码或地址端口错误、数据库未启动 用命令行客户端先验证连通性,再回填配置
TypeException: Could not resolve type alias resultType 写了短名但未配置类型别名包 写全限定名,或在配置中注册实体所在包
PersistenceException: api 协议错误 URL 少了时区或 SSL 参数(MySQL 8 高发) URL 补 serverTimezone 参数

变式:把 resultType 从全限定名改成 User 短名,并在全局配置加一行 typeAliases 注册实体包——这是生产项目几乎必做的整理。改完重跑,确认行为不变、配置更干净。

⚠️ 常见坑:映射文件放在源码目录而不是资源目录时,Maven 打包不会复制它,报"找不到 XML"。把映射文件放对位置,或在构建配置里声明资源过滤范围。

本节要点回顾

  • 五件套:依赖、全局配置、库表、实体加映射、运行入口,缺一件就有对应形态的报错
  • namespace 即接口全限定名:这是接口与 XML 绑定的第一根缝合线
  • 日志三行:Preparing、Parameters、Total 分别回答"执行了什么、带了什么值、命中几行",是后续一切调试的基线
  • 驼峰开关:mapUnderscoreToCamelCase 解决下划线列名与驼峰属性的天然错位

环境通了,下一节解剖工厂本身:SqlSessionFactory 怎么从这份 XML 长出来,配置块背后各是什么机制。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U