1.Mybatis的介绍
前面我们说使用JDBC连接池可以节省内存,不用每次都去创建和销毁,并且把配置文件抽取出来。但是还是需要我们去人为指定参数类型、下标、值,得到的结果还需要我们去遍历,还有sql语句的硬编码都是比较麻烦的。这个时候就有一些针对JDBC封装的框架出现了,而今天要介绍的是其中的一种Mybatis。他是一个持久层的框架,包含SQL Maps和Data Access Objects。其实就是解决我上述所说的那两个问题。
2.Mybatis的使用
在没有介绍Spring boot之前,我们还是使用的xml配置,第一步我们编写一个核心的配置文件mybatis-config.xml,先引入约束信息,这个可以从官网拷贝;第二步在配置文件里写入指定驱动类名、指定连接地址、指定用户名、指定的密码和对应的映射文件名;第三步可以编写对应的映射文件,这个也是需要引入约束信息,可以从官网拷贝,写入指定的命名空间namespace,在指定的命名空间里写入SQL语句;接下来就可以使用之间介绍的junit单元测试一下,测试的流程:第一步加载mybatis核心配置文件,第二步创建SqlSessionFactory,第三步获取SqlSession,第四步使用selectOne方法执行SQL语句,获得结果,处理异常并释放资源。关于他的执行流程下面有一张表可以很好的展现。

3.配置日志信息
在刚才的单元测试方法,我们发现控制台没有任何的日志信息输出,这时候就需要我们配置日志的环境,在网上找一个完整的log4j的文件并导入项目的配置,在执行的单元测试的类上加入注解。在后面的spring boot的项目里,我们只用在pom文件里导入slf4j即可。
4.Mybatis配置多环境
Mybatis其实是可以配置成适应多种环境,但是每个SqlSessionFactory实例只能选择其一,第一步在Mybatis的配置文件里加入environments的标签,标签里加入default参数指向一个环境,默认为环境的id;第二步在environment标签里配置一个具体的环境,标签里的id为一个具体环境的id;第三步添加transactionManager标签指定事务的类型;第四步使用dataSource标签配置数据源,标签里type属性指定数据源类型。下面来个实例图。


5.settings设置
在实际的操作中,有时候解决数据库中列名有下划线而不能映射到属性的问题,这个时候就需要我们开启开启驼峰匹配,使用settings设置可以完成这一步,下图是一个实例。



6.parameterType参数类型
我们在xml里写sql语句的时候,会有传入和传出参数的问题,parameterType有三种类型的输入参数,基本数据类型、hashMap和pojo包装类。如果是传入基本数据类型的时候,语句中占位符的值写什么变量名都可以,mybatis会自动给赋值,如果使用if语句时,会报错,使用parameter或者value就可以了。如果使用pojo类型或者是hashMap的时候,简单类型通过#{key},复杂类型通过{key.属性名}或者#{key.属性名}。
7.sql片段
在我们经常对一张表进行操作的时候,每写入一个sql语句,都要加上要操作的表的字段,很多时候就会变得很冗余。这个时候可以使用sql标签可以定义一个sql片段,再需要用到该sql片段的地方,用include标签引入。当同一个sql片段可能在很多个mapper文件里都有使用,这个时候就要添加一个映射文件,来统一管理sql片段。
8.动态代理Mapper实现类
当我们实际使用mybatis的时候,每个模块都需要编写一个接口及对应的实现类,并且还需要编写一个Mapper文件,特别的麻烦,这里我提供两种解决办法。第一种是使用idea的插件-Mybatis datasource。这是一个根据表或者mapper接口等自动生成xml文件和sql语句的插件,使用起来很方便。第二种办法是使用Mybatis的动态代理,使用这种方法要满足以下几个要求,第一个映射文件中的namespace必须和接口的全路径名一致;第二个是映射文件的statementId必须和接口中方法名一致;第三个是映射文件中的resultType必须和接口中方法的返回类型一致;第四个是映射文件中的parameterType必须和接口中方法的形参类型一致。(不一定,因为parameterType可以省略)
9.面试题:#和$符号的区别
有时候我们去面试的时候,会被问到#和$的区别。我总结了一下有以下四点区别:第一个#是预编译方式,而另一个是直接拼接;第二点#不需要关注数据类型,mybatis实现自动数据类型转换;另一个不做数据类型转换,需要自行判断数据类型;第三点#可以防止sql注入;另一个不能防止sql注入;第四点如果只有一个参数,默认情况下,#{}中可以写任意的名字;另一个中只能用value来接收。
10.其他问题
1.当多表查询的时候,实体类的改造;2.resultMap的继承;3.延迟加载;4.如果sql语句中出现<的解决方案;最后给大家一张Mybatis的总结图
