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

【Mybatis】笔记完整版

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

【Mybatis】笔记完整版

文章目录
  • 1、Mybatis简介
    • 1.1 什么是Mybatis
    • 1.2 获取Mybatis
    • 1.3 持久化与持久层
    • 1.4 为什么需要Mybatis?
  • 2、第一个Mybatis程序
    • 2.1 搭建环境
    • 2.2 创建项目
    • 2.3 创建模块
    • 2.4 IDEA连接数据库(可选)
    • 2.5 编写代码
    • 2.6 测试
    • 2.7 错误分析
  • 3、Mybatis增删改查实现
    • 3.1 namespace
    • 3.2 select
      • 3.2.1 步骤详解
    • 3.3 insert
    • 3.4 update
    • 3.5 delete
    • 3.6 错误分析
  • 4、Map的使用
  • 5、模糊查询拓展
  • 6、XML配置解析
    • 6.1 属性优化
      • 6.1.1 核心配置文件
      • 6.1.2 环境配置(environments)
      • 6.1.3 事务管理器(transactionManager)
      • 6.1.4 数据源(dataSource)
      • 6.1.5 属性(properties)
    • 6.2 别名优化
      • 6.2.1 类型别名(typeAliases)
      • 6.2.2设置(settings)
    • 6.3 其他配置【了解即可】
    • 6.4 映射器(mappers)
  • 7、生命周期和作用域(Scope)
  • 8、解决属性名和字段名不一致的问题
    • 8.1 问题
    • 8.2 解决方法
  • 9、resultMap结果集映射
  • 10、日志
    • 10.1 日志工厂
    • 10.2 log4j
      • 10.2.1 什么是Log4j?
      • 10.2.2 配置log4j文件
      • 10.2.3 log4j简单测试使用
      • 10.2.4 IDEA无法打开log文件的处理方法
  • 11、分页
    • 11.1 Limit实现分页
    • 11.2 【不建议使用】RowBounds实现分页
    • 11.3 分页插件
  • 12、使用注解开发
    • 12.1 面向接口编程
    • 12.2 使用注解开发
  • 13、Mybatis执行流程
  • 14、使用注解实现增删改查
    • 14.1 注解实现增删改查
    • 14.2 关于@Param()注解
    • 14.3 #{} 和 ${}区别
  • 15、Lombok的使用
  • 16、多对一处理
    • 16.1 测试环境搭建
        • 16.1.1 基本环境准备
        • 16.1.2环境搭建
        • 16.1.3 目录结构
    • 16.2 按照查询嵌套处理
    • 16.3 按照结果嵌套处理
    • 16.4 回顾MySQL多对一查询方式
  • 17、一对多处理
    • 17.1 按照结果嵌套处理
    • 17.2 按照查询嵌套处理
  • 18、总结多对一和一对多
  • 19、动态SQL
    • 19.1 环境搭建
    • 19.2 IF
    • 19.3 choose、when、otherwise
    • 19.4 trim(where、set)
    • 19.5 foreach
    • 19.6 SQL片段
  • 20、缓存
    • 20.1 简介
    • 20.1 Mybatis缓存
    • 20.2 一级缓存
    • 20.3 二级缓存
    • 20.4 缓存原理
    • 20.5 自定义缓存EhCache


1、Mybatis简介 1.1 什么是Mybatis

什么是Mybatis:Mybatis是一款优秀的持久层框架,它支持定制化SQL,存储过程以及高级映射(方面写SQL)。
Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。
Mybatis可以使用简单的xml或注解来配置和映射原生类型、接口和Java的POJO(Plain Old Objects,普通老式Java对象)为数据库中的记录。

Mybatis本是Apache的一个开源项目,2013年迁移到GitHub。

1.2 获取Mybatis

Maven仓库:https://mvnrepository.com/



    org.mybatis
    mybatis
    3.5.7


GitHub仓库:https://github.com/

中文帮助文档:https://github.com/tuguangquan/mybatis

1.3 持久化与持久层

数据持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程。
内存的特性:断电即失。

为什么需要持久化?
有一些对象,不能让他丢掉。内存太贵。

持久层:完成持久化工作的代码块。层是界限十分明显的。

1.4 为什么需要Mybatis?

帮助程序员将数据存入数据库中。
特性:方便。传统的JDBC代码太复杂。简化,有现成的框架。自动化操作。
使用的人多!!!!



2、第一个Mybatis程序

思路:搭建环境---->导入Mybatis---->编写代码---->测试

帮助文档传送门:Mybatis帮助文档

2.1 搭建环境

搭建数据库

Create database mybatis;
use mybatis;

create table user(
						id int(20) not null PRIMARY key,
						name VARCHAr(255) not null,
						pwd VARCHAr(255) not null
					
)ENGINE=INNODB DEFAULT CHARSET=utf8;


INSERT into user(id,name,pwd) VALUES
(1,'张三','123456'),
(2,'李四','123456'),
(3,'王五','123456');

2.2 创建项目

创建一个普通的Maven项目,及时将path文件修改为正确的目录,避免占用C盘资源。


删除src目录,可以当做父工程使用。


在pom.xml文件中导入依赖


    
        
        
            mysql
            mysql-connector-java
            5.1.47
        
        
        
            org.mybatis
            mybatis
            3.5.2
        
        
        
            junit
            junit
            4.12
        
    

2.3 创建模块

new---->Module---->Maven,在resources里新建一个xml配置文件


  1. 编写Mybatis工具类

理解:
String resource = "org/mybatis/example/mybatis-config.xml";读取配置文件
然后封装成一个工具类。
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

Mybatis工具类:

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {


        try {
            //使用Mybatis第一步,必须要做!!!
            //获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    //org.apache.ibatis.session.SqlSession 提供了在数据库执行 SQL 命令所需的所有方法

    public static SqlSession getSqlSession() {

        return sqlSessionFactory.openSession();
    }
}

  1. 编写Mybatis的核心配置文件。

Mybatis-config.xml(注意这里测试常见报错)






    
        
            
            
            
                
                
                
                
                
            
        
    
  
  


2.4 IDEA连接数据库(可选)

为了方便显示数据库内的数据,可在IDEA中连接数据库。

  1. 点击Database,点击+号,添加Data Source中的MySQL,

  1. 在General中输入User(账号)、Password(密码),点击Test Connection测试连接,成功后点击Schemas。

  1. 在Schemas中勾选需要用到的数据库,点击OK即可。

2.5 编写代码
  1. 实体类

文件:User
位置:

//实体类

public class User {
    private int id;
    private String name;
    private String pwd;

    public User() {
    }

    public User(int id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + ''' +
                ", pwd='" + pwd + ''' +
                '}';
    }
}



  1. Mapper接口

文件:UserDao(Dao等价于Mapper。)
位置:

//Dao等价于Mapper

public interface UserDao {
    List getUserList();
}

  1. 接口实现类

由原来的UserDaoImpl转变为一个Mapper配置文件
文件:UserMapper.xml
位置:






    
    
    
        select *
        from mybatis.user
        where id = #{id}
    
  
  1. 测试。(增删改需要提交事务)
 //增删改需要提交事务
    //测试插入
    @Test
    public void addUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.addUser(new User(4, "小雷", "123456"));

        //提交事务
        sqlSession.commit();

        //关闭SqlSession
        sqlSession.close();

    }

3.3 insert

注意:增删改需要提交事务






  
    
    
        insert into mybatis.user(id, name, pwd)
        values (#{id}, #{name}, #{pwd})
    
  

3.4 update

注意:增删改需要提交事务






  
    
        update mybatis.user
        set name = #{name},
            pwd  = #{pwd}
        where id = #{id}
    
  

3.5 delete

注意:增删改需要提交事务






  

        delete from mybatis.user
        where id = #{id}
    
  

3.6 错误分析

标签不能匹配错,标签必须相对应,插入就插入,查询就查询。

resources文件夹下的xml中,mappers标签中的resource值中的不是.,而是/符号。


    
        
    

程序配置文件,必须符合规则!!


NullPointerException空指针异常报错,原因是没有注册到资源!!

输出的xml文件中存在中文乱码问题!

Maven资源无法导出问题,解决---->在Maven中加入build,详情见Maven资源无法导出



4、Map的使用

假设,实体类或数据库中的表,字段或者参数过多,应当考虑使用Map!

   //万能的Map
    int addUser2(Map map);
  
    
        insert into mybatis.user(id, name, pwd)
        values (#{userid}, #{username}, #{password})
    
@Test
    public void addUser2() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        Map map = new HashMap();
        map.put("userid",5);
        map.put("username","Hello");
        map.put("password",222333);

        mapper.addUser2(map);

        //提交事务
        sqlSession.commit();

        //关闭SqlSession
        sqlSession.close();

    }

Map传递参数,直接在SQL中取出key即可!parameterType="map"
对象传递参数,直接在SQL中取出对象的属性即可!parameterType="Object"
只有 一个基本类型参数的情况,直接在SQL中取到! 省略不写

多个参数用Map!,或注解!



5、模糊查询拓展

模糊查询怎么写?
传送门:MySQL的模糊查询
在Java代码查询执行的时候,传递通配符% %

接口类

public interface UserMapper {

    //模糊查询一个用户
    List getUserLike(String value);
}

接口实现类

 
     理解: 

在environments标签中可以配置多个environment环境,但是默认是environments default=后的id。
若想更换默认环境,则修改default的id值即可。



  
    
        
           
        
      
           
        
    

不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。


6.1.3 事务管理器(transactionManager)

了解即可

在 MyBatis 中有两种类型的事务管理器(也就是 type=“[JDBC|MANAGED]”):

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  • MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。

6.1.4 数据源(dataSource)

了解即可
池:用完可以回收。
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
大多数 MyBatis 应用程序会按示例中的例子来配置数据源。虽然数据源配置是可选的,但如果要启用延迟加载特性,就必须配置数据源。

有三种内建的数据源类型(也就是 type=“[UNPOOLED|POOLED|JNDI]”):
**UNPOOLED **– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。
POOLED – 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。

JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。


重点
Mybatis默认的事物管理器就是JDBC,连接池就是POOLED。


6.1.5 属性(properties)

我们可以通过properties属性来实现引用配置文件。

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。

编写一个配置文件
db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF8
username=root
password=123456

在核心配置文件mybatis-config.xml中引入properties
注意:在xml中,所有的标签都可以规定其顺序,properties只能放在最上面


    
        
        
    

注意:可以直接引入外部文件,也可以在其中增加一些属性配置,如果两个文件有同一字段,优先使用外部配置文件!
优先使用外部配置文件理解:当配置文件db.properties中写了username和password,核心配置文件mybatis-config.xml中的properties标签中也写了username和password,则优先使用db.propertise文件中的配置信息。


6.2 别名优化 6.2.1 类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

方式一:

原来是这样:注意resultType:


    
    
        select *
        from mybatis.user;
    
  

方式二:

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean ,比如:
扫描实体类的包,它的默认别名就为这个类的类名,首字母小写!

在核心配置文件mybatis-config.xml中添加别名配置。


    
        
    

这样接口实现类中resultType值可优化为:(建议小写)

 
    
        select *
        from mybatis.user
        where id = #{id};
    
  • resultMap元素是 MyBatis 中最重要最强大的元素。
  • ResultMap的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
  • ResultMap最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显示地用到他们。
    • 理解:字段一样的地方可以省略不写,只写需要映射的字段即可。


10、日志 10.1 日志工厂

Mybaits:settings(设置)

如果一个数据库操作,出现了异常,需要排错。日志就是最好的助手!
以前:sout、debug;
现在:日志工厂。

  • SLF4J
  • LOG4J【掌握】
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING 【掌握】
  • NO_LOGGING

在Mybatis中具体使用哪一个日志实现,在设置中设定。

核心配置文件顺序:

STDOUT_LOGGING标准日志输出
在Mybatis核心配置中,配置日志!


        
        

效果:


10.2 log4j

Mybaits官网传送门:settings(设置)

10.2.1 什么是Log4j?

Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件;
可以控制每一条日志的输出格式;
通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程;
通过一个配置文件来灵活地进行配置,不需要修改应用的代码。


10.2.2 配置log4j文件
  1. 在pom.xml中导入log4j的包。

传送门:Maven官网导log4j



    log4j
    log4j
    1.2.17

  1. 添加log4j.properties配置文件。
#将等级为DEBUG的日志信息输出的位置,console为输出到控制台,file为输出到文件,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/shun.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
  1. 在核心配置文件Mybatis-config.xml配置log4j为日志的实现。

    


10.2.3 log4j简单测试使用
  1. 在要使用Log4j的类中,导入包import org.apache.log4j.Logger;,注意:包不能导错,要导Apache的。
  2. 日志对象,参数为当前类的class:
static Logger logger = Logger.getLogger(UserMapperTest.class);
  1. 日志级别。
 @Test
    public void testLog4j(){

        logger.info("info:进入了testLog4j方法");
        logger.debug("debug:进入了testLog4j方法");
        logger.error("error:进入了testLog4j方法");

    }
  1. 运行后会自动生成log日志文件,相当于在程序中加入System.out.println(info)一样,在log日志文件可以清晰的看到日志信息。

10.2.4 IDEA无法打开log文件的处理方法

IDEA有的时候无法打开一些后缀的文件,可以在File-settings-Editor-File Types中添加想要打开的文件类型。

再次回到IDEA打开log文件, 此时IDEA会弹出如下提示,也就是安装log文件的插件,点击Install plugins安装插件之后,也就可以正常查看文件了。



11、分页 11.1 Limit实现分页

为什么要分页?

  • 减少数据的处理量

使用Limit分页:

语法 : select * from user limit startIndex, pageSize;

startIndex为起始位置,从哪里开始查,pageSieze为每页显示多少个。

select * from user limit 3;
# 相当于select * from user limit 0,3;

使用Mybatis实现分页,核心为SQL。

  1. 接口
List getUserByLimit(Map map);
  1. Mapper.xml

   
        select *
        from mybatis.user limit #{startIndex},#{pageSize};
    
  1. 测试
@Test
    public void getUserByLimit() {

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        HashMap map = new HashMap();

        map.put("startIndex", 0);
        map.put("pageSize", 2);

        List userList =  mapper.getUserByLimit(map);

        for (User user : userList) {
            System.out.println(user);
        }

        sqlSession.close();
    }

11.2 【不建议使用】RowBounds实现分页

不再使用Sql实现分页

  1. 接口
//RowBounds实现分页
    List getUserByRowBounds();
  1. mapper.xml

    
        select *
        from teacher
        where id = #{id};
    



public class MyTest {

    @Test
    public void testStudent(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List studentList = mapper.getStudent();
        for (Student student : studentList) {
            System.out.println(student);
        }
        sqlSession.close();
    }
}

16.3 按照结果嵌套处理

个人推荐使用,因为可以在SQL中调试

修改StudentMapper.xml文件。




 

    
        select s.id sid, s.name sname, t.name tname, t.id tid
        from student s,
             teacher t
        where s.tid = t.id
          and t.id = #{tid}
    

    

        
        

        
        
            
            
            
        

    
    

测试类:

 @Test
    public void test1() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }

17.2 按照查询嵌套处理

TeacherMapper.xml文件






    
    
        select *
        from student
        where tid = #{tid}
    



测试类:

@Test
    public void test2() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);
        sqlSession.close();
    }


18、总结多对一和一对多
  1. 关联 - association(多对一)

  2. 集合 - collection(一对多)

  3. JavaType:用来指定实体类中属性我的类型。

  4. OfType:用来指定映射到List或集合中的pojo类型,泛型中的约束类型。

注意点:

  • 保证SQL的可读性,尽量保证通俗易懂。
  • 注意一对多和多对一中,属性名和字段的问题。
  • 如果问题不好排查错误,可以使用日志,建议使用Log4j

19、动态SQL

什么是动态SQL?

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

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

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

19.1 环境搭建

创建一个SQL表,字段:id,title,author,create_time,views。

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

创建一个基础工程

目录结构:

  1. 在pom.xml文件导包


    
        Mybatis-Study
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    Mybatis-SQL

    
        8
        8
    


    
        
        
            org.projectlombok
            lombok
            1.18.22
            provided
        
    


  1. MybatisUtils工具类
//工具类
//sqlSessionFactory  工厂模式

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {


        try {
            //使用Mybatis第一步,必须要做!!!
            //获取SqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    public static SqlSession getSqlSession() {
        //openSession方法的自动提交设置为true就会自动提交了
        return sqlSessionFactory.openSession(true);
    }
}

  1. properties属性
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF8
username=root
password=123456

  1. 核心配置文件Mybatis-config.xml






    
    
    

    
        

        
        
    

    
    
        
    

    
        
            
            
            
                
                
                
                
                
            
        
    

    
        
    



  1. 编写实体类
@Data
public class Blog {

    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
}

  1. 实体类对应的Mapper接口和Mapper.xml文件。

接口:

public interface BlogMapper {

    //插入数据
    //新增一个博客
    int addBlog(Blog blog);
}

sql配置文件:






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



  1. 拓展(IDUtils工具类)
//抑制警告,让黄色警告不提示
@SuppressWarnings("all")
public class IDUtils {

    public static String getId() {

        //获取UUID,生成随机数
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
}

  1. 测试类(初始化数据)
public class MyTest {

    @Test
    public void addBlogTest() {
        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();
    }
}

初始化数据完毕!

19.2 IF

作用:相当于SQL中的IF语句检索查询

官网定义的固定格式:if中的test为固定


	select * from 表
    
    	
            ……
        
        
        	and ……
        
        
        	and ……
        
    

只要找到满足的,下面的都不会执行,跟Switch中的case原理一样。


	select * from 表
    
        
        	   ……
        
    	
            and ……
        
    

使用where标签后SQL语句写select * from 表即可,无需写where,同时能将if标签中的and、or去掉,保证字符串正确拼接。相当于select * from blog where title = #{title}。

当使用where标签后,里什么都不写,它也会自动取出where。相当于select * from blog。

例如:


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

set

用于动态更新语句的类似解决方案叫做 setset 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。


	update 表
    
        
       		 ……,
        
        
        	 ……,
        
    
   		where id = #{id};

例如:


    
        update blog

        
            
                title = #{title},
            
            
                author = #{author}
            
        
            where id = #{id};
    

trim

set 元素等价的自定义 trim 元素。


  ...

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

19.5 foreach

不常用

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

准备:将数据库中前三个数据的id修改为1,2,3;

需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息

  1. 接口
List queryBlogForeach(Map map);
  1. 编写SQL语句

        select *
        from blog
        
            
        
    

注意:

  • 最好基于单表来定义SQL片段!(不要做太复杂的事情)
  • 不要存在标签。

20、缓存 20.1 简介

问题:查询需要连接数据库,耗资源。

内存:一次查询的结果,给它暂存在一个可以直接取到的地方(内存),再次查询相同数据的时候,直接走缓存,就不用连接数据库了。

1、什么是缓存 [Cache]?

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

2、为什么使用缓存?

  • 减少和数据库的交互次数,减少系统开销,提高系统效率。

3、什么样的数据能使用缓存?

  • 经常查询并且不经常改变的数据。【可以使用缓存】
  • 不经常查询且经常改变的数据【不可以使用缓存】

20.1 Mybatis缓存

Mybatis包含一个非常强大的缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。

Mybatis系统中默认定义了两级缓存:一级缓存和二级缓存

  • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
  • 二级缓存需要手动开启和配置,它是基于namespace级别的缓存。
  • 为了提高扩展性,Mybatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存。

20.2 一级缓存

一级缓存也叫本地缓存:SqlSession

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中获取,没必要再去查询数据库。

测试步骤

  1. 开启日志【mybatis-config.xml】!
  
        
    
  1. 编写接口【UserMapper.java】。
//根据id查询用户
User queryUserById(@Param("id") int id);
  1. 接口对应的Mapper文件【UserMapper.xml】。

  1. 测试在一个Session中查询两次相同的记录【MyTest.java】。
@Test
    public void test1() {

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.queryUserById(1);
        System.out.println(user);

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

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

        System.out.println(user == user2);
        
        sqlSession.close();
    }
  1. 查看日志输出。

缓存失效的情况:

  1. 查询不同的东西。

  2. 增删改操作,可能会改变原来的数据,所以必定会刷新缓存!

  1. 查询不同的Mapper.xml。

  2. 手动清理缓存!

//手动清理缓存
sqlSession.clearCache();

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

一级缓存就是一个Map,用的时候取,用完就崩掉不用了。

20.3 二级缓存

二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存。

基于namespace级别的缓存,一个名称空间,对应一个二级缓存;

工作机制:

  • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
  • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
  • 新的会话查询信息,就可以从二级缓存中获取内容;
  • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

测试步骤

  1. 开启全局缓存【mybatis-config.xml】。

  1. 在要使用二级缓存的Mapper中开启【xxxxMapper.xml】(一般就够了)。


也可以自定义参数,官方示例查看官方文档




  1. 测试

报错问题:需要将实体类序列化!!!否则就会报错。

解决:标签中加入redonly=true即可。

@Test
    public void test1() {

        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 user2 = mapper2.queryUserById(1);
        System.out.println(user2);

        System.out.println(user == user2);

        sqlSession2.close();
    }

当第一次缓存关闭后,会存入二级缓存,无需再查询数据库。

小结:

只要开启了二级缓存,在同一个Mapper下就有效。

所有的数据都会先放在一级缓存中;

只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中。

20.4 缓存原理

20.5 自定义缓存EhCache

Ehcache是一种广泛使用的java分布式缓存,用于通用缓存;

现在使用较少,目前已经广泛使用Redis缓存。

需要:要在应用程序中使用Ehcache,需要引入依赖的jar包【pom.xml】。



   org.mybatis.caches
   mybatis-ehcache
   1.1.0

  1. 在Mapper.xml中加入缓存配置。
   
  1. 编写ehcache.xml文件,如果在加载时未找到/ehcache.xml资源或出现问题,则将使用默认配置。


   
   
   
   

   
   
   


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

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

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