说明 :本文基于新增
MyBatisUtil工具类,演示如何通过三种不同方式将数据库查询结果映射为 Java 对象集合。随着项目代码量增加,未修改的文件不再重复贴出。
一、项目核心结构概览
ClientMapper.xml:定义 SQL 映射MyBatisUtil.java:封装 SqlSession 获取与关闭mybatis-config.xml:MyBatis 全局配置JunitMybatisUtil.java:JUnit 测试用例- 实体类:
TblClient.java(属性名如cid,cname等,与数据库字段id,client_name不一致)
二、三种查询结果映射方式详解
方式一:使用 <resultMap> 手动映射(推荐用于字段不一致或复杂关联)
<resultMap type="com.charles.entity.TblClient" id="tblClientID">
<id property="cid" column="id" />
<result property="cname" column="client_name"/>
<result property="caddress" column="client_address"/>
<result property="cbirthday" column="client_birthday"/>
</resultMap>
<select id="getClientAll" resultMap="tblClientID">
SELECT * FROM tbl_client
</select>
✅ 适用场景:
- 数据库字段名与实体类属性名不一致
- 需要处理一对一/一对多等复杂关联查询
💡 注意:即使使用
resultMap,MyBatis 默认仍会开启 自动映射(autoMapping) ,级别为PARTIAL(仅映射未在 resultMap 中显式声明的字段)。若需完全关闭自动映射,可在<resultMap>中设置autoMapping="false"。
方式二:使用 resultType + SQL 别名(字段名需手动对齐)
<select id="getClientAll" resultType="com.charles.entity.TblClient">
SELECT
id AS cid,
client_name AS cname,
client_address AS caddress,
client_birthday AS cbirthday
FROM tbl_client
</select>
✅ 适用场景:
- 字段数量不多,可通过 SQL 别名对齐
- 不想写冗长的
resultMap
⚠️ 要求:SQL 查询结果的列别名必须与实体类属性名完全一致(区分大小写)。
方式三:使用 resultType + 类型别名(简化全限定类名)
首先在 mybatis-config.xml 中注册别名:
<typeAliases>
<typeAlias type="com.charles.entity.TblClient" alias="baitang"/>
</typeAliases>
然后在 Mapper 中使用别名:
<select id="getClientAll" resultType="baitang">
SELECT
id AS cid,
client_name AS cname,
client_address AS caddress,
client_birthday AS cbirthday
FROM tbl_client
</select>
✅ 优势:
- 减少 XML 中冗长的包路径
- 提高可读性与维护性
🔔 注意:别名默认不区分大小写,但建议统一使用小写以避免混淆。
三、工具类封装:MyBatisUtil.java
package com.charles.util;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static SqlSessionFactory factory = null;
static {
try {
InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/** 获取 SqlSession(默认不自动提交事务) */
public static SqlSession getSqlSession() {
return factory.openSession(false);
}
/** 安全关闭 SqlSession */
public static void closeSqlSession(SqlSession sqlSession) {
if (sqlSession != null) {
sqlSession.close();
}
}
}
四、单元测试验证:JunitMybatisUtil.java
@Test
public void junitUnit() {
SqlSession session = MyBatisUtil.getSqlSession();
try {
List<TblClient> list = session.selectList("com.charles.dao.ClientMapper.getClientAll");
for (TblClient client : list) {
System.out.println(client.getCid() + "\t" +
client.getCname() + "\t" +
client.getCaddress() + "\t" +
client.getCbirthday());
}
} finally {
MyBatisUtil.closeSqlSession(session);
}
}
✅ 最佳实践 :使用
try-finally确保资源一定被释放,避免连接泄漏。
五、总结对比
| 方式 | 是否需要配置 | 适用场景 | 可读性 | 维护成本 |
|---|---|---|---|---|
resultMap |
是 | 字段不一致、复杂映射 | 高 | 中 |
resultType + 别名 |
否 | 简单映射、字段可对齐 | 中 | 低 |
resultType + 类型别名 |
需全局配置 | 同上,但类名较长时更简洁 | 高 | 低 |
如有疏漏,欢迎指正!希望本文能帮助你更好地理解和使用 MyBatis 的结果映射机制。