设为首页 收藏本站
查看: 605|回复: 0

[经验分享] Mybatis系列(六)接口式编程

[复制链接]

尚未签到

发表于 2016-11-26 07:55:51 | 显示全部楼层 |阅读模式
Mybatis系列之接口式编程

引言
  在前面的文章《Mybatis系列之简单示例》曾有一段代码涉及到了接口式编程,当时并没有展开阐述,今天我们单独把这一段拿出来表一表。
  在讲Mybatis接口式编程之前,我们先回忆一下前面是如何调用映射文件中的SQL代码的。通常情况下,都是使用SqlSession实例的selectXXX(selectOne, selectList, selectMap)方法来执行映射文件中相应的SQL语句的,这些方法都有一个共同的特征,那就是第一个参数都是String类型的,我们需要使用这个参数明确告之Mybatis我们是需要执行映射文件的哪一个元素下的SQL语句,所以这个参数内容应该是映射文件的名称空间加上相应元素的id值,如:

Object obj = session.selectOne("com.emerson.learning.mapping.user.getByID", 240);
User user = (User)obj;
... ...
  这条语句告诉我们,要在名称空间com.emerson.learning.mapping.user下查找一个id为getById的元素,并执行其SQL语句。在获取返回值之后,我们还需要对其进行强类型转换。
  这里存在一些潜在的问题:


  • 为了确保名称空间的唯一性,通常会使用相对较长的、且有一定含义的字符串来作为其值,这样就很难保证我们在代码不出现拼写错误的情况,即使是直接从映射文件拷贝过来的,也存在不经意间被修改的可能性;
  • 从selectXXX方法的签名可以看到,她的第二个参数是Object类型,那么如果我们传入的参数类型与映射文件中由parameterType属性指定的类型不一致时,将会出现不可预知的错误
  • 同样,selectXXX方法返回值使用了泛型,我们须确保用于接收其返回值的变量类型与映射文件中属性resultType指定的类型相一致
  Mybatis规避上述风险的手段,我们称之为接口式编程,也就是我们今天的主题。

定义代理接口
  接口式编程,我们可以简单的理解为Mybatis为映射文件定义了一个代理接口,以后全部通过这个接口来和映射文件交互,而不再是使用以前方法。
  映射文件如何知道自己被哪个接口代理呢?这里就是通过名称空间来实现的,映射文件的名称空间再也不是随心所欲的定义的了,而是要使用代理接口的全限定名作为其名称空间。所谓全限定名,就是接口所在的包名加上接口名称。

<mapper namespace="com.emerson.learning.dao.ICommunicatorDao">
<select id="getById" parameterType="int" resultType="Communicator">
select * from communicator where communicator_id=#{id}
</select>
<select id="getAll" resultType="Communicator">
select * from communicator order by communicator_name
</select>
</mapper>
  接口定义好了,那么如何将映射文件中的select / insert / update / delete 等元素与代理接口中的方法绑定呢?其实很简单,只需要在代理接口中定义一些方法,并以相应元素的id属性值做为方法名,parameterType属性值做为方法参数类型,属性resultType值做为方法的返回值即可。下面定义的两个方法就分别对应上面映射文件中的两个select元素。

public interface ICommunicatorDao {
public Communicator getById(int id);
public List<Communicator> getAll();
}
  有些朋友会问了,接口定义好了,是不是还要再定义一个实现类呢?答案是否定的。Mybatis会使用动态代理机制来帮助我们完成额外的工作,我们需要做的就是把这个接口注册到Mybatis中。在Mybatis的总配置文件中,加入如下语句。

<mappers>
<mapper class="com.emerson.learning.dao.ICommunicatorDao" />
</mappers>
  这样,我们就可以在Java代码中直接调用我们定义的代理接口中的方法了。

@Test
public void testGetById() {
SqlSession session = sqlSessionFactory.openSession();
try {
ICommunicatorDao cp = session.getMapper(ICommunicatorDao.class);
Communicator c = cp.getById(1);
if (null == c) {
System.out.println("the result is null.");
} else {
System.out.println(c);
}
} finally {
session.close();
}
}
@Test
public void testGetAll() {
SqlSession session = sqlSessionFactory.openSession();
try {
ICommunicatorDao cp = session.getMapper(ICommunicatorDao.class);
List<Communicator> list = cp.getAll();
for (Communicator c : list) {
System.out.println(c);
}
} finally {
session.close();
}
}
  是不是很简单,而且代码看上去比之前的要简洁了许多。
  接口式编程与之前的调用方式相比较,有以下优点:


  • 调用方法明确,因为我们调用的是接口中的某个具体方法,而不再是通过一个字符串来指定执行映射文件中的某个SQL语句了
  • 传入参数和返回值都不再是Object了,这样就可以在代码编写阶段确保传入的参数类型是正确的,也不再需要对返回值进行强类型转换了
  • 最主要的一点,就是将来Mybatis遇到了Spring,更能发挥出接口式编程的强大潜力。

使用注解
  在Mybatis3.0之后,加入了更强的注解功能。如果不需要使用到较复杂的SQL语句,可以直接把映射文件省去,直接在Java代码中使用注解的方式指定SQL语句。这种写法很简洁,但却失去了映射文件的灵活性。

public interface ICommunicatorDao {
@Select("SELECT * FROM communicator WHERE communicator_id=#{id}")
public Communicator getById(@Param(value = "id") int id);
@Select("SELECT * FROM communicator ORDER BY communicator_id")
public List<Communicator> getAll();
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-305630-1-1.html 上篇帖子: [安全] MyBatis如何防止SQL注入 下篇帖子: SpringMVC与Mybatis集成开发环境搭建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表