MyBatis之Mapper动态代理开发

1.SqlSession的使用范围

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

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

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

2.MyBatis开发DAO的方式

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

2.1原始dao的开发方式

程序员须要编写dao接口:和dao接口的实现类:安全

而后就能在测试类中使用。测试类代码以下:mybatis

咱们来看看这种方式开发有什么问题?架构

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

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

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.

1
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也能够是简单类型)传入进去。
相关文章
相关标签/搜索