Mybatis框架基础

1.动态SQL

Mybatis提供的拼接Sql语句的机制。

1.if

<select id="listSearchStudents" resultType="entity.Student">
    select *
    from stu
    where sname = #{sname}
    <if test="phone != null and phone !='' ">
        and phone = #{phone}
    </if>
</select>

2.choose when otherwise

<select id="listSearchStudents1" resultType="entity.Student">
    select *
    from stu
    where 1=1
    <choose>
        <when test="sname != null and sname != '' ">
            and sname like '%${sname}%'
        </when>
        <when test="phone != null and phone != '' ">
            and phone like '%${phone}%'
        </when>
        <!-- 以上都不满足 -->
        <otherwise>

        </otherwise>
    </choose>
</select>

3.where

子元素有返回值,在对应语句加where

<select id="listSearchStudents2" resultType="entity.Student">
    select *
    from stu
    <where>
        <if test="sname != null and sname != '' ">
            and sname like '%${sname}%'
        </if>
        <if test="phone != null and phone != '' ">
            and phone like '%${phone}%'
        </if>
    </where>
</select>

4.set

用于update

<update id="updateStudentBySid" parameterType="Integer">
    update stu
    <set>
        <if test="sname != null and sname != '' ">
            sname = #{sname},
        </if>
        <if test="phone != null and phone != '' ">
            phone = #{phone},mj
        </if>
    </set>
    where sid = #{sid}
</update>

5.trim

  • prefix 指定给Sql语句增加的前缀
  • prefixOverrides 指定给Sql语句要去掉的前缀
  • suffix 指定给Sql语句增加的后缀
  • suffixOverrides 指定给Sql语句要去掉的后缀
    代替where和set使用
<trim prefix="where" prefixOverrides="and">
  <if test="">
    and sid = #{sid}
  </if>
</trim>
<trim prefix="set" suffixOverrides=",">
  <if test="">
      sid = #{sid},
   </if>
</trim>

6.foreach

用于遍历 支持数组 List Set 接口的集合
通常用于in关键字

<select id="listStudentsByForeach" resultType="entity.Student">
    select *
    from stu
    where sid in
    <foreach collection="list" item="sid" index="index" open="(" separator="," close=")">
        #{sid}
    </foreach>
</select>

2.缓存

1.一级缓存

同一个SqlSession对象第一次执行查询语句,把结果写入一级缓存
之后没有更新插入删除操作,执行相同的查询语句,会读取一级缓存内数据

1.1 原理

SqlSession级别的缓存。创建SqlSession时,对象引入HashMap作为储存数据区域。
key是SQL语句、条件、statement组成的唯一值
value是查询的结果对象
不同SqlSession之间HashMap不影响

1.2 应用

1.2.1 log4j日志配置
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.21</version>
</dependency>
  • log4j.properies 配置文件
log4j.rootLogger = ERROR,stdout
#mybatis???? namespace?
log4j.logger.mapper.StudentMapper = DEBUG
#???????
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %5p[%t] - %m%n
1.2.2 Test类
@Test
public void Test(){
    String resource = "config.xml";
    try{
        InputStream in = Resources.getResourceAsStream(resource);

        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        SqlSessionFactory ssf = ssfb.build(in);
        SqlSession sqlSession=ssf.openSession();

        String statement="mapper.StudentMapper.getStudentBySid";

        Student student = sqlSession.selectOne(statement,1);
        System.out.println(student);

        Student student1 = sqlSession.selectOne(statement,1);
        System.out.println(student1);
        sqlSession.commit();
        sqlSession.close();
    }catch (Exception e){
        e.printStackTrace();
    }
}

2.二级缓存

2.1 原理

作用域是Mapper,可以跨多个SqlSession,多个SqlSession操作同一个Mapper的Sql语句,共用二级缓存
HashMap与一级缓存一样
可以自定义缓存源
以namespace区分Mapper,SqlSesion执行查询,没有更新删除插入,别的SqlSession执行相同查询,从缓存拿到

2.2 应用

2.2.1 开启二级缓存
  • 配置文件
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
  • Mapper.xml
<cache></cache>

默认特性:

  • 缓存使用LRU算法收回
  • 没有刷新间隔,缓存不会以任何时间顺序来刷新
  • 缓存会存储列表集合或对象的1024个引用
  • 缓存可读写,对象检索不是共享的,可以安全调用
2.2.2 实体类序列化
public class Student implements Serializable
2.2.3 测试类
@Test
public void cache(){
    String resource = "config.xml";
    try{
        InputStream in = Resources.getResourceAsStream(resource);

        SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
        SqlSessionFactory ssf = ssfb.build(in);

        SqlSession sqlSession1 = ssf.openSession();
        SqlSession sqlSession2 = ssf.openSession();

        String statement="mapper.StudentMapper.getStudentBySid";

        Student student1 = sqlSession1.selectOne(statement,1);
        System.out.println(student1);

        // 是否在新的SQL查询之前没有关闭上一个SqlSession,导致命中了一级缓存而不需要查询二级缓存
        sqlSession1.commit();
        sqlSession1.close();

        Student student2 = sqlSession2.selectOne(statement,1);
        System.out.println(student2);

        sqlSession2.commit();
        sqlSession2.close();
    }catch (Exception e){
        e.printStackTrace();
    }
}

3.整合EhCache

3.1 依赖

 <!--    EhCache-->
<dependency>
  <groupId>net.sf.ehcache</groupId>
  <artifactId>ehcache-core</artifactId>
  <version>2.6.8</version>
</dependency>
<dependency>
  <groupId>org.mybatis.caches</groupId>
  <artifactId>mybatis-ehcache</artifactId>
  <version>1.0.3</version>
</dependency>

3.2 ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <diskStore path="D:/cache"></diskStore>
    <defaultCache
            maxElementsInMemory="1"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>

</ehcache>
  • diskStore 指定缓存数据转移到磁盘,path指定存储位置
  • defaultCache 指定默认缓存配置信息
  • cache 自定义配置信息

3.基础

1.工作流程

1.读取配置文件和映射文件。
2.生成SqlSessionFactory对象:生成SqlSession
3.SqlSession通过Executor执行器接口操作数据库,其有俩个实现类,一个是普通执行器,缓存执行器。
4.Executor执行器将Sql信息封装到MapperStatement对象中。执行Sql前,MapperStatement对象吧Java数据映射到Sql。执行后,执行结果映射为Java数据

2.SqlSessionFactory类

使用单列模式创建SqlSessionFactory对象,每一个数据库对应一个SqlSessionFactory对象。

3.SqlSession类

线程不安全 不能被共享

1.#{} 和 ${}

  • 使用#{} 解析为SQL时,会将形参变量的值取出,并自动给其添加引号。
    username="Amy"
    使用#{}可以防止SQL注入而${}却不行
  • ${} 解析为SQL时,将形参变量的值直接取出,直接拼接显示在SQL中
    username=${value} -> username=Amy
    username='${value}' -> username='Amy'

使用 某字段 in 时候使用

  • 模糊查询场景
    username LIKE '%${value}%'
    username LIKE CONCAT('%', #{username}, '%')
    作用一样 但是${}不安全
  • 只能${}场景
    ORDER BY ${value} ASC 如果用#{}则错误
posted @ 2023-10-04 18:00  lwx_R  阅读(24)  评论(0)    收藏  举报