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(); }
相关推荐
mybatis之接口编程(2)mybatis之接口编程(2)详见http://blog.csdn.net/MyheartMylove/article/details/79496791
Mybatis接口式编程:讲述mybatis如何使用接口与SQL映射文件进行动态绑定并完成增删改查等一系列操作
mybatis中使用接口编程方式实现CRUD模板
Mybatis面向接口编程1
Mybatis系列学习源码 详细学习系列请参考http://www.cnblogs.com/daviddai/p/3485574.html
mybatis有两种实现方式,一种可以通过xml配置文件实现,其二是面向接口编程的实现。本文重点给大家介绍mybatis接口编程的原理,需要的的朋友参考下
JAVA接口自动化测试MyBatis+MySQL实现用例管理
mybatis不需要声明接口调用xml的helloworld的源码
一图读懂 Mybatis执行查询接口流程
Mybatis接口编程方式实现增删改查,具体效果看博文: http://blog.csdn.net/evankaka/article/details/45670527
接口平台代码概览,框架使用springmvc+mybatis
Mybatis系列教程Mybatis插件共8页.pdf.zip
mybatis编程实例,手把手教你学会初步的mybatis编程,里面有详细的开发步骤,有作者的联系方式,有问题的话可以随时联系,有很好的设计模式,和良好的编程习惯,相信读者阅读了会有很大的收获,绝不坑爹!...
Mybatis3和Spring4基于接口编程例子源代码
深入浅出mybatis系列 适合自学、初学者使用
本博客有零基础入门MyBatis,欢迎关注本博客。
spring+mybatis的编码式事务
springboot集成mybatis源码,包含自定义端口,自定义属性获取,访问文件,提供rest接口等内容。适合初学者学习参考。
Mybatis系列课程-Association
基于Springboot+Mybatis打造接口自动化测试框架-全网最新最全最具技术含量的接口自动化测试及框架编写