之前对于持久层的开发,都是写DAO接口,再写DAO实现类,而还未学习mybatis之前就了解到不用写dao实现类,只需要写接口就行了,还是挺让人好奇它的实现方式的。
mapper代理的方式:
只需要写dao接口,dao接口实现对象由mybatis自动生成代理对象。
本身dao在三层架构中就是一个通用的接口。惯例还是先“诋毁”一下其他方法
原始dao开发方式的问题
1 dao的实现类中存在重复代码,整个mybatis操作的过程代码模板重复(先创建sqlsession、调用sqlsession的方法、关闭sqlsession)
2、dao的实现 类中存在硬编码,调用sqlsession方法时将statement的id硬编码。
mapper开发规范
要想让mybatis自动创建dao接口实现类的代理对象,必须遵循一些规则:
1、mapper.xml中namespace指定为mapper接口的全限定名
此步骤目的:通过mapper.xml和mapper.java进行关联。
2、mapper.xml中statement的id就是mapper.java中方法名
3、mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致
4、mapper.xml中statement的resultType和mapper.java中方法返回值类型一致.
返回值的问题
如果方法调用的statement,返回是多条记录,而mapper.java方法的返回值为pojo,此时代理对象通过selectOne调用,由于返回多条记录,所以报错:
典型错误:
org.apache.ibatis.exceptions.TooManyResultsException:Expected one result (or null) to be returned by selectOne(), but found: 4
resultType与resultMap的区别:
先给出一个sql语句:
select id id_,username username_,birthday birthday_ from user where username like '%${userCustom.username}%'
resultType :指定输出结果的类型(pojo、简单类型、hashmap..),将sql查询结果映射为java对象 。
使用resultType注意:sql查询的列名要和resultType指定pojo的属性名相同,指定相同属性方可映射成功,如果sql查询的列名要和resultType指定pojo的属性名全部不相同,list中无法创建pojo对象的。
resultMap:将sql查询结果映射为java对象。
如果sql查询列名和最终要映射的pojo的属性名不一致,使用resultMap将列名和pojo的属性名做一个对应关系 (列名和属性名映射配置)这种情况下,使用resultMap时需在mapper.xml中进行配置:
这里用到了动态sql的内容。(实际上就是sql的拼接,更为灵活的解析与处理sql语句,mybatis重点之一)
因为做项目时会用到多表,建议一个表使用一个sql片段,接着在where中使用include标签包含就行了。