关于Mybatis框架的个人总结

来源:互联网 发布:java实现多线程并发 编辑:程序博客网 时间:2024/05/21 15:41

一:什么是Mybatis?
刚学会jdbc的时候,对数据库进行增删改差,都要事先先写一个连接工具类,用来加载驱动、获取数据库连接还有用完关闭连接这些通用操作,就像下面这张图

这里写图片描述

然后操作dao层,增删改差方法每个还要封装一遍,代码重复枯燥,很没意思。
所以为了解决这个问题,由ibatis改进的Mybatis出现了,他让我这样的瓜皮程序员能够不因为太多繁杂重复的代码粗心犯低级错误,直接把jdbc对数据库操作的过程封装起来,只需要写一写SQL语句,配置一下连接信息,万事大吉。

下面是mybatis的内部架构:
这里写图片描述

1.最顶上的SqlMapConfig.xml
就是前面说的要配置连接信息之类的文件,我们把数据库连接等信息放在这里,还有就是mybatis的运行环境之类的

2.SqlSessionFactory
意思是会话工厂(这里可以小小的涉及一下设计模式的工厂模式),没错,工厂工厂,就是生产东西的,这里也就是生产了会话SqlSession买这个SqlSession拿来做什么呢,接下来看。(顺便说一下,这个工厂是重量级的,用单例模式创建)

3.SqlSession和Executor
我印象里记得只有SqlSession,其实SqlSession只是打开了数据库,真正与数据库交互的也就是真正操作数据库的是Executor
mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器

4.Mapped Statement
Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一Mapped Statement对象,sql的id即是Mapped statement的id

二:常见配置

1.自定义别名

在SqlMapConfig.xml中配置:<typeAliases>    <!-- 单个别名定义 -->    <typeAlias alias="user" type="com.mybatis.po.User"/>    <!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->    <package name="com.mybatis.po"/>    <package name="其它包"/></typeAliases>

2.写SQL语句中,#{}与${}的区别

使用占位符#{}可以有效防止sql注入,在使用时不需要关心参数值的类型,mybatis会自动进行java类型和jdbc类型的转换。#{}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

和#{}不同,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如parameterType传输单个简单类型值,${}括号中只能是value。使用${}不能防止sql注入,但是有时用${}会非常方便,如下的例子:

<!-- 根据名称模糊查询用户信息 -->    <select id="selectUserByName" parameterType="string" resultType="user">       select * from user where username like '%${value}%'    </select>

如果本例子使用#{}则传入的字符串中必须有%号,而%是人为拼接在参数中,显然有点麻烦,如果采用${}在sql中拼接为%的方式则在调用mapper接口传递参数就方便很多。

3.动态SQL
这里引用网上大佬的网站
http://www.cnblogs.com/dongying/p/4092662.html

4.延迟加载(懒加载)

需要查询关联信息时,使用mybatis延迟加载特性可有效的减少数据库压力,首次查询只查询主要信息,关联信息等用户获取时再加载。

作用:
当需要查询关联信息时再去数据库查询,默认不去关联查询,提高数据库性能。
只有使用resultMap支持延迟加载设置。

场合:
当只有部分记录需要关联查询其它信息时,此时可按需延迟加载,需要关联查询时再向数据库发出sql,以提高数据库性能。
当全部需要关联查询信息时,此时不用延迟加载,直接将关联查询信息全部返回即可,可使用resultType或resultMap完成映射。

那么,不使用mybatis提供的延迟加载功能是否可以实现延迟加载?

实现方法:
针对订单和用户两个表定义两个mapper方法。
1、订单查询mapper方法
2、根据用户id查询用户信息mapper方法
默认使用订单查询mapper方法只查询订单信息。
当需要关联查询用户信息时再调用根据用户id查询用户信息mapper方法查询用户信息。

所以,感觉平时用到延迟加载的地方不多,了解知道这个知识应该就好吧

5.查询缓存

mybatis框架、一二级缓存

这里写图片描述

从这个图也可以看出来
Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

一级缓存区域是根据SqlSession为单位划分的。
每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。
每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。

开启二级缓存:

<setting name="cacheEnabled" value="true"/>