MyBatis学习笔记(三)Mapper动态代理开发

转载自:MyBatis之Mapper动态代理开发


1.SqlSession的使用范围

1.SqlSessionFactoryBuilder
SqlSessionFactoryBuilder是以工具类的方式来使用:需要创建sqlSessionFactory时就new一个 SqlSessionFactoryBuilder

2.sqlSessionFactory
正常开发时,以单例方式管理sqlSessionFactory,整个系统运行过程中sqlSessionFactory只有一个实例,将来和Spring整合后由Spring以单例方式管理sqlSessionFactory

3.SqlSession
SqlSession是一个面向用户(程序员)的接口,程序员调用 SqlSession接口的方法进行操作数据库。那么我们会思考:SqlSession能否以单例方式使用???由于 SqlSession是线程不安全的,所以 SqlSession最佳应用范围在方法体内。也就是说在方法体内定义局部变量 SqlSession的对象来使用。


2.MyBatis开发DAO的方式

我们先来看看MyBatis原始开发dao的开发方式,发现原始开发的问题,然后再来看看MyBatis使用mapper动态代理开发dao的方式(也是MyBatis目前使用的开发dao的方式)。

2.1原始dao的开发方式

程序员需要编写dao接口:
这里写图片描述
和dao接口的实现类:
这里写图片描述
然后就能在测试类中使用。测试类代码如下:
这里写图片描述
我们来看看这种方式开发有什么问题?

  • 1.dao的实现类中存在重复代码,整个mybatis操作的过程代码模板重复(都是先创建sqlSession、调用sqlSession的方法、关闭sqlSession)。
  • 2.dao的实现类中存在硬编码,调用sqlSession方法时将statement的id硬编码。

下面我们看看mapper动态代理的方式。

2.2mapper动态代理的方式

这种方式下程序员只需要写dao接口,dao接口实现对象由mybatis自动生成代理对象。因为本身dao在三层架构中就是一个通用的接口。

2.2.1mapper开发规范

要想让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中方法的返回值类型一致。

采用这种方式后,我们便可将第一篇文章中提到的User.xml改为UserMapper.xml。文件目录如下:

这里写图片描述
其中有些类我们会在后面用到。

2.2.2mapper.xml(映射文件)

mapper映射文件的命名方式建议表名加Mapper.xml,namespace指定为mapper接口的全限定名。
这里写图片描述

2.2.3mapper.java接口

mybatis提出了mapper接口,相当于dao接口,mapper接口的命名方式建议为表名加Mapper.

public interface UserMapper{};
2.3.4将mapper.xml在SqlMapConfing.xml中进行注册
<mappers>
 <mapper resource="mapper/UserMapper.xml"/>
</mappers>
2.3.5mapper接口返回单个对象和集合对象

在UserMapper.java中添加如下两个方法:
这里写图片描述

对于UserMapper.xml,不管查询记录是单条还是多条,在statement(即UserMapper.xml)中的resultType都定义一致,都是单条记录映射的pojo类型。

而对于UserMapper.java接口方法中的返回值,如果返回的是单个对象,返回值类型是pojo,生成的代理对象内部会自动通过selectOne获取记录,如果返回值类型是多条对象,生成的代理对象内部会自动通过selectList获取记录。

测试代码如下:

这里写图片描述

使用Mapper代理方式进行开发,使程序员只需要关注UserMapper.java接口中的方法,它的实现类由Mapper自动为我们生成,带来了很大的方便。但这种方式也有它的弊端。

2.3.6mapper代理开发的问题
  • 1.返回值的问题:如果方法(即UserMapper.java接口中的方法)调用的statement中返回是多条记录,而mapper.java方法的返回值为pojo,此时代理对象通过selectOne调用,但由于返回的是多条记录所以会报错:Expected one result (for null ) to be returned by selectOne() but found 4;
  • 2.输入参数的问题:使用mapper代理的方式开发,mapper接口方法的输入参数只有一个,可扩展性是否很差?答:可扩展性没有问题,因为dao层就是通用的,可以通过扩展pojo(定义pojo包装类型,后面第四篇文章–MyBatis输入输出映射会讲扩展pojo的知识)来将不同的参数(可以是pojo也可以是简单类型)传入进去。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值