mybatis的成神之路

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: mybatis的成神之路

官方文档:https://mybatis.org/mybatis-3/zh/getting-started.html

一、简介

什么是 MyBatis?

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

二、入门

安装

要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath 中即可。

如果使用 Maven 来构建项目,则需将下面的 dependency 代码置于 pom.xml 文件中:

               <dependency>   <groupId>org.mybatis</groupId>   <artifactId>mybatis</artifactId>   <version>x.x.x</version> </dependency>              

从 XML 中构建 SqlSessionFactory

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

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

               String rejavasource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);              

XML 配置文件中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。 XML 配置文件的详细内容后面再探讨,这里先给出一个简单的示例:

               <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"   "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>   <environments default="development">     <environment id="development">       <transactionManager type="JDBC"/>       <dataSource type="POOLED">         <property name="driver" value="${driver}"/>         <property name="url" value="${url}"/>         <property name="username" value="${username}"/>         <property name="password" value="${password}"/>       </dataSource>     </environment>   </environments>   <mappers>     <mapper resource="org/mybatis/example/BlogMapper.xml"/>   </mappers> </configuration>              

当然,还有很多可以在 XML 文件中进行配置,上面的示例指出的则是最关键的部分。 要注意 XML 头部的声明,它用来验证 XML 文档正确性。environment 元素体中包含了事务管理和连接池的配置。mappers 元素则是包含一组映射器(mapper),这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。

从 SqlSessionFactory 中获取 SqlSession

既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。例如:

               try (SqlSession session = sqlSessionFactory.openSession()) {   Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101); }              

诚然,这种方式能够正常工作,并且对于使用旧版本 MyBatis 的用户来说也比较熟悉。不过现在有了一种更简洁的方式 ——使用正确描述每个语句的参数和返回值的接口(比如 BlogMapper.class),你现在不仅可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。

例如:

               try (SqlSession session = sqlSessionFactory.openSession()) {   BlogMapper mapper = session.getMapper(BlogMapper.class);   Blog blog = mapper.selectBlog(101); }              

现在我们来探究一下这里到底是怎么执行的。

探究已映射的 SQL 语句

现在你可能很想知道 SqlSession 和 Mapper 到底执行了什么操作,但 SQL 语句映射是个相当大的话题,可能会占去文档的大部分篇幅。 不过为了让你能够了解个大概,这里会给出几个例子。

在上面提到的例子中,一个语句既可以通过 XML 定义,也可以通过注解定义。我们先看看 XML 定义语句的方式,事实上 MyBatis 提供的全部特性都可以利用基于 XML 的映射语言来实现,这使得 MyBatis 在过去的数年间得以流行。如果你以前用过 MyBatis,你应该对这个概念比较熟悉。 不过自那以后,XML 的配置也改进了许多,我们稍后还会再提到。这里给出一个基于 XML 映射语句的示例,它应该可以满足上述示例中 SqlSession 的调用。

               <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"   "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.mybatis.example.BlogMapper">   <select id="selectBlog" resultType="Blog">     select * from Blog where id = #{id}   </select> </mapper>              

为了这个简单的例子,我们似乎写了不少配置,但实际上它并不多。在一个 XML 映射文件中,可以定义无数个映射语句,这样一来,XML 头部和文档类型声明占去的部分就显得微不足道了。而文件的剩余部分具备自解释性,很容易理解。 在命名空间 “org.mybatis.example.BlogMapper” 中定义了一个名为 “selectBlog” 的映射语句,允许你使用指定的完全限定名 “org.mybatis.example.BlogMapper.selectBlog” 来调用映射语句,就像上面例子中那样:

               Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);              

你可能注意到这和使用完全限定名调用 Java 对象的方法类似。这样,该命名就可以直接映射到在命名空间中同名的 Mapper 类,并将已映射的 select 语句中的名字、参数和返回类型匹配成方法。 因此你就可以像上面那样很容易地调用这个对应 Mapper 接口的方法,就像下面这样:

               BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101);              

第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点; 其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择已映射的 SQL 语句。

提示:对命名空间的一点说明(可能会被面试的点)

在之前版本的 MyBatis 中,命名空间(Namespaces)的作用并不大,是可选的。 但现在,随着命名空间越发重要,你必须指定命名空间。

命名空间的作用有两个,一个是利用更长的完全限定名来将不同的语句隔离开来,同时也实现了你上面见到的接口绑定。就算你觉得暂时用不到接口绑定,你也应该遵循这里的规定,以防哪天你改变了主意。 长远来看,只要将命名空间置于合适的 Java 包命名空间之中,你的代码会变得更加整洁,也有利于你更方便地使用 MyBatis。

命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。

  • 完全限定名(比如 “com.mypackage.MyMapper.selectAllThings)将被直接用于查找及使用。
  • 短名称(比如 “selectAllThings”)如果全局唯一也可以作为一个单独的引用。 如果不唯一,有两个或两个以上的相同名称(比如 “com.foo.selectAllThings” 和 “com.bar.selectAllThings”),那么使用时就会产生“短名称不唯一”的错误,这种情况下就必须使用完全限定名。

对于像 BlogMapper 这样的映射器类来说,还有另一种方法来处理映射。 它们映射的语句可以不用 XML 来配置,而可以使用 Java 注解来配置。比如,上面的 XML 示例可被替换如下:

package org.mybatis.example;publicinterfaceBlogMapper{  @Select("SELECT * FROM blog WHERE id = #{id}")  Blog selectBlog(int id);}

使用注解来映射简单语句会使代码显得更加简洁,然而对于稍微复杂一点的语句,Java 注解就力不从心了,并且会显得更加混乱。 因此,如果你需要完成很复杂的事情,那么最好使用 XML 来映射语句。

选择何种方式来配置映射,以及认为映射语句定义的一致性是否重要,这些完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。

作用域(Scope)和生命周期

理解我们目前已经讨论过的不同作用域和生命周期类是至关重要的,因为错误的使用会导致非常严重的并发问题。


提示 对象生命周期和依赖注入框架

依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。 如果对如何通过依赖注入框架来使用 MyBatis 感兴趣,可以研究一下 MyBatis-Spring 或 MyBatis-Guice 两个子项目。


SqlSessionFactoryBuilder

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。 换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。 下面的示例就是一个确保 SqlSession 关闭的标准模式:

try(SqlSession session = sqlSessionFactory.openSession()){  // 你的应用逻辑代码}

在你的所有的代码中一致地使用这种模式来保证所有数据库资源都能被正确地关闭。

映射器实例

映射器是一些由你创建的、绑定你映射的语句的接口。映射器接口的实例是从 SqlSession 中获得的。因此从技术层面讲,任何映射器实例的最大作用域是和请求它们的 SqlSession 相同的。尽管如此,映射器实例的最佳作用域是方法作用域。 也就是说,映射器实例应该在调用它们的方法中被请求,用过之后即可丢弃。 并不需要显式地关闭映射器实例,尽管在整个请求作用域保持映射器实例也不会有什么问题,但是你很快会发现,像 SqlSession 一样,在这个作用域上管理太多的资源的话会难于控制。 为了避免这种复杂性,最好把映射器放在方法作用域内。下面的示例就展示了这个实践:

try(SqlSession session = sqlSessionFactory.openSession()){  BlogMapper mapper = session.getMapper(BlogMapper.class);  // 你的应用逻辑代码}

三、配置

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  • configuration(配置)
  • environment(环境变量)
  • transactionManager(事务管理器)
  • dataSource(数据源)

属性(properties)

这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。例如:

resource="org/mybatis/example/config.properties">  name="username"value="dev_user"/>  name="password"value="F2Fa3!33TYyg"/>

然后其中的属性就可以在整个配置文件中被用来替换需要动态配置的属性值。比如:

type="POOLED">  name="driver"value="${driver}"/>  name="url"value="${url}"/>  name="username"value="${username}"/>  name="password"value="${password}"/>

这个例子中的 username 和 password 将会由 properties 元素中设置的相应值来替换。 driver 和 url 属性将会由 config.properties 文件中对应的值来替换。这样就为配置提供了诸多灵活选择。

属性也可以被传递到 SqlSessionFactoryBuilder.build()方法中。例如:

SqlSessionFactory factory =newSqlSessionFactoryBuilder().build(reader, props);// ... 或者 ...SqlSessionFactory factory =newSqlSessionFactoryBuilder().build(reader, environment, props);

如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载

  • 在 properties 元素体内指定的属性首先被读取。
  • 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
  • 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。

因此,通过方法参数传递的属性具有最高优先级resource/url 属性中指定的配置文件次之最低优先级的是 properties 属性中指定的属性

从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值。例如:

               <dataSource type="POOLED">   <!-- ... -->   <property name="username" value="${username:ut_user}"/> <!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' --> </dataSource>              

这个特性默认是关闭的。如果你想为占位符指定一个默认值, 你应该添加一个指定的属性来开启这个特性。例如:

               <properties resource="org/mybatis/example/config.properties">   <!-- ... -->   <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 启用默认值特性 --> </properties>              

提示 如果你已经使用 ":" 作为属性的键(如:db:username) ,或者你已经在 SQL 定义中使用 OGNL 表达式的三元运算符(如: ${tableName != null ? tableName : 'global_constants'}),你应该通过设置特定的属性来修改分隔键名和默认值的字符。例如:

               <properties resource="org/mybatis/example/config.properties">   <!-- ... -->   <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 --> </properties>              

               <dataSource type="POOLED">   <!-- ... -->   <property name="username" value="${db:username?:ut_user}"/> </dataSource>              

设置(settings)

这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项的意图、默认值等。

设置名

描述

有效值

默认值

cacheEnabled

全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存。

true | false

true

lazyLoadingEnabled

延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。

true | false

false

aggressiveLazyLoading

当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods)。

true | false

false (在 3.4.1 及之前的版本默认值为 true)

multipleResultSetsEnabled

是否允许单一语句返回多结果集(需要驱动支持)。

true | false

true

useColumnLabel

使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。

true | false

true

useGeneratedKeys

允许 JDBC 支持自动生成主键,需要驱动支持。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能支持但仍可正常工作(比如 Derby)。

true | false

False

autoMappingBehavior

指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。

NONE, PARTIAL, FULL

PARTIAL

autoMappingUnknownColumnBehavior

指定发现自动映射目标未知列(或者未知属性类型)的行为。

NONE: 不做任何反应

WARNING: 输出提醒日志 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN)

FAILING: 映射失败 (抛出 SqlSessionException)

NONE, WARNING, FAILING

NONE

defaultExecutorType

配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。

SIMPLE REUSE BATCH

SIMPLE

defaultStatementTimeout

设置超时时间,它决定驱动等待数据库响应的秒数。

任意正整数

未设置 (null)

defaultFetchSize

为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。

任意正整数

未设置 (null)

defaultResultSetType

Specifies a scroll strategy when omit it per statement settings. (Since: 3.5.2)

FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(same behavior with 'Not Set')

Not Set (null)

safeRowBoundsEnabled

允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。

true | false

False

safeResultHandlerEnabled

允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为 false。

true | false

True

mapUnderscoreToCamelCase

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。

true | false

False

localCacheScope

MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。

SESSION | STATEMENT

SESSION

jdbcTypeForNull

当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。

JdbcType 常量,常用值:NULL, VARCHAR 或 OTHER。

OTHER

lazyLoadTriggerMethods

指定哪个对象的方法触发一次延迟加载。

用逗号分隔的方法列表。

equals,clone,hashCode,toString

defaultScriptingLanguage

指定动态 SQL 生成的默认语言。

一个类型别名或完全限定类名。

org.apache.ibatis.scripting.xmltags.XMLLanguageDriver

defaultEnumTypeHandler

指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5)

一个类型别名或完全限定类名。

org.apache.ibatis.type.EnumTypeHandler

callSettersOnNulls

指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值初始化的时候比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。

true | false

false

returnInstanceForEmptyRow

当返回行的所有列都是空时,MyBatis默认返回 null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (如集合或关联)。(新增于 3.4.2)

true | false

false

logPrefix

指定 MyBatis 增加到日志名称的前缀。

任何字符串

未设置

logImpl

指定 MyBatis 所用日志的具体实现,未指定时将自动查找。

SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

未设置

proxyFactory

指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。

CGLIB | JAVASSIST

JAVASSIST (MyBatis 3.3 以上)

vfsImpl

指定 VFS 的实现

自定义 VFS 的实现的类全限定名,以逗号分隔。

未设置

useActualParamName

允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1)

true | false

true

configurationFactory

指定一个提供 Configuration 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3)

类型别名或者全类名.

未设置

一个配置完整的 settings 元素的示例如下:

               <settings>   <setting name="cacheEnabled" value="true"/>   <setting name="lazyLoadingEnabled" value="true"/>   <setting name="multipleResultSetsEnabled" value="true"/>   <setting name="useColumnLabel" value="true"/>   <setting name="useGeneratedKeys" value="false"/>   <setting name="autoMappingBehavior" value="PARTIAL"/>   <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>   <setting name="defaultExecutorType" value="SIMPLE"/>   <setting name="defaultStatementTimeout" value="25"/>   <setting name="defaultFetchSize" value="100"/>   <setting name="safeRowBoundsEnabled" value="false"/>   <setting name="mapUnderscoreToCamelCase" value="false"/>   <setting name="localCacheScope" value="SESSION"/>   <setting name="jdbcTypeForNull" value="OTHER"/>   <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings>              

类型别名(typeAliases)

类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:

 alias="Author"type="domain.blog.Author"/>  alias="Blog"type="domain.blog.Blog"/>  alias="Comment"type="domain.blog.Comment"/>  alias="Post"type="domain.blog.Post"/>  alias="Section"type="domain.blog.Section"/>  alias="Tag"type="domain.blog.Tag"/>

当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

 name="domain.blog"/>

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

@Alias("author")publicclassAuthor{    ...}

这是一些为常见的 Java 类型内建的相应的类型别名。它们都是不区分大小写的,注意对基本类型名称重复采取的特殊命名风格。



传对象增

传对象增,并返回ID

传map

传对象

传ID

通过ID查

通过ID、Name查

传入map查

传对象查


连表查

正常返回(one-by-one)

one-by-one

one-by-many

扩展-了解

分步查询

鉴别器 discriminator


一、动态SQL

2.1、if

2.2、choose, when, otherwise

2.3、trim, where, set

2.4、foreach

@param("xxx") 起个名字,不起试试

2.5、两个内置参数:了解

_parameter:

单个参数:_parameter代表单个的参数

多个参数:自动封装成map,_parameter代表map

_databaseId:

多数据库的支持

2.6、bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

id="selectBlogsLike"resultType="Blog">  name="pattern"value="'%' + _parameter.getTitle() + '%'"/>  SELECT * FROM BLOG   WHERE title LIKE #{pattern}

2.7、SQL标签

标签:抽取可以重用的SQL语句

标签:对sql标签进行引用

二、缓存

               MyBatis包含了一个非常强大的查询缓存特性,他可以非常方便的配置和定制。缓存可以极大地提升查询效率。 MyBatis系统中默认定义了两级缓存。 一级缓存和二级缓存     1、默认情况下,只有一级缓存(SQLSession级别的缓存,也称为本地缓存)开启。     2、二级缓存(全局缓存)需要手动开启和配置,它是基于namespace级别的缓存     3、为了提高扩展性。MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存。              

               一级缓存失效:     1、采用不同的SQLSession     2、SQLSession相同,查询条件不同(一级缓存中没有这个数据)     3、SqlSession相同,两次查询之间有增删改操作(可能对数据库有影响了)     4、sqlSession相同,手动清理了一级缓存,session.clearCache()清理一级缓存              

               二级缓存:基于namespace级别的缓存,一个namespace对应一个二级缓存     工作机制:     1、一个会话,查询一条数据,这个数据就会被放在当前的会话的一级缓存中;     2、如果会话关闭,一级缓存中的数据会被保存到二级缓存中,新的会话查询信息,就可以参考二级缓存中的内容     3、SQLSession---->> TeacherMapper -->> Teacher对象                 ----->> StudentMapper -->> Student对象                 不同namespace查出的数据会放在自己对应的缓存中                      开启全局缓存:     <settings>中cacheEnabled属性          SQL映射文件中添加下面标签     <cache       eviction="FIFO"       flushInterval="60000"       size="512"       readOnly="false"/>     eviction:缓存的回收策略         LRU – (默认的))最近最少使用:移除最长时间不被使用的对象。         FIFO – 先进先出:按对象进入缓存的顺序来移除它们。         SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。         WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。     flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。          默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。     size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。     readOnly(只读)属性可以被设置为 true 或 false。         只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。         而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。     提示 二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。      使用自定义缓存 除了上述自定义缓存的方式,你也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。 <cache type="com.domain.something.MyCustomCache"/>                  

               缓存关闭:     1、cacheEnabled:只能关闭二级缓存,不能关闭一级缓存     2、useCache:只能关闭二级缓存,不能关闭一级缓存(在select标签上使用)     3、flushCache:增删改标签,一二级都清空。增删改默认是true,查询默认是false     4、sqlSession.clearCache:只是清空当前缓存的一级缓存,不影响二级缓存      5、localCacheScope:本地缓存作用域,SESSION表示一级缓存,STATEMENT没有缓存,禁用一级缓存              

               第三方缓存  Mybatis继承别的缓存技术redis、chcache、memercache,通过实现一个接口:Cache              

附加:MyBatis也可以用注解的方式进行操作,比如@Select("SQL语句"),这样就不需要用SQL映射文件XML了,但是不推荐这么使用

               public interface Mapper {   @Select("SELECT * FROM BLOG")   List<Blog> selectBlog(); }              

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
158 0
|
6月前
|
XML Java 数据库连接
阿里P7架构师带你修炼MyBatis
我们通过一个简单的权限控制需求(RABC,Role-Based Access Control,基于角色的访问控制),来讲解通过XML方式配置MyBatis的基本用法(即select、update、insert、delete等操作的XML配置方式)。
89 0
|
6月前
|
SQL Java 数据库连接
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
124 1
|
11月前
|
SQL 缓存 Java
MyBatis的核心技术掌握,简单易懂(上)
MyBatis的核心技术掌握,简单易懂(上)
|
SQL Java 数据库连接
一般文章让你了解mybatis,以及如今在Java开发的地位!
一般文章让你了解mybatis,以及如今在Java开发的地位!
166 0
|
11月前
|
SQL XML 存储
SSM三大框架之MyBatis总结【动力节点老杜】
要想获取SqlSession对象,需要先获取SqlSessionFactory对象,通过SqlSessionFactory工厂来生产SqlSession对象。
860 0
SSM三大框架之MyBatis总结【动力节点老杜】
|
XML SQL Java
MyBatis配置与使用-初入篇
MyBatis配置与使用
216 0
|
SQL XML Java
【测试开发】知识点-mybatis,使用入门
【测试开发】知识点-mybatis,使用入门
【测试开发】知识点-mybatis,使用入门
|
SQL XML Java
MyBatis源码学习笔记(一) 初遇篇
MyBatis源码学习笔记(一) 初遇篇
MyBatis源码学习笔记(一) 初遇篇
下一篇
无影云桌面