【MyBatis】事务,动态SQL

5 篇文章 0 订阅

数据库连接池

当一个连接通道使用完后,系统并不会将其释放,而是将它存储在连接池里。下次需要使用连接通道的时候,系统会判断连接池里是否有空闲的连接通道对象。如果有,设置其连接字符串,修改其连接状态,重新使用。

 这样能在很大程度上减少实例化的次数,节省了内存和时间,提升了效率。

mybatis连接池提供了3种方式的配置:

配置的位置:

主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。

type属性的取值:
            POOLED        使用连接池。采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
            UNPOOLED   不使用连接池。采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
            JNDI               采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。

MyBatis中的事务

什么是事务

是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合。

事务的四大特性(ACID)

1 、原子性 
事务是数据库的逻辑工作单位,事务中包含的各操作要么都做,要么都不做 
2 、一致性 
事 务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。 
3 、隔离性 
一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。 
4 、持续性 
也称永久性,指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。 

不考虑事务隔离性会产生的三大问题

脏读:指当一个事务正字访问数据,并且对数据进行了修改,而这种数据还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。因为这个数据还没有提交那么另外一个事务读取到的这个数据我们称之为脏数据。依据脏数据所做的操作肯能是不正确的。
不可重复读:指在一个事务内,多次读同一数据。在这个事务还没有执行结束,另外一个事务也访问该同一数据,那么在第一个事务中的两次读取数据之间,由于第二个事务的修改第一个事务两次读到的数据可能是不一样的,这样就发生了在一个事物内两次连续读到的数据是不一样的,这种情况被称为是不可重复读。
幻象读:一个事务先后读取一个范围的记录,但两次读取的纪录数不同,我们称之为幻象读(两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,并没有说这两次执行是在同一个事务中)

Mybatis中事务的提交方式,本质上就是调用JDBC的setAutoCommit()来实现事务控制。

动态SQL

常用的动态SQL元素包括:

  • if
  • where
  • set
  • foreach
  • choose

<if>标签

动态SQL通常会做的事情就是有条件的包含where子句的一部分:

    <!--使用if语句-->
    <select id="findUserByCondition" resultType="com.lwl.domain.User" parameterType="user">
        select * from user where sex = '男';
    <!--可选条件,如果传入的参数中username为null,就将查询条件加上username名-->
            <if test="username != null">
                and username = #{username};
            </if>
    </select>

以上如果传入的user实例中username为空就查询所有姓名为男的信息,如果不为空,就查询性别为男并且username为传入user实例中的username的信息。

如果要传入的条件有多个:

    <!--使用if语句-->
    <select id="findUserByCondition" resultType="com.lwl.domain.User" parameterType="user">
        select * from user
        <where>
            <if test="username != null">
                and username = #{username};
            </if>
            <if test="sex != null">
                and sex = #{sex};
            </if>
        </where>
    </select>

<where>标签

 下面这段是根据传入user实例的username查询改用户的信息,如果传入的username是空的话,返回的结果是select * from user查询所有用户的信息。

    <!--使用if语句-->
    <select id="findUserByCondition" resultType="com.lwl.domain.User" parameterType="user">
        select * from user
        <where>
            <if test="username != null">
               username = #{username};
            </if>
        </where>
    </select>

<set>标签

set元素可以用于动态包含需要更新的列,而舍去其它的。

 动态的更新员工的地址:

    <!--修改用户-->
    <update id="updateUser" parameterType="User">
        update user 
        <set>
            <if test="address != null">
            address=#{address}
            </if>
        </set>
        where id =#{id};
    </update>

<foreach>标签

对一个集合进行便利的时候需要使用,通常发生在构建IN条件语句中:

    <!--使用queryVo中的Id集合实现查询用户列表-->
    <select id="findUserByIds" resultType="com.lwl.domain.User" parameterType="com.lwl.domain.QueryVo">
        select * from user
                <where>
                    <if test="ids != null and ids.size>0" >
                        <foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
                            #{id}
                        </foreach>
                    </if>
                </where>
    </select>

collection为要遍历的集合,open为拼接字符串的开始,close为拼接字符串的结束,separator为迭代中间放置的分隔符。

<choose>标签

有时候不想使用所有的条件语句,而是准备二选一,可以使用choose标签,类似于switch语句。

    <!--使用if语句-->
    <select id="findUserByCondition" resultType="com.lwl.domain.User" parameterType="user">
        select * from user where sex = '男'
        <choose>
            <when test="username != null">
                and username = #{username};
            </when>
            <when test="address != null">
                and address = #{address};
            </when>
        </choose>
    </select>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程芝士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值