MyBatis — 动态SQL、缓存机制

@Test
public void TestgetStudent(){
      StudentMapper bean = ioc.getBean(StudentMapper.class);
      Student student = new Student(4,"jack", "111", "jack@qq.com");
      System.out.println(student);
      Student student2 = bean.getStudent(student);
      System.out.println(student2);
}

         
惟有会话提交或者关闭之后,一流缓存中的多少才会换至二级缓存中。

 3)用if标签改写为动态SQL,如下所示:

 test:判断表明式(OGNL):OGNL参照PPT或者法定文档。

案例:

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

 

 3)测试类代码为

 

<select id="getStuByIdForEach" resultType="com.neuedu.mybatis.entity.Student">
      select * from student
      where id
      in
      <foreach collection="ids" item="id" open="(" close=")" separator=",">
            #{id}
      </foreach>
</select>

案例演示:

和缓存有关的装/属性:


测试:

手动清除了缓存,所以得更寻找

– foreach:

 遇见特殊符号,应该去写转义字符:如<>分别吗&lt,&gt

1)开启全局二级缓存配置:

<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
      SELECT *
      FROM student
      <where>
            <if test="id != null">
                  id=#{id}
            </if>
            <if test="name !=null and name!=''">
                  and name=#{name}
            </if>
            <if test="password !=null and password !=''">
                  and password=#{password}
            </if>
            <if test="email !=null and email !=''">
                  and email=#{email}
            </if>
      </where>
</select>

4.SqlSession同样,手动清除了一流缓存[缓存清空]

1.每当EmployeeMapper接口类中上加批量栽的法门

        –2、二级缓存需要手动开启同布置,他是因namespace级别之休养存。

 

 

顶尖缓存:

常用标签:

功用:数据会从二级缓存中拿到

 

@Test
public void getStuByIdForEach(){
      StudentMapper bean = ioc.getBean(StudentMapper.class);
      List<Integer> list = Arrays.asList(16,17,18,19);
      List<Student> stuByIdForEachlist = bean.getStuByIdForEach(list);
      for (Student student : stuByIdForEachlist) {
            System.out.println(student);
      }
}

– choose【when…otherwise】:分支采取

foreach元素允许指定一个会师,评释集合项和目录变量,并可指定开闭匹配的字符串以及以迭代中间放置分隔符。

<cache eviction="FIFO" size="100" readOnly="false"/>

 将set标签用trim标签代替

1.sqlSession不同,重新定义SqlSession

@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);

      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);

      session.clearCache();

      Employee emp2 = mapper.getEmpInfoById(4);
      System.out.println(emp2);

      System.out.println(emp == emp2);

      session.commit();
      session.close();
}

   mybatis就会将where标签中并装的sql,多出的and或者or去丢!

赏心悦目来就发送了一样次等SQL语句,第二次等询问时于二级缓存中拿到之数目,并没发送新的sql语句。

3.亟需注意:where标签只会失掉丢第一独多出去的and或者or


readOnly:是否就读,true/false

<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
      SELECT *
      FROM student
       where
            <if test="id != null">
                  id=#{id}
            </if>
            <if test="name !=null and name!=''">
                  and name=#{name}
            </if>
            <if test="password !=null and password !=''">
                  and password=#{password}
            </if>
            <if test="email !=null and email !=''">
                  and email=#{email}
            </if>
</select>

用回true,表达emp与emp2是缓存,而未是双重找

<update id="updateStu">
      update student
      <set>
            <if test="name !=null and name!=''">
                  name=#{name},
            </if>
            <if test="password !=null and password !=''">
                  password=#{password},
            </if>
            <if test="email !=null and email !=''">
                  email=#{email}
            </if>
      </set>
            where id = #{id}
</update>
public void updateStu(Student student);

 

 

 

4)测试代码

trim标签:可以于定义字符串的截取规则** 

1)在EmployeeMapper接口文件添加一个道

3)我们的POJO需要贯彻体系化接口[implements Serializable]

 

MyBatis系统中默认定义了少于级缓存。

@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);

      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);

      mapper.deleteEmp(16);

      Employee emp2 = mapper.getEmpInfoById(4);
      System.out.println(emp2);

      System.out.println(emp == emp2);

      session.commit();
      session.close();
}

中属性:

– if:字符判断

    前面多有的and或者or where标签不克化解

     
代表缓存最多可储存多少个目的,太可怜容易招内存溢出

3)每个增删改标签都发生一个flushCache=”true”:增删改执行到位后虽相会精通缓存【顶尖二级缓存都汇合被清空】

4)必须事先关从前的sqlsession对象

1.受where前边长1=1,将来的标准化且可行使and xxx了

    prefix=””:前缀:trim标签体是一体字符串拼串后的结果。

一流缓存和二级缓存

         
需要注意的凡:在什么人Mapper.xml文件中打开了<cache>缓存标签,哪个Mapper中便拉开了二级缓存。


trim【where,set】:字符串截取,其中where标签封装查询条件,set标签封装修改标准

MyBatis
包含一个异常强大的询问缓存特性,它可以老便于地配置与定制。缓存可以大幅度的升级换代查询功用。

            与数据库同一回对话期间查询到的数目在地面缓存中。

              mybatis为了加紧获取速度,直接就是会合拿数据以缓存中之援交给用户。不安全,速度快。

 2.每当EmployeeMapper.xml的sql映射文件被添加响应的说话

     二级缓存(全局缓存):

           查询标签:flushCache = “false”

@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);
      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);
      session.close();

      SqlSession session2 = sqlSessionFactory.openSession();
      EmployeeMapper mapper2 = session2.getMapper(EmployeeMapper.class);
      Employee emp2 = mapper2.getEmpInfoById(4);
      System.out.println(emp2);
      session2.close();
}
<insert id="insertStus">
      insert into student (name,password,email) values
      <foreach collection="stus" item="stu" separator=",">
            (#{stu.name},#{stu.password},#{stu.email})
      </foreach>
</insert>

今非昔比namespace查出的数据会放在自己相应的休养生息存着(map)   

foreach 中因故
collection,collection中凡于Mapper接口传来的参数,separator是失去丢中间符号

WEAK
–弱引用:更主动地移除基于垃圾收集器状态及弱引用规则的对象。

 

 2.sql映射文件

           假诺flushCache =
true;每趟查询前还汇合清空缓存,缓存是未曾吃采纳!

  
也就是说使用where标签有时候要无克缓解问题的,这怎么收拾呢?我们这边可以使trim标签

    prefixOverrides=””:前缀覆盖:去丢满字符串前边多余的字符

二级缓存:

要小心的是:只有一级缓存中关闭的情事下,二级缓存才会师被运用。

一部分时候需要依据要询问的参数动态的拼接SQL语句

      
       mybatis会利用体系化&反连串化的技术克隆一卖。安全,速度放缓。

          查出的数都汇合让默认先在一流缓存中。

– foreach:遍历元素

以回两长条select语句

1.一个对话,查询同一漫漫数,这些数量就是会叫放在脚下对话的一流缓存中。

 

FIFO
–先进先出:按目的上缓存的逐一来移除它们。

 

1)cacheEnabled=”true”:
false:关闭缓存(二级缓存关闭)【一级缓存一向可用】

<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
       select *from tbl_employee where id = #{id} and user_name = #{userName} and email = #{email} and gender = #{gender}
</select>
public void insertStus(@Param("stus")List<Student> student);

choose标签:分支选取,类似于Java被的带动了break的switch…case**

                  false:不接纳缓存(超级缓存还以,二级缓存不行使)

           
未来如果欲得到相同之数,直接打缓存中以,没必要更错过查询数据库;

public Student getStudent(Student student);

而仔细来说,下边的sql语句是出问题之,当我们不被动态sql语句传递id值的时光,sql语句之拼装就会见暴发题目!【name前发出一个and】

SOFT
–软引用:移除基于垃圾回收器状态与软引用规则的靶子。

 

解决办法

type:指定由定义缓存的全类名
实现cache接口即可!

    prefix给拼串后底满贯字符串加一个前缀

默认的是LRU。

 顶尖缓存失效的景【4种植】(没有利用及眼前一级缓存的状态,效果就是是,还欲再为数据库来查询)

将返回false,说明emp2不是emp的缓存

@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);

      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);

      Employee emp2 = mapper.getEmpInfoById(4);
      System.out.println(emp2);

      System.out.println(emp == emp2);

      session.commit();
      session.close();
}

MyBatis-缓存机制   

 

 test于参数中取值进行判断

3.SqlSession同等,可是简单破查询之间进行了多删改操作【这一次增删改可能针对眼前数量有影响】

public List<Student> getStus(Student student);

 

1.当EmployeeMapper接口中补充加一个办法

@Test
public void TestUpdateStu(){
      StudentMapper bean = ioc.getBean(StudentMapper.class);
      bean.updateStu(new Student(4, "jackk", null, null));
}

 foreach标签还可用来批量保存数据

【一流缓存的限量如故太小了,每一回SqlSession一闭馆,一流缓存中之数码就是没有】

@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);

      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);

      Employee emp2 = mapper.getEmpInfoById(16);
      System.out.println(emp2);

      System.out.println(emp == emp2);

      session.commit();
      session.close();
}

 #测试结果没有问题,

<select id="getStus" resultType="com.neuedu.mybatis.entity.Student">
      select * from student
      <where>
            <choose>
                  <when test="id !=null">
                        id = #{id}
                  </when>
                  <when test="name !=null and name!=''">
                        name = #{name}
                  </when>
                  <when test="password !=null and password!=''">
                        password = #{password}
                  </when>
                  <when test="email !=null and email!=''">
                        email = #{email}
                  </when>
                  <otherwise>
                        1 = 1
                  </otherwise>
            </choose>
      </where>
</select>

唯有以MyBatis中,在SSM整合文件被从不因此,因为SqlSession 定义在
bean.xml中,无法再一次定义SqlSession

if案例

size:引用数,正整数,默认1024

 

LRU
–近日至少使用的:移除最充分时未深受应用的目的。

【全局缓存】:基于namespace级此外缓存:一个namespace对应一个二级缓存。

    suffix=””:后缀


工作体制:

 2)在sql映射文件被,填写相应的sql语句,如下所示【set标签可以将字段前面的逗号去丢】

    suffixOverrides=””:后缀覆盖:去丢满字符串前面多余的字符

– where 标签

flushInterval:缓存刷新间隔
?缓存多少长度期清空一破,默认不清空,设置一个纳秒值。

 

动态SQL的任何一个常用之操作是用针对一个聚集举行遍历,通常以构建in条件语句的时节!

      true:只读缓存;mybatis认为颇具由缓存中获取数据的操作都是唯有读操作,不汇合窜数据。

 2)假如假定描写下列的SQL语句,只倘诺未为空,就作为查询条件,如下所示,这样形容实际是来问题的,所以大家而描绘成动态SQL语句:

    suffix给拼串后底整套字符串加一个后缀

 3.测试代码

 2)去mapper.xml中布局使用二级缓存

     一流缓存:(本地缓存):SqlSession级别之缓存,一级缓存是直被的,没法关。方法之间莫一起用!

2.SqlSession同样,不过查询条件不平等[即缓存中尚平昔不这一个数量]

用回来一长达select查询语句,

      false:非只读:mybatis觉得收获之多少或许谋面于改动。

虽然一定给冲不同规格还寻找

set标签:字符串截取,可以描绘在trim里面**

2)每个select标签还发useCache=”true”;

 

<update id="updateStu">
      update student
      <trim prefix="set" suffixOverrides=",">
            <if test="name !=null and name!=''">
                  name=#{name},
            </if>
            <if test="password !=null and password !=''">
                  password=#{password},
            </if>
            <if test="email !=null and email !=''">
                  email=#{email}
            </if>
      </trim>
            where id = #{id}
</update>
@Test
public void TestFirstCache(){
      SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
      session = sqlSessionFactory.openSession();
      mapper = session.getMapper(EmployeeMapper.class);
      Employee emp = mapper.getEmpInfoById(4);
      System.out.println(emp);

      SqlSession session2 = sqlSessionFactory.openSession();
      EmployeeMapper mapper2 = session2.getMapper(EmployeeMapper.class);
      Employee emp2 = mapper2.getEmpInfoById(4);
      System.out.println(emp2);

      System.out.println(emp == emp2);

      session.commit();
      session.close();
}

       
–3、为了提升扩充性。MyBatis定义了缓存接口Cache。大家得以经过实现Cache接口来自定义二级缓存。

 3.测试类代码

public List<Student> getStuByIdForEach(@Param("ids")List<Integer> ids);

以默认自动刷新了缓存

一定给确保了第一只case 符合之后,就跳出

set元素会动态前置set关键字,同时为会面败无关之逗号

2.如会讲话关闭,一流缓存中的数额会于封存至二级缓存中;新的对话查询信息,就可以参考二级缓存中。

eviction=“FIFO”:缓存回收策略:

<select id="getStudent" resultType="com.neuedu.mybatis.entity.Student">
      SELECT *
      FROM student
      <trim prefix="where" prefixOverrides="and">
            <if test="id != null">
                  id=#{id}
            </if>
            <if test="name !=null and name!=''">
                  and name=#{name}
            </if>
            <if test="password !=null and password !=''">
                  and password=#{password}
            </if>
            <if test="email !=null and email !=''">
                  and email=#{email}
            </if>
      </trim>
</select>

 

得专注的是:在哪个Mapper.xml文件被启了<cache>缓存标签,哪个Mapper中就敞开了二级缓存。

1)在EmployeeMapper中添加一个改进的情势

案例演示:

1.于EmployeeMapper接口中进入一个主意

       
–1、默认情状下,只爆发一级缓存(SqlSession级别之缓存,也叫做本地缓存)开启。

 

 

 

2.当MyBatis的sql映射文件被描写相应的代码

因此打那一个角度谈:能跨sqlSession的缓存为二级缓存!

案例:测试超级缓存【默认是打开之】

2.足利用 where
标签
来将享有的查询条件包括在内

@Test
public void TestInsertStus(){
      StudentMapper bean = ioc.getBean(StudentMapper.class);
      List<Student> list = new ArrayList<Student>();
      list.add(new Student("123","123", "123"));
      list.add(new Student("123","123", "123"));
      list.add(new Student("123","123", "123"));
      bean.insertStus(list);
}
网站地图xml地图