什么是Mybatis

MyBatis 是一款优秀的持久层框架,它支撑自定义 SQL、存储进程以及高级映射。

MyBatis 免除了几乎一切的 JDBC 代码以及设置参数和获取成果集的作业,开发时只需求关注sql语言自身。

MyBatis 能够通过简略的 XML 或注解来配置和映射原始类型、接口和 Java pojo为数据库中的记录。

Mybatis优点

  • 基于SQL句子编程,相当灵敏,不会对应用程序或许数据库的现有设计造成任何影响,SQL写在XML里,免除sql与程序代码的耦合,便于统一管理;提供XML标签,支撑编写动态SQL句子,并可重用。
  • 与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需求手动开关衔接;
  • 很好的与各种数据库兼容(因为MyBatis运用JDBC来衔接数据库,所以只需JDBC支撑的数据库MyBatis都支撑)。
  • 能够与Spring很好的集成;
  • 提供映射标签,支撑目标与数据库的ORM字段联系映射;提供目标联系映射标签,支撑目标联系组件维护。

Mybatis缺陷

  • SQL句子的编写作业量较大,尤其当字段多、关联表多时,对开发人员编写SQL句子的功底有一定要求。
  • SQL句子依赖于数据库,导致数据库移植性差,不能随意更换数据库。

Mybatis下的增修改查

Mybatis下的增修改查有两种常用的办法,即运用注解开发和在xml文件中开发。

运用注解开发

运用注解开发可直接在接口类中的相关函数上编写,用注解编写的增修改查如下:

public interface UserMapper {
    @Select("select * from user")
    List<User> getUsers();
    //办法存在多个参数,一切的参数前面必须加上@Param("id")注解,sql顶用的是注解中的id
    @Select("select * from user where id=#{id}")
    User getUsersById(@Param("id") int id);
    @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{password})")
    int addUser(User user);
    @Update("update user set name=#{name},pwd=#{password} where id=#{id}")
    int uptateUser(User user);
    @Delete("delete from user where id=#{id}")
    int deleteUser(@Param("id") int id);
}

在xml文件中开发

句子相关参数阐明

  • id:对应的接口中的办法名
  • resultType: sql句子履行的返回值类型
  • parameterType:参数类型

在xml文件中开发前需编写对应的接口函数:

//依据ID查询用户
User getUserById(int id);
//增加用户信息
void addUser(User user);
//修改用户信息
void updateUser(User user);
//依据ID删除用户信息
void deleteUser(int id);

然后在xml文件中编写:

<?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" >
<mapper namespace="com.qing.mapper.UserMapper">
     <select id="getUserById" resultType="com.qing.entity.User" parameterType="int">
        select * from mybatis.user where id = #{id}
     </select>
     <insert id="addUser" parameterType="com.qing.entity.User">
        insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd});
     </insert>
     <update id="updateUser" parameterType="com.qing.entity.User">
        update mybatis.user set name=#{name} ,pwd=#{pwd} where id=#{id};
     </update>
     <delete id="deleterUser" parameterType="int">
        delete from mybatis.user where id=#{id};
     </delete>
</mapper>

动态SQL

Mybatis 动态 SQL能够让咱们在 xml 映射文件内,以标签的方式编写动态 sql,完成逻辑判别和动态拼接 sql 的功用。

动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它相似的框架中,开发人员一般需求手动拼接 SQL 句子,依据不同的条件拼接 SQL 句子是一件极端痛苦的作业。它一般是依据用户输入或外部条件动态组合的SQL句子块。 动态SQL能灵敏的发挥SQL强大的功用、便利的处理一些其它办法难以处理的问题。 但是动态SQL有时候在履行功用 (功率)上面不如静态SQL,而且运用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。

Mybatis的九种动态SQL标签

元素 作用 补白
if 判别句子 单条件分支判别
choose(when、otherwise) 相当于 Java 中的 switch case 句子 多条件分支判别
trim(where、set) 辅佐元素 用于处理一些SQL组装问题
foreach 循环句子 在in句子等罗列条件常用
bind 辅佐元素 拼接参数,兼容不同数据库,避免SQL注入

动态SQL标签详解

首先编写一个实体类

@Alias("blog")
@Data
public class Blog {
    private int id;
    private String title;
    private String author;
    private Date createTime;
    private  int views;
}

if标签

if标签:条件判别,依据标签中test特点所对应的表达式决定标签中的内容是否需求拼接到SQL中去。

if 句子运用办法简略,常常与 test 特点联合运用,语法如下:

<if test="判别条件">  SQL句子</if>

编写一个查询博客函数接口:

//查询博客
List<Blog> queryBlogIf(Map map);

xml中动态sql的编写:

<select id="queryBlogIf" parameterType="map" resultType="blog">
    select * from blog where 1=1
    <if test="title != null">
        and title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</select>

在此 SQL 句子中, where 1=1 是多条件拼接时的小技巧, 后边的条件查询就能够都用 and 了。

set标签

set 元素会动态地在行首插入set关键字,并会删掉额定的逗号(这些逗号是在运用条件句子给列赋值时引进的)或许,能够通过运用trim元素来达到相同的作用

示例如下:

<update id="updateBlog" parameterType="map">
    update blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    where id = #{id}
</update>

where标签

where标签

  • 当where标签中有内容时,会自动生成where关键字,而且将**内容前(内容后不可)**剩余的and或or去掉
  • 当where标签中没有内容时,此时 where标签没有任何作用

比如如下:

<select id="queryBlogIf" parameterType="map" resultType="blog">
    select * from blog    
    <where>        
        <if test="title != null">            
            and title = #{title}        
        </if>        
        <if test="author != null">            
            and author = #{author}        
        </if>    
    </where> 
</select>

trim标签

trim标签(标签中无内容时无任何作用)

  • prefix/suffix:将trim标签中的内容前面或许后边增加指定内容
  • prefixOverriders/suffixOverriders:将trim标签中的内容前面或许后边去掉指定内容

示例如下:

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">
        select * from user
    <trim prefix="where" prefixOverrides="and | or">
        <if test="username != null">
           and username=#{username}
        </if>
        <if test="sex != null">
           and sex=#{sex}
        </if>
    </trim>
</select>

该示例中,trim的作用是加上前缀where,并去掉第一个and或or

choose when otherwise标签

动态SQL中的choose,when,otherwise相似于java中的if,else if,else

一个 choose 标签中至少有一个 when, 最多一个otherwise

示例如下:

<select id="selectUserByChoose" resultType="com.ys.po.User"
        parameterType="com.ys.po.User">
      select * from user
      <where>
          <choose>
              <when test="id !='' and id != null">
                  id=#{id}
              </when>
              <when test="username !='' and username != null">
                  and username=#{username}
              </when>
              <otherwise>
                  and sex=#{sex}
              </otherwise>
          </choose>
      </where>
 </select>

这里咱们有三个条件:id,username,sex,只能选择一个作为查询条件:

假如 id 不为空,那么查询句子为:select * from user where id=?

假如 id 为空,那么看username 是否为空,假如不为空,那么句子为 select * from user where username=?

假如 username 为空,那么查询句子为 select * from user where sex=?

foreach标签

  • foreach是用来对调集的遍历,这个和Java中的功用很相似,一般处理SQL中的in句子

  • foreach 元素的功用十分强大,它答应你指定一个调集,声明能够在元素体内运用的调集项(item)和索引(index)变量。它也答应你指定最初与完毕的字符串以及调集项迭代之间的分隔符。这个元素也不会过错地增加剩余的分隔符

  • 你能够将任何可迭代目标(如 List、Set 等)、Map 目标或许数组目标作为调集参数传递给 foreach。当运用可迭代目标或许数组时,index 是当时迭代的序号,item 的值是本次迭代获取到的元素。当运用 Map 目标(或许 Map.Entry 目标的调集)时,index 是键,item 是值。

foreach 元素的特点主要有 collection、item、separator、index、open、close

特点 介绍
collection 指定要遍历的调集。表明传入过来的参数的数据类型。该特点是必须指定的,要做 foreach 的目标
index 索引,index 指定一个姓名,用于表明在迭代进程中,每次迭代到的位置。遍历 list 的时候 index 便是索引,遍历 map 的时候 index 表明的便是 map 的 key,item 便是 map 的值。
item 表明本次迭代获取的元素,若collection为List、Set或许数组,表明其间的元素;若collection为map,代表key-value的value,该参数为必选
open 表明该句子以什么开端,最常用的是左括弧’(’,mybatis会将该字符拼接到全体的sql句子之前,而且只拼接一次,该参数为可选项
separator 表明在每次进行迭代之间以什么符号作为分隔符。select * from tab where id in(1,2,3)相当于1,2,3之间的”,”
close 表明该句子以什么完毕,最常用的是右括弧’)’,mybatis会将该字符拼接到全体的sql句子之后,该参数为可选项

示例如下:

//查询第1,2,3号的记录
List<Blog> queryBlogForeach(Map map);
<select id="queryBlogForeach" resultType="Blog" parameterType="map">
    select * from blog
        <where>
            <foreach collection="ids" item="id" 
                open="and (" close=")" separator="or">
                id =#{id}
            </foreach>
        </where>
</select>

sql片段

将sql中一些功用片段提取出来,便利运用

示例如下:

<--运用sql标签抽取公共部分-->
<sql id="if-title-author">    
    <if test="title != null">        
        title = #{title}    
    </if>    
    <if test="author != null">        
        and author = #{author}    
    </if> 
</sql>
<--在需求运用的地方运用Include标签引证-->
<select id="queryBlogIf" parameterType="map" resultType="blog">    
    select * from blog    
    <where>        
        <include refid="if-title-author"></include>    
    </where> 
</select>