文章目录
一、什么是 Mybatis ?
Mybatis是一个orm类型的半自动框架,执行了对JDBC的封装,是一个持久层框架,它可以通过XML文件或者注解来配置原生信息,不在需要去做更多繁琐重复的过程,如创建连接,加载驱动!
ORM 思想:
Object Relational Mappging 对象关系映射
简单的说:
就是把数据库表和实体类及实体类的属性对应起来
让我们可以操作实体类就实现操作数据库表。
二、Mybatis 优缺点及使用场合
优点:
- 基于SQL语句编译,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
- 与JDBC相比,减少了50%的代码,消除了JDBC大量冗余的代码,不需要手动开关连接;
- 很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)
- 能够与Spring很好的集成
- 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护
缺点:
- SQL语句的编写工作量较大,尤其字段多,关联表多时,对开发人员编写SQL语句的功底有一定要求!
- SQL语句依赖于数据库,导致数据库的移植性差,不能随意更换数据库。
适用场合:MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案,对性能要求很高,或者需求变化较多的项目,如互联网项目
三、#{}和${}的区别是什么?
(1)${}
表示拼接 sql 串,通过${}
可以将语句传入的内容拼接在 sql 中
<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="mybatis.domain.User">
select * from user where username like '%${value}%'
</select>
(2)Mybatis在处理#{}
时,会对sql语句进行预处理,将sql中的#{}
替换为?
号,调用PreparedStatement
的set
方法来赋值;
四、mappers 映射器对应的Dao接口的工作原理?
我们的 Dao 接口并没有实现类,调用它的时候,具体是怎么执行到我们的 SQL 语句的?
配置文件配置package 标签,会将对应包路径下的所有dao 类注册到 Spring 容器中,当我们通过注解注入这个 dao 接口时,返回的是一个 Dao 接口的代理对象,这个代理对象的处理器是 MapperProxy对象,所以通过@Autowired
注入Dao接口的时候,注入的就是这个代理对象,我们调用到Dao接口的方法时,则会调用到MapperProxy对象的invoke()
方法。
代理对象会拦截接口方法,根据类的全限定名+方法名
,唯一定位到一个 MapperStatement
并调用执行器执行所代表的sql,然后将sql执行结果返回。
Mapper 接口里的方法,不能重载,因为是使用 “全限名+方法名” 的保存和寻找策略
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace确定该方法是在哪个dao接口-->
<mapper namespace="mybatis.dao.UserDao">
<!--查询所有用户-->
<!--id 表示方法名称,resultType 表示要封装到哪里去-->
<select id="findAll" resultType="mybatis.domain.User">
select * from user
</select>
<!--保存用户-->
<insert id="saveUser" parameterType="mybatis.domain.User">
insert into user(username,birthday,sex,address)
values (#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
五、Mybatis 的一级和二级缓存
缓存:
(1)一级缓存:SqlSession 级别的缓存
(2)二级缓存:mapper 级别的缓存
(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开启了二级缓存,则只根据配置判断是否刷新。
六、Mybatis 的 Mapper 接口调用要求
(1)Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
(2) Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
(3)Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
(4) Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径
<!--namespace确定该方法是在哪个dao接口-->
<mapper namespace="mybatis.dao.UserDao">
<!--根据id查询-->
<select id="findById" parameterType="int" resultType="mybatis.domain.User">
select * from where id = #{uid};
</select>
</mapper>
七、resultMap 和 resultType
(1)resultType
(2)resultMap
<resultMap id="userMap" type="mybatis.domain.UserTest">
<!--主键字段的对应-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="name"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
八、Mybatis 实现批量插入
配置useGeneratedKeys
和keyProperty
就可以批量插入并返回主键了
<insert id="batchInsertCameras" useGeneratedKeys="true" keyProperty="cameraNo">
insert into camera (chanIndex,cameraName)
values
<foreach collection="list" item="c" separator=",">
(#{c.chanIndex},#{c.cameraName})
</foreach>
</insert>
具体可参考:mybatis批量插入并返回主键