likes
comments
collection
share

Mybatis相关知识点总结

作者站长头像
站长
· 阅读数 11

什么是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>