三分钟了解什么是MyBatis
一.MyBatis介绍
1.简介
MyBatis 是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis 可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(n Plain d Old a Java Objects ,普通的 a Java 对象)映射成数据库中的记录。
mybatis不是一个完全的orm框架,Mybatis需要程序员自己写 sql,但是也存在映射(输入参数映射,输出结果映射), 学习门槛 s mybatis 比hibernate低;同时灵活性高,特别适用于业务模型易变的项目,使用范围广。
简单概括:更加简化jdbc代码,简化持久层,sql 语句从代码中分离,利用反射,将表中数据与java bean属性一一映射即ORM(Object Relational Mapping 对象关系映射).
二、MyBatis 功能架构图
1.架构图
2.架构图解析
mybatis 的功能架构分为三层:
API 接口层:提供给外部使用的接口API,开发人员通过这些本地 API 来操纵数据库。接口层接收到调用请求就会调用数据处理层来完成具体的数据处理。
数据处理层:负责具体的 SQL 查找、SQL 解析、SQL 执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
三、MyBatis 框架体系结构
1、Configuration-mybatis 配置
1)、与 spring 一样,可以通过配置文件或注解的形式进行配置;
2)、 SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis 的运行环境等信息;
3)、mapper 文件即sql映射文件,文件中配置了操作数据库的sql 语句。 此文件需要在SqlMapConfig.xml 中加载。
4)、有了配置文件后,通过mybatis环境等配置信息构造 SqlSessionFactory即会话工厂
5)、由会话工厂创建sqlSession 即会话,操作数据库需要通过 sqlSession 进行
6)、sqlSession 使用 Executor(数据库操作执行器口)操作数据库,同Executor 具体实现类实现指定 dao 层数据访问操作
四、Mybatis 环境搭建
1.新建maven项目
与spring建立项目一致
2.配置依赖文件pom.xml
2.Resources资源包下的文件配置
(1)添加log4j日志文件.
在 src/main/resources 资源包下添加 log4j 日志输出properties 文件,便于查看日志输出信息
(2) 添加数据库连接信息文件
(3) 添加mybatis.xml文件
(4) 映射文件添加
在main-àjavaà包下新建mapper映射文件UserMapper.xml
该文件主要用来写SQL语句的,
注意:该文件必须有一个借口与之对应,并且必须和该文件写在同一个包下
3.代码编写
(1) UserMapper.xml文件中书写SQL语句.
(2)UserMapper接口写方法
方法名与xml文件中的id属性名保持一致
(4).Dao层实现接口重写方法
(5).测试类
4. typeAliases别名
若有注解,则别名为其注解值。注解名 @Alias(value=“user”)
别名à映射的类型
_byteàByte;_longàLong;_shortàShort;_intàInt; _integeràInt;_doubleàDouble;_floatàFloat;_booleanàBoolean;stringàString;byteàByte;longàLong;shortàShort;
intàInteger;integeràInteger;doubleàDouble; floatàFloat
booleanàBoolean;dateàDate;decimalàBigDecimal
5.配置环境
尽管可以配置多个环境,每个 SqlSessionFactory 实例只能选择其一。
五. mappers 映射器
1. sqlmapper 配置文件路径
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
2.绝对路径形式
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
3.接口列表配置形式注解sql
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
4.映射包下所有接口
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
六、Mapper Xml映射文件
1. Select 元素标签使用
输入参数分类
基本类型,字符串,java bean,map,数组(删除操作时体现),List(添加时体现)等每种情况定义如下
1), <!-- 输入参数为基本数据类型 -->
<select id="queryUserById" parameterType="int" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
2) <!-- 每条结果类型为 实体 最终结果为多条记录 list 结果 -->
<select id="queryUserByName" parameterType="string" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user
where user_name like concat("%",#{userName},"%")
</select>
3) <!-- 输入参数为 map 类型 -->
<select id="queryUserByMap" parameterType="map" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
4) <!-- 输入参数为 java bean 类型 -->
<select id="queryUserByUser" parameterType="user" resultType="user">
select id,user_name as userName,user_pwd as userPwd from user where id=#{id}
</select>
2.Insert 元素标签使用(四种添加配置篇幅限制)
1)添加记录不返回主键配置
<insert id="addUserNoKey" parameterType="User">
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
2)添加记录返回主键 1(属性配置)
<insert id="addUserHasKey" parameterType="user">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID() as id
</selectKey>
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
Oracle 情况
<selectKey resultType="int" order="BEFORE" keyProperty="id">
SELECT LOGS_SEQ.nextval AS ID FROM DUAL
</selectKey>
3)加记录返回主键 2(属性配置)
<insert id="addUserHasKey2" parameterType="user" useGeneratedKeys="true"keyProperty="id">
insert into user(user_name,user_pwd) values(#{userName},#{userPwd})
</insert>
4)批量添加记录返回影响总记录行数(属性配置)
<insert id="addUserBatch" parameterType="list" >
insert into user(user_name,user_pwd) values
<foreach collection="list" item="item" separator=",">
(#{item.userName},#{item.userPwd})
</foreach>
</insert>
3.Update 元素标签使用
1)更新单条记录返回影响行数
<!-- 更新单条 -->
<update id="updateUser" parameterType="User">
update user set
userName=#{userName} ,userPwd=#{userPwd} where id=#{id}
</update>
2)批量更新多条记录 属性配置
<update id="updateUserBatch" parameterType="java.util.Map">
update user set userPwd=#{pwd}
where id in
<foreach collection="ids" item="item" open="(" separator=","
close=")">
#{item}
</foreach>
</update>
4.Delete 元素标签使用
1)删除单条记录
<delete id="delUserById" parameterType="int">
delete from user where
id=#{id}
</delete>
2)批量删除多条记录(属性配置)
<delete id="delUserBatch" parameterType="java.util.Map">
delete from user where
id in
<foreach collection="ids" item="item" open="(" separator=","
close=")" index="index">
#{item}
</foreach>
</delete>
或下列形式,入参为数组类型
<delete id="deleteUserBatch2" >
delete from user where id in
<foreach collection="array" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
九.动态sql语句
1.简介
MyBatis的强大特性之一便是它的动态SQL。如果你有使用JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接SQL语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态SQL这一特性可以彻底摆脱这种痛苦。它借助ognl(类似于jsp 里面的el表达式)表达式来完成动
态 sql 的拼接使得非常简便。
2.if条件判断
<!-- 模糊匹配 -->
<select id="queryUserByUserName" parameterType="map"
resultType="user">
select id,userName,userPwd from user where 1=1
<if test="userName!=null and userName!=''">
and userName like '%${userName}%'
</if>
</select>
2.choose, when, otherwise 选择器使用
我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句
< select id="queryUserByParams" parameterType="map" resultType="user">
select id,userPwd
<choose>
<when test="nation!=null and nation!=''">
,userName
</when>
<otherwise>
,realName
</otherwise>
</choose>
from user
where userName like '%${userName}%'
<if test="phone!=null and phone!=''">
and phone like '%${phone}%'
</if>
</select>
这条语句的意思就是说 如果我传进 nation 不为空就查 userName 的值, 否则是realName 的值
3.trim, where, set
前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题, 然后我们再来看第一条的配置
<select id="findUserByUserName" resultMap="RM_User" >
select
userId, userName, password from user where
userName like '%${userName}%'
<if test="phone != null and phone != ''" >
and phone like '%${phone}%'
</if>
</select>
如果我把 userName like '%${userName}%'这个语句也用if做个判断
<select id="findUserByUserName" resultMap="RM_User" >
select
userId, userName, password from user where
<if test="userName != null and userName != ''" >
userName like '%${userName}%'
</if>
<if test="phone != null and phone != ''" >
and phone like '%${phone}%'
</if>
</select>
这样的话我们预测一下 打印的sql应该是
select userId, userName, password from user where
很明显这条sql会报错
那为了解决这个问题呢, 我们使用<where></where>标签
<select id="queryUserByParams" parameterType="map" resultType="user">
select id,userPwd,phone
<choose>
<when test="nation!=null and nation!=''">
,userName
</when>
<otherwise>
,realName
</otherwise>
</choose>
from user
<where>
<if test="userName !=null and userName !=''">
userName like '%${userName}%'
</if>
<if test="phone!=null and phone!=''">
and phone like '%${phone}%'
</if>
</where>
4.foreach
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建IN条件语句或者是批量插入 。