MyBatis学习整理

什么是MyBatis

MyBatis原来是apache的一个开源项目,叫做ibatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis,是一个基于Java的持久层框架。

MyBatis的优势

1.MyBatis 避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集的过程,减少了代码的冗余,减少程序员的操作。

2.MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类映射成数据库中的记录。

Mybatis的四个核心组件

1.SqlSessionFactoryBuilder (构造器):它会根据配置或者代码来生成 SqISessionFactory,采用的是分步构建的 Builder 模式。

2.SqlSessionFactory (工厂接口):依靠它来生成 SqlSession,使用的是工厂模式。

3.SqlSession (会话): 一个既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接 口。在现有的技术中, 一般我们会让其在业务逻辑代码中“消失”,而使用的是 MyBatis 提供的 SQLMapper 接口编程技术,它能提高代码的可读性和可维护性。 

4.SQL Mapper (映射器): MyBatis 新设计存在的组件,它由一个 Java 接口和 XML 文件(或注解)构成,需要给出对应的 SQL 和映射规则。它负责发送SQL去执行, 并返回结果

Mybatis配置文件的元素

Mybatis的基础crud语句

id标识了对应的SQL语句,parameterType标出了参数的类型,resultType则代表结果映射的类型。

解决 Mybatis 数据库字段名和实体类属性名不一致问题的三种办法

1.取别名

2.使用 resultMap 标签 (推荐使用)

3.如果只是单纯的下划线,可以使用 setting 标签设置开启驼峰命名规则。

<settings>

        <setting name="mapUnderscoreToCamelCase" value="true" />

</settings>

动态 sql 拼接

MyBatis 动态 sql 可以让我们在 xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

if 标签

if 标签通常用于 WHERE 语句、UPDATE 语句、INSERT 语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。

<if test="name != null and name != ''">

    and NAME = #{name}

</if>

foreach 标签

foreach 标签主要用于构建 in 条件,可在 sql 中对集合进行迭代(遍历集合)。也常用到批量删除、添加等操作中。

<!-- in查询所有,不分页 -->

<select id="selectIn" resultMap="BaseResultMap">

    select name,hobby from student where id in

    <foreach item="item" index="index" collection="list" open="(" separator="," close=")">

        #{item}

    </foreach>

</select>

属性介绍:

collection:遍历的集合。

item :表示在迭代过程中每一个元素的别名

index :表示在迭代过程中每次迭代到的位置(下标)

open :遍历开始前拼接的sql片段

close :遍历结束后拼接的sql片段

separator :分隔符,表示迭代时每个元素之间以什么分隔

choose 标签

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis 提供了 choose 元素,按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when的条件都不满则时,则执行 otherwise 中的 sql。类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

if 是与(and)的关系,而 choose 是或(or)的关系。

<select id="getStudentListChoose" parameterType="Student" resultMap="BaseResultMap">

    SELECT * from STUDENT WHERE 1=1

    <where>

        <choose>

            <when test="Name!=null and student!='' ">

                AND name LIKE CONCAT(CONCAT('%', #{student}),'%')

            </when>

            <when test="hobby!= null and hobby!= '' ">

                AND hobby = #{hobby}

            </when>

            <otherwise>

                AND AGE = 15

            </otherwise>

        </choose>

    </where>

</select>

where 标签

当 if 标签较多时,这样的组合可能会导致错误。 如下:

<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">

    SELECT * from STUDENT WHERE

    <if test="name!=null and name!='' ">

        NAME LIKE CONCAT(CONCAT('%', #{name}),'%')

    </if>

    <if test="hobby!= null and hobby!= '' ">

        AND hobby = #{hobby}

    </if>

</select>

当 name 值为 null 时,查询语句会出现 “WHERE AND” 的情况,解决该情况除了将"WHERE"改为“WHERE 1=1”之外,还可以利用 where标签。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以 AND 或 OR 开头的,则它会剔除掉。

<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">

    SELECT * from STUDENT

    <where>

        <if test="name!=null and name!='' ">

            NAME LIKE CONCAT(CONCAT('%', #{name}),'%')

        </if>

        <if test="hobby!= null and hobby!= '' ">

            AND hobby = #{hobby}

        </if>

    </where>

</select>

set 标签

没有使用 if 标签时,如果有一个参数为 null,都会导致错误。当在 update 语句中使用 if 标签时,如果最后的 if 没有执行,则或导致逗号多余错误。使用 set 标签可以将动态的配置 set关键字,和剔除追加到条件末尾的任何不相关的逗号。

<update id="updateStudent" parameterType="Object">

    UPDATE STUDENT

    SET NAME = #{name},

    MAJOR = #{major},

    HOBBY = #{hobby}

    WHERE ID = #{id};

</update>

<update id="updateStudent" parameterType="Object">

    UPDATE STUDENT SET

    <if test="name!=null and name!='' ">

        NAME = #{name},

    </if>

    <if test="hobby!=null and hobby!='' ">

        MAJOR = #{major},

    </if>

    <if test="hobby!=null and hobby!='' ">

        HOBBY = #{hobby}

    </if>

    WHERE ID = #{id};

</update>

<update id="updateStudent" parameterType="Object">

    UPDATE STUDENT

    <set>

        <if test="name!=null and name!='' ">

            NAME = #{name},

        </if>

        <if test="hobby!=null and hobby!='' ">

            MAJOR = #{major},

        </if>

        <if test="hobby!=null and hobby!='' ">

            HOBBY = #{hobby}

        </if>

    </set>

    WHERE ID = #{id};

</update>

trim 标签

trim标记是一个格式化的标记,主要用于拼接sql的条件语句(前缀或后缀的添加或忽略),可以完成set或者是where标记的功能。

trim属性主要有以下四个:

prefix:在trim标签内sql语句加上前缀

suffix:在trim标签内sql语句加上后缀

prefixOverrides:指定去除多余的前缀内容,如:prefixOverrides=“AND | OR”,去除trim标签内sql语句多余的前缀"and"或者"or"。

suffixOverrides:指定去除多余的后缀内容。

例如在update中

<update id="updateByPrimaryKey" parameterType="Object">

    update student set

    <trim  suffixOverrides=",">

        <if test="name != null">

            NAME=#{name},

        </if>

        <if test="hobby != null">

            HOBBY=#{hobby},

        </if>

    </trim>

    where id=#{id}

</update>

如果name和hobby的值都不为空的话,会执行如下语句

update student set NAME='XX',HOBBY='XX' /*,*/ where id='XX'

会忽略最后一个“,” ;

sql 标签

当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求 <select> 结构清晰也可将 sql 语句分解

sql标签负责抽取重复字段,include标签负责在原来抽取的位置再通过include引用进来

<!-- 查询字段 -->

<sql id="Base_Column_List">

    ID,MAJOR,BIRTHDAY,AGE,NAME,HOBBY

</sql>

<!-- 查询条件 -->

<sql id="Example_Where_Clause">

    where 1=1

    <trim suffixOverrides=",">

        <if test="id != null and id !=''">

            and id = #{id}

        </if>

        <if test="major != null and major != ''">

            and MAJOR = #{major}

        </if>

        <if test="birthday != null ">

            and BIRTHDAY = #{birthday}

        </if>

        <if test="age != null ">

            and AGE = #{age}

        </if>

        <if test="name != null and name != ''">

            and NAME = #{name}

        </if>

        <if test="hobby != null and hobby != ''">

            and HOBBY = #{hobby}

        </if>

        <if test="sorting != null">

            order by #{sorting}

        </if>

        <if test="sort!= null and sort != ''">

            order by ${sort} ${order}

        </if>

    </trim>

</sql>

include 标签

用于引用定义的常量

<!-- 查询所有,不分页 -->

<select id="selectAll" resultMap="BaseResultMap">

    SELECT

    <include refid="Base_Column_List" />

    FROM student

    <include refid="Example_Where_Clause" />

</select>

<!-- 分页查询 -->

<select id="select" resultMap="BaseResultMap">

    select * from (

        select tt.*,rownum as rowno from

        (

            SELECT

            <include refid="Base_Column_List" />

            FROM student

            <include refid="Example_Where_Clause" />

            ) tt

            <where>

                <if test="pageNum != null and rows != null">

                    and rownum

                    <![CDATA[<=]]>#{page}*#{rows}

                </if>

            </where>

        ) table_alias

    where table_alias.rowno>#{pageNum}

</select>

<!-- 根据条件删除 -->

<delete id="deleteByEntity" parameterType="java.util.Map">

    DELETE FROM student

    <include refid="Example_Where_Clause" />

</delete>

MyBatis的分页插件

PageHelper: 物理分页, 通过拦截器加 limit 语句进行分页

RowBounds: 逻辑分页,数据量大的时候压力较大

总结:Mybatis的逻辑分页比较简单,简单来说就是取出所有满足条件的数据,然后舍弃掉前面offset条数据,然后再取剩下的数据的limit条。

如何批量插入

  1. 不使用批处理(Java语句中循环插入),速度很慢,效率低

2.foreach标签

3.使用batch元素进行批量操作

MyBatis 的三种基本 Executor 执行器

1.SimpleExecutor

 每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。

2.ReuseExecutor

执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>内,供下一次使用。简言之,就是重复使用 Statement 对象。

3.BatchExecutor

执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。作用范围:Executor 的这些特点,都严格限制在 SqlSession 生命周期范围内。

Mybatis配置日志

步骤:

  1. 在pom文件中导包(log4j)
  2. 配置log4j.properties

3.配置xml文件的<settings>,注意大小写和空格问题

4.完成

日志的简单使用:

  1. 在要使用Log4j的类中,导入包import org.apache.log4j.Logger
  2. 日志对象,参数为当前类的class

Static Logger logger=Logger.getLogger(UserDaoTest.class)

     3.日志级别

OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值