SSM框架-MyBatis 深入学习

MyBatis

1. sql语句的参数传入

要对数据库中的数据进行查询或者更新的操作,sql语句应当是根据用户的要求将对应的变化sql中的值
需要向mapper文件中的sql语句进行参数传入,然后进行处理

1.1 简单类型数据的传入

直接利用 #{ } 作为传参的符号,parameterType作为是传入参数的类型,和接口中的方法selectStudent(int id) 所传入的参数保持类型上的一致,便可以将参数传入过去

  <select id="selectStudents" resultType="com.bjpowernode.domain.Student" parameterType="int">
        select id,name,age from student order by #{id}
    </select>

在这里插入图片描述

1.2 对象数据的传入

比如说一些时候,需要传入的参数比较多的时候,便可以采用对象来进行传参,利用对象的属性作为传入的参数,例如插入操作public int insertStudent(Student student);
这个方法的返回结果是变化的数据条数
对应的 mapper文件 中的sql标签变化:

<insert id="insert" parameterType="com.bjpowernode.pojo.Student">
        insert into student (name,email ,age) values(#{name},#{email},#{age})
    </insert>

或者是更新学生数据:

<!--
      更新学生
      int update(Student stu);
    -->
    <update id="update" parameterType="com.bjpowernode.pojo.Student">
        update student set name=#{name},email=#{email},age=#{age}
        where id=#{id}
    </update>

一般采用对象进行传参比较多

1.3 占位符 #{}和${}

  • #{}是对非字符串拼接的参数的占位符,如果入参是简单数据类型,#{}里可以任意写,但是如果入参是对象类型,则#{}里必须是对象的成员变量的名称,#{}可以有效防止sql注入
  • #{}使用的是PreparedStatement执行Sql,效率更高一些
  • 主要是针对字符串拼接替换,如果入参是基本数据类型, {}主要是针对字符串拼接替换,如果入参是基本数据类型, 主要是针对字符串拼接替换,如果入参是基本数据类型,{}里必须是value,但是如果入参是对象类型,则 里必须是对象的成员变量的名称。 {}里必须是对象的成员变量的名称。 里必须是对象的成员变量的名称。{}还可以替换列名和表名,存在sql注入风险,尽量少用
  • ${}使用的是Statement执行Sql,效率低一些

2. mapper文件

在这里插入图片描述
在这里插入图片描述

3. 最后的操作程序

案例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 一些重要的类

  1. Resources类: 资源,用于读取资源文件,解析MyBatis-Config.xml文件,创建出相应的对象
  2. SqlSessionFactoryBuilder:SqlSessionFactory的创建需要用到该对象的Build方法,在创建完工厂之后,即可被销毁
  3. SqlSessionFactory:重量级对象(系统开销大的对象),是线程安全的,使用OpenSession来完成SqlSession 的获取
  4. SqlSession:该接口对象用于指向持久化操作(DAO层操作),一个SqlSession对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以SqlSession对象 的关闭结束,是非线程安全的,所以每次数据库会话结束后,需马上调用close()方法将其关闭

5. 使用注解开发

后面所学的一些框架Spring、SpringMVC、SpingBoot 等一般都是使用的注解开发,而对于MyBatis一般采用的是xml配置文件来进行配置处理,对于注解开发进行一些了解

直接在接口文件中的抽象功能上直接上注解,例如@select(“sql语句”)
然后在mybatis-config.xml文件中绑定上接口(原来绑定的mapper映射文件)

mybatis在项目中一般是不允许使用注解开发的,重要的操作还是使用xml文件进行开发

6. 动态Sql

什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句
官网上的描述:
在这里插入图片描述
动态SQL就是在刻画SQL语句的使用上面的多种标签放入到sql语句中,将多种情况考虑进来,然后就可以将语句富含变化
例如:

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>

7. 多对一的查询

在mybatis操作查询的时候,可能是需要连表查询,比如说建立一个学生表和一个老师表,多个学生对应一个老师,然后是多对一的关系

7.1 按照类似 子查询的方式来进行处理

建立查询的时候,写sql语句
按照mysql中的数据库中查询,select * from student s,teacher t where s.tid=t.id
但是在mybatis 的配置文件中利用select标签来处理的话,是没办法的,牵涉到两个表格,处理的时候就会有问题,要最后查询出来结果显示出来,需要利用resultMap标签将学生表中的字段给处理了

   <select id="selectStudents" resultMap="自定义名称studentTeacher" >
        select * from student 
    </select>
   <resultMap id="studentTeacher" type="student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--与外面的表相连的属性,要采用ass-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
    <select id="getTeacher" parameterType="int" resultType="Teacher">
        select * from teacher where id=#{id}
    </select>

建立了两个select,完成了对应的select * from student s,teacher t where s.tid=t.id 功能 根据的是对应的tid来找到学生所对应的老师
最后要返回的结果是student学生类,如果是只采用第一个selectStudents的标签处理的话,返回的结果中老师那一栏就是全是null
所以采用的是返回加过类型不再是resultType,而是resultMap,利用resultMap映射来改边映射关系,使用resultMap标签,下面的result标签是student类中不需要发生变化的字段,直接用处理即可
对于teacher这一和外面的表进行联合查询获得的字段,使用association标签给联合起来
在标签的属性中建立一个javaType是告诉处理完后放入的是Teacher这个对象类
另一个select属性,将第二个select标签的查询结果放入到第一个select查询结果中,最后得到了对应的结果。

7.2 按照结果进行嵌套处理

相当于只写一个select 然后建立一个新的结果resultMap,然后再结果中处理对应的字段信息

 <select id="selectStudents" resultMap="自定义名称studentTeacher2" >
        select s.id as sid,s.name as sname,t.name as tname
        from student s,teacher t
        where s.tid=t.id
    </select>
   <resultMap id="studentTeacher2" type="student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <!--与外面的表相连的属性,要采用ass-->
        <association property="teacher"  javaType="Teacher">
              <result property="name" column="tname">
        </association>
    </resultMap>

直接在resultMap中的association标签下完成result映射,将另一个老师表中的对应的对象给存进来

8. 一对多的查询

8.1 按照结果进行嵌套处理

 <select id="getTeacher" resultMap="自定义名称TeacherStudent" >
        select s.id as sid,s.name as sname,t.name as tname,t.id as tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid}
    </select>
   <resultMap id="TeacherStudent" type="teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--与外面的表相连的属性,要采用association 或者 collection
        javaType 指定属性的类型
        集合中的泛型信息,我们使用ofType获取
        -->
       <collection property="students" ofType="Student">
          <result property="id" column="sid"/>
          <result property="name" column="sname"/>
          <result property="tid" column="tid"/>
       </collection>
    </resultMap>

本身需要实现的是查找一个老师,其中的学生属性应该是一个集合,有多个,所以最后需要获得一个新的表里面有多个学生,使用结果resultMap映射来做的

8.2 按照类似 子查询的方式来进行处理

<select id="getTeacher2" resultMap="自定义名称TeacherStudent2" >
        select *
        from teacher t
        where  t.id=#{tid}
    </select>
   <resultMap id="TeacherStudent2" type="teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
         <collection property="students" ofType="Student" javaType="ArrayList" column="id" select="getStudentByTeacherId">
   
   <select id="getStudentByTeacherId" resultType="student" >
        select *
        from student s
        where  s.tid=#{tid}
    </select>

在处理一对多、多对一关系中,要保证SQL的可读性,尽量保证通俗易懂;并且要注意属性名和字段的问题

官网上对于结果映射:
在这里插入图片描述

9. 缓存

9.1 缓存的简介

当进行数据库查询的时候:需要连接数据库,非常消耗资源!
解决的方式: 将一次查询的结果,给他暂存在一个可以直接取到的地方------>内存: 缓存
我们再次查询相同数据的时候,直接走缓存,这样就不用走数据库了

将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。mybatis提供查询缓存,用于减轻数据库压力,提高数据库性能。
使用缓存,减少和数据库的交互次数,减少系统开销。对于经常查询并且不经常改变的数据可以使用缓存

数据库满足读写分离,主从复制(保证所有的数据库的同步变化)

缓存执行机制:
在进行数据库访问时,首先去访问缓存,如果缓存中有要访问的数据,则直接返回客户端,如果没有则去访问数据库,在库中得到数据后,先在缓存放一份,再返回客户端。

9.2 Mybatis缓存

在这里插入图片描述
mybatis中有自己的缓存策略,官网上有说明(当前注意前两种)
在这里插入图片描述
在这里插入图片描述

9.3 一级缓存

第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。如果sqlSession去执行commit操作(执行插入、更新、删除),则清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。如果没有重复第一次查询操作

在这里插入图片描述
缓存失效的情况:

  1. 查询不同的东西
  2. 增删改操作,可能会改变原来的数据,所以必定会刷新缓存
  3. 查询不同的Mapper.xml
  4. 手动清理缓存(使用SqlSession的clearCache方法)

小结:一级缓存默认是开启的,只在一次SqlSession中有效,也就是拿到连接到关闭连接这个区间端!

9.4 二级缓存

在这里插入图片描述
在这里插入图片描述

二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。

当sqlsession关闭的时候,相当于一级缓存就直接没了,这个时候将一级缓存的内容给放到了二级缓存中。

在这里插入图片描述
缓存顺序:首先是先看二级缓存中有没有查询过的数据,然后是看一级缓存中有没有查询过的数据,最后在查询数据库。

还有一部分是用ehcache来做自定义缓存,但是已经基本被淘汰了,后面是使用Redis来做缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值