MyBatis,从0到0.8

MyBatis,从0到0.8,第1张

MyBatis,从0到0.8

目录

一,简介

二,mybatis执行原理

1,环境搭建原理

2,功能、生命周期和作用域

三,搭建环境(基于Maven构建项目)

 1,引入依赖

2,编写mybatis核心xml配置文件

3,编写返回SqlSession的工具类

4,创建实体类

5,编写*Mapper接口类

6,编写*Mapper.xml映射文件

 7,测试

四、配置文件XML

 1,配置文档的顶层结构

2,properties(属性)

 (1)属性的三种配置方式:

(2) 三种配置方式的加载顺序和优先级

3,settings(设置)

4,typeAliases(类型别名)

(1)指定别名的两种方式

(2)Mybatis内置的常见的 Java 类型的类型别名

 3,typeHandlers(类型处理器)

4,objectFactory(对象工厂)

5,plugins(插件)

6,environments(环境配置)——重要

(1)配置多个环境:

 (2)配置说明​

(3) 事务管理器

(4)dataSource(数据源)

7,mappers(映射器)

五,XML映射文件

1,xml映射文件的顶层标签

2,< select>标签

 3,< insert>、< update>、< delete>标签

4,< sql>标签

 5,参数

6,< resultMap>标签

7,< cache/>标签——缓存

(1)mybatis缓存介绍

(2)一级缓存测试

 (3)二级缓存测试

8,< cache-red>标签

六,使用注解开发

1,编写步骤

七,mybatis日志实现

1,mybatis日志简介

2,日志配置步骤

3,打印的日志

八、动态SQL

1,< if>标签 

2,< choose>(when,otherwise)标签

3,< where>

4,< trim>

 5,< set>

 6,< foreach>


学而时习之,不亦说乎?

以前只是能在项目中使用,并不懂里面的弯弯绕,而且对mybatis的认识不系统、不深刻,故在此系统的学习一下,并总结下文。

一,简介

MyBatis是建立在JDBC之上的持久层框架,既是提供了从连接数据库、到执行sql、获取处理sql执行结果的功能,它的存在使编程变的更加快捷方便,使我们在编写程序的时候省去了很多在使用JDBC编程时需要重复写的代码,比如与数据库建立连接、创建运行sql的对象、执行sql语句、处理运行结果、  释放连接资源。同时,通过分层的思想,将业务逻辑和数据访问逻辑分离,解除了sql与程序代码的耦合。

JDBC在每次执行sql时的 *** 作步骤如下,其中①②③⑤⑦都是处处相同的代码:

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。——mybatis官网的简介

mybatis – MyBatis 3官网中文https://mybatis.org/mybatis-3/zh/index.html

二,mybatis执行原理

这一章节,有mybatis执行原理的说明,和重要概念的说明,通过这一章节的学习,可以让我对后面的第三章节环境搭建有个基本的认识,对为什么这样构建,为什么需要这个步骤,为什么需要这样的文件等,有 一定的认知。

1,环境搭建原理

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

——mybatis官网

     SqlSessionFactoryBuilder根据mybatis-config.xml配置文件中的配置调用build()构建出SqlSessionFactory对象;SqlSessionFactory对象调用它自己的openSession()方法生成一个SqlSession对象;*Mapper接口类编写增删改查的方法;*Mapper.xml配置文件编写sql语句,并绑定到*Mapper接口类中的方法;SqlSession对象调用getMapper()构建一个Mapper接口对象;通过*Mapper接口对象调用其增删改查的方法,由于这些方法被*Mapper.xml的sql绑定,所以调用*Mapper接口对象的增删改查方法,便执行了*Mapper.xml中的sql语句;接收*Mapper接口对象的增删改查方法的返回值,后续处理。
2,功能、生命周期和作用域

作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

SqlSessionFactoyBuilder、SqlSessionFactory、SqlSession 和 映射器实例 的主要功能、生命周期和作用域如下:

①SqlSessionFactoryBuilder

功能:SqlSessionFactoryBuilder主要用来创建SqlSessionFactory;生命周期:一旦创建了 SqlSessionFactory,就不再需要它了; 作用域:SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)因为它通过xml配置文件创建SqlSessionFactory,所以它占用IO资源,故不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

②SqlSessionFactory

功能:用来创建 SqlSession 接口对象,相当于一个数据库连接池;生命周期:SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在;作用域:SqlSessionFactory 的最佳作用域是应用作用域。 最简单的就是使用单例模式或者静态单例模式创建SqlSessionFactory。

③SqlSession

功能:SqlSession 就相当于一个数据库连接(Connection 对象),可以在这个连接中执行多条 SQL,使用 commit、rollback 等方法,提交或者回滚事务等;生命周期:每次需要执行SQL,就可以打开一个 SqlSession,返回一个响应后,就关闭它;作用域:它的最佳的作用域是请求或方法作用域。

④映射器实例

功能:映射器是一些绑定映射语句的接口,映射器接口的实例是从 SqlSession 中获得的;通过调用映射器的中的方法执行对应的sql语句;生命周期:映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃;映射器实例并不需要被显式地关闭;作用域:任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域。 

三,搭建环境(基于Maven构建项目)

这一章,是对整个mybatis的配置流程,执行流程,先加载配置文件确定后面mybatis的工作行为、怎么连接数据库、怎么找到编写的sql、怎么执行sql等有个整体的认知,具体的细节和更深层次的认识会在后面的第四章mybatis的核心配置文件、第五章节*Mapper.xml映射文件说明。

 1,引入依赖

    org.mybatis
    mybatis
    3.5.9

 当然,因为mybatis需要连接mysql,同时,在这里通过junit测试、lombok插件;故在这里引入响应依赖:

 
        
            mysql
            mysql-connector-java
            5.1.47
        

        
            org.projectlombok
            lombok
            RELEASE
            compile
        

        
            junit
            junit
            RELEASE
            test
        
2,编写mybatis核心xml配置文件



    
        
            
            
                
                
                
                
            
        
    
    
        
    

 具体解释可参见下文第四章节mybatis核心配置文件对xml配置文件的详解!

3,编写返回SqlSession的工具类
public class MybatisUtils {
    //静态变量被,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化
    private static SqlSessionFactory sqlSessionFactory;

    //在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
    static {
        try {
            //mybatis-config.xml配置文件的路径
            String resource = "mybatis-config.xml";
            //使用Mybatis提供的工具类Resources加载配置文件
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //使用SqlSessionFactoryBuilder类根据配置文件构建sqlSessionFactory
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取SqlSession连接
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }
}

 上面的内容只需要编写一次,下面的内容需要在 *** 作不同的数据表时编写不同的内容。

4,创建实体类
@Data
public class Books {
    private Integer id;
    private String title;
    private String author;
    private Integer sales;
    private Date published_date;
}
5,编写*Mapper接口类
public interface BooksMapper {
    List findAllBooks();
}

 当然,mybatis可以使用注解的方式直接在*Mapper接口方法上直接编写sql语句,这时就不在需要*Mapper.xml映射文件了,具体内容见第六章节。

6,编写*Mapper.xml映射文件



    标签,通过这些标签的id属性与*Mapper接口类的 方法绑定在标签中编写增删改查sql语句在需要的地方调用*Mapper接口类的方法,以执行sql语句
 
四、配置文件XML 

根据mybatis执行原理,“SqlSessionFactoryBuilder根据mybatis-config.xml配置文件中的配置调用build()构建出SqlSessionFactory对象”,也就是说之后的一切 *** 作的行为都是根据配置文件中的配置进行的!

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。——mybatis官网

 1,配置文档的顶层结构

configuration(配置)

properties(属性)settings(设置)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境配置)

environment(环境变量)

transactionManager(事务管理器)dataSource(数据源)databaseIdProvider(数据库厂商标识)mappers(映射器)

必须按照这个顺序在mybatis-config.xml文件中配置,否则会报错:

2,properties(属性)

通过标签配置的属性,可以在整个配置文件中用来替换需要动态替换的属性值;就相当于java代码中设置的常量,可以在其他地方引用,同时修改的时候只需要修改一个地方。

 (1)属性的三种配置方式:

标签的子标签中设置在标签的resource属性或url属性引入的属性文件中设置在 SqlSessionFactoryBuilder.build() 方法中传入属性值:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
(2) 三种配置方式的加载顺序和优先级
    首先读取在标签的子标签设置的属性,然后根据 标签中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性,最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。优先级最高

前面读取的属性会被后面读取的同名属性的值覆盖掉,既是加载的越晚优先级越高!

3,settings(设置)

我们通过进行设置,可以调整MyBatis的运行时的行为;比如,开启驼峰命名的自动映射、Mybatis增加到日志名称的前缀、设置数据库驱动等待数据库响应的超时时间、开启缓存等。

4,typeAliases(类型别名)

通过标签设置java类型(多为实体类)的一个名字缩写,意在降低冗余的全限定类名书写;就是:在不设置别名时,在*Mapper.xml配置文件中resultType属性设置返回值时需要指定全限定类名(报名.类名),设置别名之后,直接使用别名即可,简便了书写。

没有设置别名时:

 设置别名:

 当这样配置时,Books可以用在任何使用 com.demo.model.Books 的地方。

(1)指定别名的两种方式

在mybatis-config.xml中使用标签的子标签配置,如上图在mybatis-config.xml中使用标签的子标签


  

MyBatis会在包名下面搜索需要的java Bean,在其他地方即可直接写类型名,而不用指定包名.类型:

同时, 在每一个Java Bean(实体类)中使用@Alias注解;在没有指定注解值的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 com.demo.model.Books 的别名为 books;若有注解,则别名为其注解值:

(2)Mybatis内置的常见的 Java 类型的类型别名

它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格

别名映射的类型_bytebyte_longlong_shortshort_intint_integerint_doubledouble_floatfloat_booleanbooleanstringStringbyteBytelongLongshortShortintIntegerintegerIntegerdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalobjectObjectmapMaphashmapHashMaplistListarraylistArrayListcollectionCollectioniteratorIterator  3,typeHandlers(类型处理器)

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。

在将Sql的查询结果保存到Java对象中时,MyBatis会通过类型处理器自动的从数据库类型到java类型的类型转换;我们可以重写已有的类型处理器或创建自己的类型处理器类处理不支持或非标准的类型; 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.baseTypeHandler, 并且可以(可选地)将它映射到一个 JDBC 类型; 4,objectFactory(对象工厂)

每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。 5,plugins(插件)

MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。 6,environments(环境配置)——重要

主要用于配置数据源,以及配置 *** 作这个数据源的事务管理器。

MyBatis可以配置多个数据库源,比如在开发、测试和生产环境需要不同的配置,或想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。

(1)配置多个环境:

在通过SqlSessionFactoryBuilder.build()构建SqlSessionFactory时,传入指定的环境配置:每个 SqlSessionFactory 实例只能选择一种环境每个数据库对应一个 SqlSessionFactory 实例  (2)配置说明 (3) 事务管理器

事务管理器具体干了什么?

mybatis中有两种类型的事务管理器:JDBC、MANAGED

JDBC:

mybatis在执行事务的时候,直接使用JDBC的提交和回滚的功能,就是: *** 作事务的功能都用JDBC原有的功能,根据从数据源获得的连接管理事务作用域;MANAGED:

mybatis在管理事务时,不提交或回滚一个连接,而是让容器来管理事务的整个生命周期就是:将 *** 作事务的事情交给容器来做

 如果你正在使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置。

(4)dataSource(数据源)

配置数据源

mybatis中有三种内建的数据源类型:POOLED、UNPOOLED、JNDI

POOLED:

利用“池”的概念将 JDBC 连接对象组织起来避免了创建新的连接实例时所必需的初始化和认证时间就是:mybatis向数据库申请一定数量的连接,保存下来,用的时候取一个连接,用完在归还,省去了数据库创建连接的时间UNPOOLED:

执行sql前,mybatis向数据库发送请求,建立一个连接,mybatis与数据库交互完就把连接释放,数据库关闭连接。每次执行sql都会有建立连接、关闭连接的过程。JNDI:

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

标签用来告诉MyBatis到哪里找到我们编写的sql语句,就是让mybatis看到有这么一个编写了sql语句的文件。

mybatis提供了四种找到资源的路径:

到这里,配置文件确定了Mybatis后续工作的行为,同时,Mybatis也已经知道编写好的sql语句文件了。

后面,要确定怎么编写sql、怎么让mybatis知道要执行哪个sql。

五,XML映射文件 1,xml映射文件的顶层标签

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

cache – 该命名空间的缓存配置。cache-ref – 引用其它命名空间的缓存配置。resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。sql – 可被其它语句引用的可重用语句块。insert – 映射插入语句。update – 映射更新语句。delete – 映射删除语句。select – 映射查询语句。 2,< select>标签

在里面写select语句,并通过属性id绑定*Mapper接口方法,确定传入参数类型、返回结果类型等,通过此标签将sql语句与java代码联系起来:通过java代码调用sql执行、java代码接收sql执行的结果。

  select * from books where title = #{title} and author = #{author}

注意:也可不指定 parameterType="map",因为mybatis可通过类型处理器(TypeHandler)自动推断具体传入参数的类型。

③在调用接口方法时,给map赋值,其中key为sql中取的值,没有顺序要求

 @Test
    public void findAllBooksTest(){
        //①获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSession();

        //②获得映射器实例(*Mapper接口对象)
        BooksMapper booksMapper = sqlSession.getMapper(BooksMapper.class);

        //③调用*Mapper接口对象的方法,以执行其绑定的sql
        Map map = new HashMap<>();
        map.put("title","昨日今宵");
        map.put("author","张三");
        List books = booksMapper.findBooksByTitleAndAuthor2(map);
        
        for (Books book: books) {
            System.out.println(book);
        }
        //④关闭sqlSession
        sqlSession.close();
    }
 3,< insert>、< update>、< delete>标签

 示例:

①在*Mapper接口方法文件中,编写接口方法

    int addBook(Books book);

②在.Mapper.xml映射文件中, 指定通过parameterType属性指定传递参数类型为map

    
        insert into books(title,author,sales,published_date) values(#{title},#{author},#{sales},#{publishedDate});
    

③在调用接口方法时,给map赋值,其中key为sql中取的值,没有顺序要求

    @Test
    public void findAllBooksTest(){
        //①获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSession();

        //②获得映射器实例(*Mapper接口对象)
        BooksMapper booksMapper = sqlSession.getMapper(BooksMapper.class);

        //③调用*Mapper接口对象的方法,以执行其绑定的sql
        Books book = new Books();
        book.setAuthor("赵五");
        book.setSales(13);
        book.setTitle("秋天的童话");
        book.setPublishedDate(new Date());

        int res= booksMapper.addBook(book);

        System.out.println(book.getId());

        //④提交事务
        sqlSession.commit();
        //④关闭sqlSession
        sqlSession.close();
    }

注意:

insert、update、delete *** 作,需要通过sqlSession.commit();提交事务,否则不会将修改写入数据库中;自动生成主键,且返回到java代码中:设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性(数据表i的主键名);最后在传入的实体对象的相应属性就保存了数据库返回来的自增id值;接口的多个普通参数,用@Param标注

提示:

可以在获取SqlSession对象时在sqlSessionFactory.openSession()中配置自动提交事务:

//获取SqlSession连接
public static SqlSession getSession(){
    return sqlSessionFactory.openSession(true);
}
4,< sql>标签

通过标签,将可重用的Sql代码片段提取出来,通过标签在需要的地方引用,同时可以动态的传递标签中的参数。

 5,参数

参数类型(parameterType)会被mybatis类型处理器自动推断mode 属性允许你指定 IN,OUT 或 INOUT 参数。如果参数的 mode 为 OUT 或 INOUT,将会修改参数对象的属性值,以便作为输出参数返回。JDBC 要求,如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType)。 大多时候,你只须简单指定属性名,顶多要为可能为空的列指定 jdbcType,其他的事情交给 MyBatis 自己去推断就行了

#{}和${}区别:

使用 #{} 参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样),更安全、更迅速${}参数语法,MyBatis 不会修改或转义该字符串,常用于表名或列表动态生成用${}接受用户的输入,并用作语句参数是不安全的,会导致潜在的 SQL 注入攻击。因此,要么不允许用户输入这些字段,要么自行转义并检验这些参数

6,< resultMap>标签

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

 在这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。

①顶层标签结构

constructor - 用于在实例化类时,注入结果到构造方法中

idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能arg - 将被注入到构造方法的一个普通结果id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能result – 注入到字段或 JavaBean 属性的普通结果association – 一个复杂类型的关联;许多结果将包装成这种类型

嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用collection – 一个复杂类型的集合

嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用discriminator – 使用结果值来决定使用哪个 resultMap

case – 基于某些值的结果映射

嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射

②id & result


id 和 result 元素都将一个列的值映射到一个简单数据类型(String, int, double, Date 等)的属性或字段。id 元素对应的属性会被标记为对象的标识符

③constructor (构造方法)

 构造方法注入允许你在初始化时为类设置属性的值,而不用暴露出公有方法。

④association (关联)

关联(association)元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。

MyBatis 有两种不同的方式加载关联:

嵌套 Select 查询:通过执行另外一个 SQL 映射语句来加载期望的复杂类型。嵌套结果映射:使用嵌套的结果映射来处理连接结果的重复子集。

⑤collection (集合)

一个博客有很多文章,“有多个”类型的关系 7,< cache/>标签——缓存 (1)mybatis缓存介绍

MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。Mybatis包含两级缓存:一级缓存和二级缓存

一级缓存:

SqlSession级别的缓存,也称本地缓存;所以:仅对一个会话(SqlSession)中的数据进行缓存;所以:与数据库同一次会话期间查询到的数据会放到本地缓存中;所以:以后如果需要获取相同的数据,直接从缓存中拿,不会再去查询数据库;默认情况下,只启用了本地会话缓存;且无法手动关闭;一级缓存失效的情况:

两次查询之间执行了增删改 *** 作;(不论是否 *** 作了当前的这条数据都会令缓存失效,因为增删改 *** 作可能会对当前数据产生影响)手动清除了缓存:sqlSession.clearCache()。执行原理:

    一个sqlSession(会话)查询一条数据,这个数据就会被放在当前sqlSession的一级缓存中;如果当前sqlSession关闭了,这个sqlSession对应的一级缓存就没了;
二级缓存:

在*Mapper.xml映射文件中添加一行即可启动:

是基于namaspace级别的缓存,也叫全局缓存;所以:一个命名空间,对应一个二级缓存;Mybatis定义了缓存接口Cache,我们可以自定义二级缓存;执行原理:
    一个SqlSession(会话)查询一条数据,这个数据就会被放在当前SqlSession的一级缓存中;如果当前SqlSession关闭了,这个SqlSession对应的一级缓存就没了;如果开启二级缓存:SqlSession会话关闭时,一级缓存中的数据会被保存到二级缓存中;(一级缓存没有的时候才会将缓存数据放入二级缓存)新的SqlSession会话查询信息时,先从二级缓存中获取信息;
(2)一级缓存测试

因为一级缓存默认开启,且不需要进行配置(也没有可以手动配置的参数),所以在这里直接使用测试:

    @Test
    public void findAllBooksTest(){
        //①获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSession();

        //②获得映射器实例(*Mapper接口对象)
        BooksMapper booksMapper = sqlSession.getMapper(BooksMapper.class);

        //③调用*Mapper接口对象的方法,以执行其绑定的sql
        Books book = booksMapper.selectBookById(12);
        System.out.println(book);

        System.out.println("-----------------------------------------------------");
        Books book2 = booksMapper.selectBookById(12);
        System.out.println(book2);

        //④关闭sqlSession
        sqlSession.close();
    }

 执行结果:

 (3)二级缓存测试

①mybatis-config.xml开启全局缓存

    
        
    

② 在*Mapper.xml映射文件中配置使用二级缓存

的作用:

该*Mapper.xml文件中的所有select语句的结果都将被缓存; 该*Mapper.xml文件中的所有insert、update和delete语句会刷新缓存(缓存只作用域cache标签所在的映射文件中的语句,如果混合使用java API和XML映射文件,在公用接口中的语句将不会被默认缓存,使用@CacheNamesapceRed注解指定缓存作用域);缓存会默认使用最近最少使用算法(LRU)清除不需要的缓存;缓存不会定时进行刷新;缓存默认会保存列表或对象的1024个引用;缓存会被是为读/写缓存,所以获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所在的潜在修改。

的属性:

eviction:指定清除缓存的策略,可用清除策略如下:

LRU,最近最少使用,移除最长时间不被使用的对象,默认使用;FIFO,先进先出,按对象进入缓存的顺序来移除他们;SOF,软引用,基于垃圾回收器状态和软引用规则移除对象;WEAK,弱引用,更积极地基于垃圾收集器状态和弱引用规则移除对象。flushInterval:设置刷新时间间隔,毫秒为单位,默认不设置时没有刷新间隔;size:引用数目,默认是1024;readOnly:设置只读时,缓存的对象不能被修改,缓存会给所有调用者返回缓存相同实例;设置可读写时,缓存会通过序列化返回缓存对象的拷贝。默认false。

③对实体类实现序列化接口

所有的实体类先实现序列化接口

public class Books implements Serializable {
    .......
}

 ④测试代码

    @Test
    public void findAllBooksTest(){
        //①获取SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSession();
        //②获得映射器实例(*Mapper接口对象)
        BooksMapper booksMapper = sqlSession.getMapper(BooksMapper.class);
        //③调用*Mapper接口对象的方法,以执行其绑定的sql
        Books book = booksMapper.selectBookById(12);
        System.out.println(book);
        //④关闭sqlSession
        sqlSession.close();

        //重新开启一个SqlSession会话,进行查询
        //①获取SqlSession对象
        SqlSession sqlSession1 = MybatisUtils.getSession();
        //②获得映射器实例(*Mapper接口对象)
        BooksMapper booksMapper1 = sqlSession1.getMapper(BooksMapper.class);
        //③调用*Mapper接口对象的方法,以执行其绑定的sql
        Books book1 = booksMapper1.selectBookById(12);
        System.out.println(book1);
        //④关闭sqlSession
        sqlSession1.close();
    }

 ⑤执行结果 

 自定义缓存:除了上述mybatis自定义缓存的方式,我们也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。

8,< cache-red>标签

对某一命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。

当想要在多个命名空间中共享相同的缓存配置和实例时,使用 cache-ref 元素来引用另一个缓存。

 这时,这个*Mapper.xml中的缓存会保存在所引用的*Mapper.xml映射文件的缓存中;既是它们公用一个缓存。

六,使用注解开发

利用注解开发就不需要mapper.xml映射文件了 。将sql语句直接卸载*Mapper接口方法上,通过这个位置关系直接实现了sql语句和包.类的绑定和包.类的方法的绑定。

注解 类型主要分成 (对应sql的增删改查):

@select ()

@update ()

@Insert ()

@delete ()

1,编写步骤

只需要在前面的基础上省去*Mapper.xml文件,修改mybatis-config.xml核心配置的注入,并在接口上通过注解写上sql语句即可!

①省去*Mapper.xml文件

②在mybatis-config.xml核心配置文件注入接口

    
        
    

③在*Mapper接口方法上写上sql

    @Select("select * from books where id = #{id}")
    Books selectBookById(int id);

注意:其他内容和使用*Mapper.xml文件时保持一致! 

七,mybatis日志实现 1,mybatis日志简介

Mybatis 通过使用内置的日志工厂提供日志功能。内置日志工厂将会把日志工作委托给下面的实现之一:

SLF4JApache Commons LoggingLog4j 2Log4j (deprecated since 3.5.9)JDK logging

MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。

不少应用服务器(如 Tomcat 和 WebShpere)的类路径中已经包含 Commons Logging,所以在这种配置环境下的 MyBatis 会把它作为日志工具,我们配置的 Log4J 配置将被忽略。

如果我们的应用部署在一个类路径已经包含 Commons Logging 的环境中,而又想使用其它日志工具,我们可以通过在 MyBatis 配置文件 mybatis-config.xml 里面添加一项 setting 来选择别的日志工具。如下:


  
    ...
    
    ...
  
2,日志配置步骤

①引入log4j的jar包

        
        
            log4j
            log4j
            1.2.17
        

②log4j.properties配置文件

#设置等级为DEBUG的日志信息输出到stdout
log4j.rootLogger=DEBUG, stdout

#stdout输出的相关配置
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

③在mybatis-config.xml中添加配置

    
        
    

 也可以不添加,因为MyBatis 内置日志工厂会环境中有没有日志工具,如果有会自动启动,如果没有会禁用日志功能;

如果添加了这个配置,MyBatis会优先采用这个配置下指定的日志工具,不会先采用被其他默认优先级更高的日志工具。

3,打印的日志

八、动态SQL

就是Mybatis提供的动态拼接sql的语法规则,根据条件判断某部分sql要不要拼接。

mybatis提供的用于动态SQL的标签:

ifchoose (when, otherwise)trim (where, set)foreach 1,< if>标签 

2,< choose>(when,otherwise)标签

3,< where>

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

4,< trim>

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

 5,< set>

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

 6,< foreach>
       collection:指定输入对象中的集合属性
       item:每次遍历生成的对象
       open:开始遍历时的拼接字符串
       close:结束时拼接的字符串
       separator:遍历对象之间需要拼接的字符串
       select * from blog where 1=1 and (id=1 or id=2 or id=3)

 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。


脑壳痛,整天内容大概根据mybatis的编写步骤构建了mybatis的整体,同时在每个步骤深入展示了重要的应该注意的东西;进行了一定的理解和自己的说明,总体觉得还行。但缺乏spingboot集成mybatis的部分。

剩下的就通过在项目中应用的过程深入理解吧。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5706805.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存