Mybatis实操遇到的问题-
由selectOne和返回值类型引发的一系列问题
先是一个简单的错误
写了一个简单的测试项目,分为两层:web层和core层,在写core层的DAO操作时候,使用了selecOne方法:
此时为0.1版本代码
- 1
- 2
BaseDaoImpl.java
public Object queryForObject(String sqlId, Map<String, Object> params) {
return getSqlSession().selectOne(sqlId, params);
}
NoticeMapper.xml
<!-- 查询公告列表 -->
<select id="getNotice" parameterType="java.util.Map" resultType="Notice">
select * from notice
<where>
<if test="id!=null">
ID = #{id}
</if>
<if test="content!=null">
and content = #{content}
</if>
<if test="createTime!=null">
and createTime = #{createTime}
</if>
</where>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用的时候查了一下API知道会返回一条查询数据,无数据时候返回null,理解为了Mybatis会自动处理数据,当有多条数据的时候,自动返回第一条数据,但是在测试时候,发现理解错误,当有多条数据时候会直接报错:“selectOne会返回一条结果数据,但是当前结果条数:总计:2”。也就是说selectOne只能处理单条数据,超过一条时就会出现错误,使用此函数哟啊慎用。
由于这个问题引发了一个联想的问题,当数据库没有数据的时候,selectOne的结果会是如何的呢?因此进行了测试,清空了数据表之后进行debug,一步步调试的时候很正常,返回结果为null并没有报错,也就是selectOne的操作可以处理数据为空的清空,但是调试到为了方便查看结果写下的print语句:System.out.println("getnotice"+notice.toString());
时竟然开始报Java错误了,看到错误原因才想到因为notice的结果是null,所以null.toString()就会报Java的错误。
结论:
1.使用selectOne时必须确保返回的结果条数小于等于一条在实际环境中感觉实用性一般。
2.如果需要将selectOne的返回值传递进行操作的话,必须考虑可能的返回null的情况,否则程序就会异常。
引发的第二个问题
由于selectOne使用有问题,而数据库内数据不确定性较大,考虑改为使用List<Map<*,*>>
来接收返回值,因此更新了DAO的操作:
0.2版本 BaseDaoImpl.java
public List<Map<String, Object>> queryForList(String sqlId,
Map<String, Object> param) {
List<Map<String, Object>> list = getSqlSession().selectList(sqlId, param);
List<Map<String, Object>> beans = ConvertUtil.convertSqlMap2JavaMap(list);
return beans;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
在更新完成后,进行测试,依旧报错,debug之后发现犯了低级的错误,在更改了DAO的操作之后没有联动的去更新NoticeMapper.xml文件内容,在0.1版本中select的返回值类型是Notice,需要将其更改为java.util.Map。
0.2版本 NoticeMapper.xml
<!-- 查询公告列表 -->
<select id="getNotice" parameterType="java.util.Map" resultType="java.util.Map">
select * from notice
<where>
<if test="id!=null">
ID = #{id}
</if>
<if test="content!=null">
and content = #{content}
</if>
<if test="createTime!=null">
and createTime = #{createTime}
</if>
</where>
</select>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
结论:每次的修改都要细致的考虑整个逻辑流程,级联更改所有可能涉及的部分。
需要自己深思的地方
-
写代码不能太急,在写的过程中,要细心,保持逻辑清楚。
-
selectOne的问题值得深思,因为返回null时感觉不容易考虑到,所以自己进行简单测试不容易发现,有必要学习一些自动化的测试方法,在完成功能编写后对代码自己先进行测试。