一、什么是MyBatis?
MyBatis是一个基于Java的持久层框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
二、Mybatis动态sql有什么用?
Mybatis的强大特性之一便是它的动态SQL
。在实际开发中,数据库的查询比较复杂,需要在不同的逻辑中执行不同的SQL语句。我们往往要根据各种不同的场景拼接出不同的SQL语句,而Mybatis
给我们提供了动态SQL,可以让我们根据具体的业务逻辑来拼接SQL语句。(Mybatis采用功能强大的基于OGNL的表达式来淘汰其他的大部分元素)
Mybatis动态sql可以在Xml映射文件内,以标签的形式编写动态sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接sql的功能。
Mybatis提供了9种动态sql标签:trim | where | set | foreach | if | choose | when | otherwise | bind。
三、动态标签的使用
1、if条件(简单的条件判断)
if标签判断条件是否符合,如果符合就把sql片段加入到sql语句中。多个if标签需要用and连接。
where元素当只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除。
test属性
test的属性用于条件判断的语句中,它在Mybatis
中广泛使用。它的作用相当于判断真假。在大部分场景中我们都是用它判断空和非空。有时候我们需要判断字符串、数字和枚举等。
<!-- 携带条件查询 查询条数 多个if标签需要用and连接 -->
<select id="selConditionCount" parameterType="java.util.HashMap"
resultType="java.lang.Long">
select count(*) from fruit
<where>
<if test="fruitName !=null and fruitName !=''">
fruitName=#{fruitName}
</if>
<if test="startTime != null and startTime != ''">
and fruitDate >= #{startTime}
</if>
<if test="endTime != null and endTime != ''">
<![CDATA[ and fruitDate <= #{endTime} ]]>
</if>
</where>
</select>
2、choose(选择其中的一项)
在mybatis中if
标签是判断,那么choose
结合when
和otherwhen
标签就是分支判断。
choose标签功能是分支判断,配合when标签与otherwhen标签进行条件过滤。与if标签功能不同的是:if标签是进行一个一个判断,只要匹配就会执行。而choose | when | otherwhen标签则是单个匹配只要有一个配置则会执行匹配的部分,而后面的条件匹配都会被忽略。
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
3、trim(替换和添加)
trim
元素就意味着我们需要去掉一些特殊的字符串,prefix
代表的语句中的前缀,而prefixOverrides
代表的是你需要去掉的那种字符串,我们可以将and替换为where,如下:
<select id="getUser4" resultMap="map">
SELECT * FROM user2
<!--这个语句中是把AND换成where,下面的写法基本与where是等效的-->
<trim prefix="where" prefixOverrides="and">
AND id=1
</trim>
</select>
这个最终执行的sql是 select * from user2 where id = 1;
4、set(主要用于更新)
set是我们在更新表的时候使用的元素,通过set元素,我们可以逐字段的修改一条数据,有了 set 元素就可以动态的更新那些修改了的字段。如下:
<update id="update">
UPDATE user2
<set>
<if test="username!=null">
user_name=#{username},
</if>
<if test="password!=null">
password=#{password}
</if>
</set>
WHERE id=#{id}
</update>
在set元素中,如果遇到了逗号,系统会自动将之去除。
5、foreach(主要用于构建IN条件)
foreach
元素用来遍历集合,他可以在sql中对集合进行迭代。通常可以将之用到批量删除、添加等操作中。
collection
表示传入的参数中集合的名称,index
表示是当前元素在集合中的下标,open
和close
则表示如何将集合中的数据包装起来,separator
表示分隔符,item
则表示循环时的当前元素。
<!-- 批量删除 -->
<delete id="allDelFruit" parameterType="java.util.ArrayList">
delete from fruit where fruitId in
<foreach collection="list" item="fruitId" open="(" close=")" separator="," index="index">
#{fruitId}
</foreach>
</delete>
注意 :你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给*foreach*
作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值
6、bind(预定义变量)
使用bind元素我们可以预先定义一些变量,然后在查询语句中使用,如下:
<select id="getUserByName" resultMap="">
<bind name="un" value="username+'%'"></bind>
SELECT* FROM user2 WHERE user_name LIKE #{un}
</select>
四、为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
五、Mybatis的一级、二级缓存
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),它可以提高对数据库查询的效率,以提高应用的性能。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;
六、Mybatis中<![CDATA[ ]]>的作用
在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用<![CDATA[ ]]>来解决。
如果文本包含了很多的"<"字符 <=和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
这里小于号会跟起始标签冲突,而大于号不会,所以这里才要加这个标签避免被转义。
<where>
<if test="endTime != null and endTime != ''">
<![CDATA[ and fruitDate <= #{endTime} ]]>
</if>
</where>
七、Hibernate 和 MyBatis 的区别
相同点
都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。
不同点
映射关系
- MyBatis 是一个半自动映射的框架,配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单。
- Hibernate 是一个全表映射的框架,配置Java对象与数据库表的对应关系,多表关联关系配置复杂,hibernate可以自动生成SQL语句,自动执行。
SQL优化和移植性
- Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。
- MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工作量相对大些。直接使用SQL语句操作数据库,不支持数据库无关性,但sql语句优化容易。
开发难易程度和学习成本
- Hibernate 是重量级框架,学习使用门槛高,适合于需求相对稳定,中小型的项目,比如:办公自动化系统
- MyBatis 是轻量级框架,学习使用门槛低,适合于需求变化频繁,大型的项目,比如:互联网电子商务系统
总结
MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,
Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。