初遇Mybatis:记录第一天的莫名BUG

初遇Mybatis

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

初印象:

不好使,但感觉很牛逼

使用体验很复杂,数据库、JDBC驱动、Java类、XML文档间需要相互对应,配置文件可读性不够直观,可能是我之前接触XML比较少的缘故。

个人感觉使用它的目的是为了在类结构特别复杂的大型项目中降低耦合度。

一个莫名的BUG

问题复现

跟着教程配置了第一个使用MyBatis的Maven项目,项目结构如下:

mybatis-config.xml中配置mappers:

1
2
3
<mappers>
<mapper resource="mappers/UserMapper.xml" />
</mappers>

UserMapper.xml中建立映射:

1
2
3
<select id="getUser" resultType="User" parameterType="java.lang.String">
SELECT * FROM DBTEST WHERE USER_NAME = #{username}
</select>

UserMapper接口中对应的方法:

1
public User getUser(String username);

在最后的测试类设计了以下方法:

1
2
3
4
5
6
7
8
9
10
11
public static void getUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUser("5284");
System.out.println("username: " + user.getUsername() + "|password: "
+ user.getPassword());
} finally {
sqlSession.close();
}
}

数据表对应SQL语句:

1
2
3
4
CREATE TABLE DBTEST(
USER_NAME VARCHAR(10) PRIMARY KEY;
PASS_WORD VARCHAR(10) NOT NULL;
);

所有步骤执行到这里都是一片祥和,丝毫没有有错误要抛出的迹象。

但IDE还是抛出了一个小小的错误:

显而易见,user是个空对象,getUser方法没有如期获得数据库中的数据(查询返回null)。

验证映射中的查询语句,能够返回正确的结果:

问题描述

  • 配置,语法,代码逻辑无误
  • SQL语句正常查询可以返回正确结果
  • SQL映射返回null

原因分析

查了一圈资料,造成这种情况是因为getUser返回的是一个User BeanUser的属性名与数据表的不一致。

比如用户名这个属性,在User中对应username,而在数据表中则对应USER_NAME

至于更具体的原因是什么,目前还不太清楚,需要继续深入学习(逃)

解决方案

给映射中的SQL语句的查询属性加上别名

1
2
3
4
5
6
<select id="getUser" resultType="User" parameterType="java.lang.String">
SELECT
USER_NAME AS username,
PASS_WORD AS password
FROM DBTEST WHERE USER_NAME = #{username}
</select>

获得了预期的输出!泪目!