Mybatis 学习笔记总结

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis 学习笔记总结相关的知识,希望对你有一定的参考价值。

文章目录

1. 动态SQL

1.1 什么是动态SQL?


什么是动态SQL?

  • 动态SQL就是指根据不同的条件生成不同的SQL语句。

平时我们操作一些不同的sql语句,都是直接在代码上更改,很麻烦。通过Mybatis的动态SQL就很方便。


利用动态SQL这一特性可以彻底摆脱这种痛苦。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

要学习的内容也就下面4个标签:
if
choose (when, otherwise)
trim (where, set)
foreach

1.2 准备工作


Blog实体类:

package com.itholmes.pojo;

import lombok.Data;

import java.util.Date;

@Data
public class Blog 
    private String id;
    private String title;
    private String author;
    /*
		对于这种驼峰命名,对应数据库的内容,我们可以在mybatis的核心配置文件的setting配置,mapUnderscoreToCamelCase为true.
	*/
    private Date createTime;
    private int views;

创建一个IDUtils类,来获取UUId的一个字符串。将这个字符串作为Blog的id属性。

package com.itholmes.utils;

import org.junit.jupiter.api.Test;

import java.util.UUID;

public class IDUtils 
    public static String getUUId()
        /*
            UUID.randomUUID().toString()来生成一个uuid字符串。
            注意:UUID是不会重复的!
        */
        return UUID.randomUUID().toString().replaceAll("-","");
    

	//测试uuid的效果。
    @Test
    public void test()
        String uuId = IDUtils.getUUId();
        String uuId2 = IDUtils.getUUId();
        String uuId3 = IDUtils.getUUId();
        System.out.println(uuId);
        System.out.println(uuId2);
        System.out.println(uuId3);
    

1.3 动态SQL之if语句


<select id="findActiveBlogWithTitleLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #title
  </if>
</select>

结构就是:if标签加一个test属性,test属性中是字段名的一些限制语句啥的。

BlogMapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.BlogMapper">

    <select id="queryBlogIF" parameterType="map" resultType="com.itholmes.pojo.Blog">
        select * from mybatis.blog where 1=1
        
        <if test="title != null">
            and title = #title
        </if>

        <if test="author != null">
            and author = #author
        </if>
    </select>

</mapper>

BlogMapper接口类:

package com.itholmes.dao;

import com.itholmes.pojo.Blog;

import java.util.List;
import java.util.Map;

public interface BlogMapper 
    //查询博客
    List<Blog> queryBlogIF(Map map);

测试类:

import com.itholmes.dao.BlogMapper;
import com.itholmes.pojo.Blog;
import com.itholmes.utils.IDUtils;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

public class test 
    @Test
    public void test2()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map = new HashMap();

        map.put("title","数据结构");
        map.put("author","张三");

        List<Blog> list = mapper.queryBlogIF(map);
        for (Blog blog : list) 
            System.out.println(blog);
        
        sqlSession.close();
    

1.4 动态SQL的trim(where , set)


where作用很关键,我们在执行一些动态SQL的语句时,可能会出现sql语句拼接的错误。如下:

作用:where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。


set的作用:set元素会动态前置SET关键字(update set语句的set关键字) ,同时会删除无关的逗号。

语句类似下面的效果:

<update id="updateBlog" parameterType="map">
    update mybatis.blog
    <set>
        <if test="title != null">
            title = #title,
        </if>
        <if test="author != null">
            author = #author
        </if>
    </set>
    where id = #id
</update>

trim元素有四个属性:

  • prefix属性:给语句开头添加prefix的值。
  • prefixOverrides属性:语句开头如果匹配到prefixOverrides属性值,就移除。
  • suffix属性:给语句末尾添加suffix的值。
  • suffixOverrides属性:语句末尾如果匹配到suffixOverrides属性值,就移除。

如下:

<update id="updateBlog" parameterType="map">
    update mybatis.blog
    <trim prefix="set" suffixOverrides="," suffix="where id = #id">
        <if test="title != null">
            title = #title,
        </if>
        <if test="author != null">
            author = #author,
        </if>
    </trim>
</update>

1.5 动态SQL之 choose(when ,otherwise) 语句


<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #title
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #author.name
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

choose,when,otherwise。就类似Java代码中的switch,case,default。


BlogMapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.BlogMapper">

    <select id="queryBlogChoose" parameterType="map" resultType="com.itholmes.pojo.Blog">

        select * from mybatis.blog
        <where>
            <choose>
                <when test="title != null">
                    -- 这里不需要and,因为第一个元素前面是where。
                    title = #title;
                </when>
                <when test="author != null">
                    and author = #author
                </when>
                <otherwise>
                    and views = #views
                </otherwise>
            </choose>
        </where>

    </select>

</mapper>

BlogMapper接口类:

package com.itholmes.dao;

import com.itholmes.pojo.Blog;

import java.util.List;
import java.util.Map;

public interface BlogMapper 
    //choose测试
    List<Blog> queryBlogChoose(Map map);

测试类:

 public void test3()
     SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
     BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
     HashMap map = new HashMap();

//        map.put("title","数据结构");
//        map.put("author","张三");
     map.put("views",999);

     List<Blog> list = mapper.queryBlogChoose(map);

     for (Blog blog : list) 
         System.out.println(blog);
     
     sqlSession.close();
 

1.6 动态SQL之 sql片段


有的时候,我们可能会将一些公共的部分抽取出来,方便复用。

第一步:使用sql标签定义公共部分。

<sql id="if-title-author">
    <if test="title != null">
        and title = #title
    </if>
    <if test="author != null">
        and author = #author
    </if>
</sql>

第二步:在需要使用的地方使用include标签引用即可。

<select id="queryBlogIF" parameterType="map" resultType="com.itholmes.pojo.Blog">
    select * from mybatis.blog
    <where>
        <include refid="if-title-author"></include>
    </where>
</select>

sql片段的注意事项:

  • 最好基于单表来定义SQL片段。
  • sql标签中,不要存在where标签。

1.7 动态SQL之 foreach 语句


foreach元素的作用:对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

foreach很简单,对应他们的属性名就能理解如下:

<!--
    使用foreach进行查询。

    演示下面的语句:
    select * from mybatis.blog where 1=1 and (id = 1 or id = 2 or id = 3);

    这里接受的一个map,这个map中可以存一个集合。
-->
<select id="queryBlogForeach" parameterType="map" resultType="com.itholmes.pojo.Blog">
    select * from mybatis.blog
    <where>
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id = #id
        </foreach>
    </where>
</select>

2. 什么是缓存(Cache)? 缓存在架构中的作用?


我们查询数据时,首先需要连接数据库,拿到数据传到后台。这样我们每一次的查询结果,可以将它暂存到一个可以直接获取到的地方!那就是内存。而这种临时数据就是缓存了。

什么是缓存(Cache)?

  • 存在内存中的临时数据。
  • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,直接从缓存中查询,从而提高查询效率,解决高并发系统的性能问题

对于架构方面的了解:

3. Mybatis缓存



4. Mybatis 一级缓存

4.1 准备工作 和 一级缓存的案例


User实体类:

package com.itholmes.pojo;

import lombok.Data;

@Data
@AllArgsConstructor
public class User 
    private int id;
    private String name;
    private String pwd;

UserMapper接口类:

package com.itholmes.dao;

import com.itholmes.pojo.User;
import org.apache.ibatis.annotations.Param;

public interface UserMapper 
    //查询指定id的用户给
    User queryUsers(@Param("id") int a);

UserMapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itholmes.dao.UserMapper">
    <select id="queryUsers" parameterType="int" resultType="User">
        select * from user where id = #id;
    </select>
</mapper>

测试类:

import com.itholmes.dao.UserMapper;
import com.itholmes.pojo.User;
import com.itholmes.utils.MybatisSqlSession;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;

public class test 
    @Test
    public void test()
        SqlSession sqlSession = MybatisSqlSession.getMybatisSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user1 = mapper.queryUsers(1);
        System.out.println(user1);

        System.out.println("===================");

        User user2 = mapper.queryUsers(1);
        System.out.println(user2);

        System.out.println("user1 和 user2 是否相等:" + (user1==user2));

        sqlSession.close();
    


我们从执行结果得出,两次相同的查询,仅仅调用了一次sql,并且得到的对象相同(对象地址相同),这第二次查询就用到了缓存的效果。这里mybatis默认是开启一级缓存的。

4.2 一级缓存 失效(清理)的情况


缓存必须要有失效的情况(失效了,就要清理缓存),如果数据库的数据发生了变化,而缓存没有,这样拿到的数据就有大问题了!!

缓存失效的情况:

  • 1.插叙不同的数据。
  • 2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存!!例如:
import com.itholmes.dao.Mybatis 学习笔记总结

Mybatis 学习笔记总结

MyBatis学习笔记总结

MyBatis学习笔记总结

mybatis学习笔记(11)-多对多查询

MyBatis学习笔记 —— MyBatis核心配置文件详解