栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

不能吧,你不能这样,都最后了-------sql和缓存(“最易懂得MyBatis学习”)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

不能吧,你不能这样,都最后了-------sql和缓存(“最易懂得MyBatis学习”)

 哇 咔 咔 : textcolor{blue}{哇咔咔:} 哇咔咔: 古 娜 拉 黑 暗 之 神 , 请 赐 予 我 力 量 , 让 我 起 个 床 textcolor{green}{古娜拉黑暗之神,请赐予我力量,让我起个床} 古娜拉黑暗之神,请赐予我力量,让我起个床
gitee中MyBatis学习源码所用到的代码都可以在这里找到

mybatis动态sql和缓存
    • 十二、动态SQL
      • 1. 搭建环境
      • 2. 创建一个基础工程
        • 2.1导包
        • 2.2 编写配置文件
        • 2.3 编写实体类
        • 2.4 编写实体类对应的Mapper接口和Mapper.xml文件
        • 2.5 生成UUID的工具类
        • 2.6 测试加入数据
      • 3. if
      • 4. trim(where,set)
        • 4.1 where
        • 4.2 set
      • 5. choose(when,otherwise)
      • 6. foreach
        • 使用
      • 7. SQL片段
      • 8. 总结
    • 十三、缓存
      • 1. 简介
      • 2. Mybatis缓存
      • 3. 一级缓存
        • 3.1 测试步骤:
        • 3.2 缓存失效得情况
        • 3.3 小结
      • 4. 二级缓存
        • 4.1 简介
        • 4.2 开启步骤
        • 4.3 测试
        • 4.4 小结
      • 5. 缓存原理
      • 6. 自定义缓存-Ehcache

十二、动态SQL

mybatis中的sql

什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。

1. 搭建环境
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
2. 创建一个基础工程 2.1导包

    
        org.projectlombok
        lombok
        1.18.20
    

2.2 编写配置文件

mybaits-config.xml和db.properties

2.3 编写实体类
import lombok.Data;

import java.util.Date;

@Data
public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;//属性名和字段名不一致
    private int views;
}

2.4 编写实体类对应的Mapper接口和Mapper.xml文件

BlogMapper和BlogMapper.xml





    
    

    
        
        
        
    
    
    
    
        
    

    
        
            
            
            
                
                
                
                
            
        
    

    
        

    



2.5 生成UUID的工具类
import java.util.UUID;

@SuppressWarnings("all")//抑制警告
public class IDutils {
    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }
}
2.6 测试加入数据
public interface BlogMapper {
    //插入数据
    int addBlog(Blog blog);
}





    
        insert into blog (id,title,author,create_time,views)
        values (#{id},#{title},#{author},#{createTime},#{views});
    


import com.hxl.dao.BlogMapper;
import com.hxl.pojo.Blog;
import com.hxl.utils.IDutils;
import com.hxl.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;

public class MyTest {
    @Test
    public void addInitBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = new Blog();
        blog.setId(IDutils.getId());
        blog.setTitle("Mybatis");
        blog.setAuthor("王木木");
        blog.setCreateTime(new Date());
        blog.setViews(9999);
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Java");
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("Spring");
        mapper.addBlog(blog);

        blog.setId(IDutils.getId());
        blog.setTitle("微服务");
        mapper.addBlog(blog);

        sqlSession.close();
    }
}
  • 出现了问题

    他说是无效绑定。

    这里需要绑定,但是我是绑定了的,所以又进行了下面的操作

    • 在pom文件下加入下面的话既可以解决,加入后记得刷新maven

    • 
          
              
                  src/main/resources
                  
                      ***.xml
                  
                  true
              
              
                  src/main/java
                  
                      ***.xml
                  
              
              
                  src/main/resources
                  true
              
          
          
              
                  org.apache.maven.plugins
                  maven-resources-plugin
                  
                      UTF-8
                  
              
          
      
      

  • 我觉得出现上述的问题是因为我的BlogMapper.xml是放在src/main/java/com/hxl/dao下的。而不是像上面的那个放在resources下的。所以出现了那个问题。

3. if
List queryBlogIF(Map map);

  select * from blog
  
      
          title = #{title}
      
      
          and author = #{author}
      
  

  • where元素只会在至少有一个子元素的条件返回SQL子句的情况下采取插入“WHERe”自子句,而且,若语句的开头为“AND“或”OR“,where元素也会将它们去除。

    • 我们很容易看到,之前提到的if是用了一个where 1=1.其实这个是不合适的。但是现在加了个标签,它可以自动识别是不是第一个where,然后在判断是否加上and。
    • where的存在会判断and是不是需要,第二个前面及以后要加上and。

如果 where 元素与你期望的不太一样,你也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:


  ...

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

4.2 set
  • set元素会动态前置SET关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的SQL语句的后面留下这些逗号

  update blog
  
      
          title = #{title},
      
      
          author = #{author},
      
  
  where id = #{id}

@Test
public void updateBlog(){
  SqlSession sqlSession = MybatisUtils.getSqlSession();
  BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
  HashMap map = new HashMap();
  map.put("id","ac040b29e3b047a09a4fe78797193597");
  map.put("author","王木木");
  map.put("title","Java1");
  mapper.updateBlog(map);
  sqlSession.close();
}

来看看与 set 元素等价的自定义 trim 元素吧:


  ...

注意,我们覆盖了后缀值设置,并且自定义了前缀值。

5. choose(when,otherwise)

    select * from blog
    
        
    

  • 注意事项:

    • 最好基于单表来定义SQL片段
    • 不要存在where标签
  • 8. 总结

    所谓的动态SQL,本质还是SQL语句,只是我们可以在sql层面,去执行一个逻辑代码。

    if,where,set,choose,when

    动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL的格式,去排列组合就ok了

    建议:

    • 先在Mysql中写出完整的SQL,再对应的去修改成为我们的动态SQL。实现通用。
    十三、缓存 1. 简介
    查询-->需要连接数据库,耗资源
    	一次查询的结果,给他暂存一个可以直接取到的地方-->内存:缓存
    我们再次查询相同数据的时候,直接走缓存,就不用走数据库了 
    
    1. 什么是缓存[Cache]?
      • 存在内存中的临时数据
      • 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
    2. 为什么要使用缓存?
      • 减少和数据库的交互次数,减少系统开销,提高系统效率
    3. 什么样的数据能使用缓存?
      • 经常查询并且不经常改变的数据
    2. Mybatis缓存
    1. Mybatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大地提升查询效率。
    2. Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存
      • 默认情况下,只有一级缓存开启。(Sqlsession级别的缓存,也称为本地缓存)
      • 二级缓存需要手动开启和配置,是基于namespace级别的缓存
      • 为了提高扩展性,mybatis定义了缓存接口,我们可以通过实现Cache接口来自定义二级缓存。
    3. 一级缓存
    • 一级缓存也叫本地缓存:SqlSession
      • 与数据库同一次会话期间查询到得数据会放在本地缓存中
      • 以后如果需要获取相同得数据,直接从换从中拿,没必要再去查询数据库
    3.1 测试步骤:
    1. 开启日志

      在核心配置文件中

      
          
          
      
      
    2. 测试再一个Session中查询两次相同得记录

      @Test
      public void queryUserByIdTest(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          User user = mapper.queryUserById(1);
          System.out.println(user);
          System.out.println("========");
          User user1 = mapper.queryUserById(1);
          System.out.println(user1);
          sqlSession.close();
      }
      
    3. 查看日志输出

    3.2 缓存失效得情况
    • 查询不同得东西

    • 增删改操作可能会改变原来得数据,所以必定会刷新缓存

      • 比如说在查两个相同的用户,中间插一个修改用户的操作
    • 查询不同Mapper.xml

    • 手动清理缓存

      • sqlSession.clearCache();//手动清理缓存
        
    3.3 小结

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

    一级缓存就相当于一个map

    4. 二级缓存 4.1 简介 4.2 开启步骤
    1. 开启全局缓存

      虽然默认就是true但是还是需要显示的开启一下,增强可读性

      在核心配置文件中

      
          
          
      
      
    2. 要启用二级缓存需要在sql映射文件中添加一行代码

      
      

      也可以自定义一些参数

      
      

      还可以在你想要的地方关闭缓存,只需要在sql语句标签下添加下面的代码

    4.3 测试
    1. 如果没有加二级缓存,查询两个sqlSession是会进入两次数据库的

      @Test
      public void queryUserByIdTest(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          SqlSession sqlSession2 = MybatisUtils.getSqlSession();
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
          User user = mapper.queryUserById(1);
          System.out.println(user);
          User user1 = mapper2.queryUserById(1);
          System.out.println(user1);
      
          sqlSession.close();
          sqlSession2.close();
      }
      

    2. 如果开启了二级缓存

      @Test
      public void queryUserByIdTest(){
          SqlSession sqlSession = MybatisUtils.getSqlSession();
          SqlSession sqlSession2 = MybatisUtils.getSqlSession();
      
          UserMapper mapper = sqlSession.getMapper(UserMapper.class);
          User user = mapper.queryUserById(1);
          System.out.println(user);
          sqlSession.close();
      
          UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
          User user1 = mapper2.queryUserById(1);
          System.out.println(user1);
          System.out.println(user == user1);
          sqlSession2.close();
      }
      

    3. 问题:

      我们需要将实体类序列化,否则就会报错

      Caused by:java.io.NotSerializableException:com.hxl.pojo.User
      

      我们需要在实体类后加上implements Serializable

      @Data
      public class User implements Serializable {
          private int id;
          private String name;
          private String pwd;
      }
      
    4.4 小结
    1. 只要开启了二级缓存,在同一个Mapper下就有效
    2. 所有的数据都会先放在一级缓存中
    3. 只有当会话提交,或者关闭的时候,才会提交到二级缓存中
    4. 实体类要序列化
    5. 缓存原理

    6. 自定义缓存-Ehcache

    Ehcache是一种广泛使用的开源Java分布式缓存,主要面向通用缓存

    要在程序中使用Ehcache,先要导包

    
        org.mybatis.caches
        mybatis-ehcache
        1.2.1
    
    

    在resources下建立一个ehcache.xml文件

    
    
    
        
        
        
        
    
    

    在需要的Mapper.xml下

    
    

    测试

    转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/488862.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号