Mybatis-动态sql和缓存机制以及注解开发

Mybatis

1.动态SQL

相当于按条件拼接SQL语句

**if 判断条件: ** 相当于java中的if语句
where 标签: 代替的where 1=1恒等式
​ 如果where标签对中有子句拼接,where就提供一个where关键字
​ 去掉第一个多余的and
​ 如果where标签对中没有子句拼接,提供where关键字

<select id="queryEmp" resultType="Emp">
        select empno,ename,job,mgr,sal,comm,hiredate,deptno from emp
   		<!--或者 where 1=1  恒等式  --> 
        <where>
            <if test="ename!=null and ename!=''">
                and ename = #{ename}
            </if>
            <if test="deptno!=null and deptno!=0">
                and deptno = #{deptno}
            </if>
        </where>
    </select>-->

set标签 : 自动去掉最后的,

<update id="updateEmp">
        update emp
        <set>
            empno =#{empno},<!--没有满足条件的  前面要加上 和where判断一样的语句-->
            <if test="ename!='' and ename!=null">
                ename = #{ename},
            </if>
            <if test="sal!=null and sal!=0">
                sal = #{sal},
            </if>
        </set>
        where empno =#{empno}
    </update>
trim标签:

使用trim代替where标签

用于在前后添加或删除一些内容

  1. prefix,在前面添加内容

  2. refixOverrides, 从前面去除内容

  3. suffix, 向后面添加内容

  4. uffixOverrides, 从后面去除内容

    <select id="queryEmp" resultType="Emp">
            select <include refid="emp_all"/> from emp
            <trim prefix="where" prefixOverrides="and">
                <if test="ename!=null and ename!=''">
                    and ename = #{ename}
                </if>
                <if test="deptno!=null and deptno!=0">
                    and deptno = #{deptno}
                </if>
            </trim>
        </select>
    

choose when: 只能判断拼出一个条件类似 swtich case

<select id="queryEmp2" resultType="Emp">
        select <include refid="emp_all"/> from emp
        <where>
            <choose>  <!--switch-->
                <when test="ename!='' and ename!=null">  <!--case-->
                    and ename = #{ename}
                </when>
                <when test="deptno!=0 and deptno!=null">  <!--case-->
                    and deptno = #{deptno}
                </when>
                <otherwise>and sal>1500</otherwise>
            </choose>
        </where>
    </select>

bind :用于对数据进行再加工, 用于模糊查询

<if test="ename!=null and ename!=''">
                <bind name="ename" value="'%' + ename + '%'" />
                and ename like #{ename}
            </if>

sql include: sql用于提取 SQL 语句, include用于引用 SQL 语句

 	<sql id="emp_all">
        empno,ename,job,mgr,sal,comm,hiredate,deptno
    </sql>
    select <include refid="emp_all"/> from emp

使用动态sql后,如果接口中的参数名称不对应 必须用@Param注解改为对应的 不能使用arg0类似的

2.列名和属性名不一致问题

列别名

查询时, 可以通过列别名的方式将列名和属性名保持一致,继续使用自动映射, 从而解决该问题. 但是较为麻烦

使用resultMap

resultMap用于自定义映射关系, 可以由程序员自主制定列名和属性名的映射关系. 一旦使用 resultMap, 表示不再采用自动映射机制

 <!--resultMap 自动映射关联设置
        注意: 非同名的属性与字段之间必须 通过resultMap设置关联
        如果同名可以省略
    -->
    <resultMap id="user_map" type="user">
        <!--<id proerty='' column=''>  映射主键-->
        <result property="name" column="username"/><!--映射非主键-->
    </resultMap>

3.关系映射查询

数据库中表与表之间的关系:

一对一 (人->身份证)

一对多 (夏令营->学生)

多对一 (学生->班级)

多对多 (学生->课程)

resultMap 的关联方式实现多表查询(一对一|多对一)

通过resultMap标签定义映射关系, 并通过association标签指定对象属性的映射关系.

可以把association标签看成一个resultMap标签使用.

javaType 属性表示当前对象, 可以写全限定路径或别名

学生类中添加一个班级类型的属性

<!--做表字段与类型属性的映射-->
    <resultMap id="haha" type="Emp">
        <id property="empno" column="empno"></id>
        <result property="ename" column="ename"/>
        <result property="deptno" column="deptno"/>
        <!--自定义引用数据类型的关联-->
        <association property="dept" javaType="Dept">
            <id property="deptno" column="deptno"/>
            <result property="dname" column="dname"/>
            <result property="loc" column="loc"/>
        </association>
    </resultMap>
resultMap 的关联方式实现多表查询(一对多)

通过resultMap定义映射关系, 并通过collection标签指定集合属性泛型的映射关系.

可以collection标签看成一个resultMap标签使用.

ofType 属性表示集合的泛型,可以写全限定路径或别名.

班级类中添加一个List容器存储学生类型的数据

<!--做表字段与类型属性的映射-->
    <resultMap id="haha" type="Dept">
        <id property="deptno" column="deptno"></id>
        <result property="dname" column="dname"/>
        <result property="loc" column="loc"/>
        <!--设置当属性为集合类型时-->
        <collection property="list" javaType="list" ofType="Emp">
            <id property="empno" column="empno"/>
            <result property="ename" column="ename"/>
            <result property="deptno" column="deptno"/>
        </collection>
    </resultMap>

4.Mybates的缓存机制

一级缓存
  1. 默认开启. 线程级别的缓存, SqlSession 的缓存;

  2. 在一个 SqlSession 生命周期中有效. SqlSession 关闭,缓存清空;

  3. 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值,将键值和结果存放在一个 Map 中,如果后续的键值一样,则直接从 Map中获取数据;

  4. 不同的 SqlSession 之间的缓存是相互隔离的;

  5. 用一个 SqlSession,可以通过配置使得在查询前清空缓存;flushCache=“true”

  6. 任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

二级缓存
  1. 进程级别的缓存, SqlSessionFactory 的缓存

  2. 在一个SqlSessionFactory生命周期中有效. 可以在多个SqlSession 生命中期中共享.

  3. 默认关闭, 需要使用的时候, 要为某个命名空间开启二级缓存(在 mapper.xml 中配置cache)

  1. 由于在更新时会刷新缓存,因此需要注意使用场合:查询频率很高,更新频率很低时使用,即经常使用 select, 相对较少使用delete, insert, update。

  2. 缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个 namespace的缓存,也就是你 update 了一个,则整个缓存都刷新了。

  3. 最好在「只有单表操作」的表的 namespace 使用缓存,而且对该表的操作都在这个 namespace 中。否则可能会出现数据不一致的情况。

注解开发

MyBatis 中常用的注解
CRUD 注解

@Select: 类似于select标签

@Insert: 类似于insert标签

@Update: 类似于update标签

@Delete: 类似于delete标签

	@Select("select * from dept")
    List<Dept> queryDept();

    @Select("select * from dept where deptno = #{deptno}")
    Dept queryDeptByDeptno(int deptno);

    @Update("update dept set dname = #{dname} where deptno = #{deptno}")
    int updateDept(Dept dept);
其他注解

@Results: 类似于resultMap标签

@Result: 类似<resultMap的子标签

@One: 类似于association标签

@Many: 类似于collection标签

@Select("select * from emp")
    @Results(value={
         @Result(property ="empno",column = "empno",id = true),  /*id = true主键字段*/
         @Result(property ="ename",column = "ename"),
         @Result(property ="deptno",column = "deptno"),
         @Result(property ="dept",one=@One(select="com.xxxx.mappers.DeptMapper.queryDeptByDeptno"),column = "deptno")
    })
    List<Emp> queryEmp();



//class  DeptMapper 
@Select("select * from dept where deptno = #{deptno}")
    Dept queryDeptByDeptno(int deptno);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值