既然已经入”坑“mybatis了,你竟然还想着挣脱,我是不会让你挣脱的~

当然我有一个算是挣脱的办法。那就是把它学会、理解透。这样我们也就不用在坑里一直徘徊,也算得上是一种挣脱吧!

我在[上一篇文章](file:///E:/LearnNote/后端/Java/mybatis/mybatis入"坑"第一步.md)中对创建一个mybatis项目过程中有过的简单的解释,这篇文章对增加mybatis生命周期和更加详细的配置的说明和解释以及在配置的可能会遇到的关键问题。

一、mybatis作用域与生命周期

如下图是mybatis简易的生命周期图。首先mybatis通过IO流的方式获取配置文件mybatis.config.xml的信息,然后利用SqlSessionFactoryBuilder创建SqlSessionFactory,而SqlSessionFactory是在一个mybatis中是以单例形式存在的,接着利用SqlSessionFactory生产SqlSession,接着利用SqlSession调用SQL Mapper去处理具体的业务。

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder的作用就是用来创建SqlSessionFactory的,所以创建完成SqlSessionFactory后便可以将其丢弃,所以SqlSessionFactoryBuilder的作用域最好就是在局部方法中。当需要它是可以再次重用,但是不要一直保留。

SqlSessionFactory

SqlSessionFactory被创建成功后,你应该保证它在运行期间一直存在,因为每一个业务都需要同样的SqlSessionFactory去创建SqlSession。因此 SqlSessionFactory 的最佳作用域是应用作用域。也就是要使SqlSessionFactory在每一个mybatis中都是以单例形式存在的。

SqlSession

SqlSession 的实例不是线程安全的,是不能被共享的,所以作用域最好是在局部方法中。同时对于每一次请求SqlSession,返回一个响应后,应该及时关闭它。

Mapper映射器实例

Mapper映射器接口的实例是从 SqlSession 中获得的,最好将映射器放在方法作用域内,这样可以更好的管理。Mapper代表的是一个具体的业务处理,所以当处理完该业务时就可以丢弃。Mapper是随着SqlSession的关闭而消失废弃的

二、mybatis关键配置详解

properties属性

properties标签:可以动态配置属性。

可以全部在外部进行配置,如下:

<properties resource="db.properties" />

也可以在通过property标签一部分在外部进行内部配置另一部分在内部进行配置(如下),增加配置的灵活性。

<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>

当外部的db.properties文件进行配置之后,在property标签中又配置一遍后会使用哪一个配置呢?

这就需要考虑优先级的问题,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。这里我们的db.properties文件时通过resource指定的,所以优先级大于properties元素指定的属性。所以优先使用外部的db.properties文件中的配置。

typeAliases类型别名

配置Mapper.xml的类型别名可以降低书写冗余的全限定类名。通过对实体类别名的配置,简化开发人员的书写的代码量。比如需要书写com.wkx.pojo.User的全限定类名,在配置别名后便可以仅仅书写user。

那么如何去配置类型别名呢?

第一种:通过typeAlias的标签去配置,这样需要对每一个实体类进行分别配置。type属性中为实体类的路径,alias属性为别名名称。

<!--配置别名-->
<typeAliases>
<typeAlias type="com.wkx.pojo.User" alias="user"/>
</typeAliases>

第二种:通过package标签属性去配置,name属性为实体类所在的包路径。

在无注解的情况下,使用 Bean 的首字母小写的非限定类名来作为它的别名,比如com.wkx.pojo.User的别名便是user

<!--配置别名-->
<typeAliases>
<package name="com.wkx.pojo"/>
</typeAliases>

在有注解的情况下,使用注释的别名进行配置。

@Alias("wkx")
public class User {
...
...
}

使用注解后便可以通过注解的内容进行类型配置

<mapper namespace="com.wkx.dao.UserMapper">
<select id="getUser" resultType="wkx">
select * from user
</select>
</mapper>

下面列出关于Java类型内建的类型别名,这里只列出一部分,其他的类型的别名可以依次类推。比如别名为_double,映射类型为double;别名为double,对应映射类型为Double。

别名 映射的类型
_int int
_integer int
int Integer
integer Integer
map Map
hashMap HashMap

environments环境配置

用于配置数据的环境。可配置多个数据库环境,但是SqlSessionFactory只能选择一个去使用。如下:

<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>
<environment id="test">
<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>

可以在不同的环境下切换不同的数据环境,只需要修改environments标签中的default属性对应不同环境下的id属性,比如development和test不同的环境。

  • 事务管理器(transactionManager)

    在mybatis中有两种不同的事务管理器,即type="JDBC"或者type="MANAGED"

    JDBC的事务类型是直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。

    MANAGED的事务类型配置几乎没有做什么,从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。

  • 数据源(dataSource)

    主要有三种数据源类型,即type="[UNPOOLED|POOLED|JNDI]"。

    UNPOOLED的数据源类型是不使用连接池,每次请求时都会打开和关闭连接,显然这样的连接数据源类型效率不高。

    POOLED的数据源类型是使用连接池的概念,每次请求可以直接从“池”子里拿出活跃的连接,避免了重复的创建连接,提高效率。

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

mappers映射器

定义映射的路径,告诉mybatis去哪里找对应的语句。我们可以是使用类路径的资源引用方式(推荐使用):

<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="com/wkx/dao/AuthorMapper.xml"/>
</mappers>

可以通过使用完全限定资源定位符(URL)的方式(方式二):

<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///E:/UserMapper.xml"/>
</mappers>

可以通过映射器接口实现类的完全限定类名的方式(方式三):

<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="com.wkx.dao.UserMapper"/>
</mappers>

可以包的形式将映射器接口全部注册为映射器的方式(方式四):

<mappers>
<package name="com.wkx.dao"/>
</mappers>

注意:方式三和方式四使用需要具备两个条件,一个是接口和Mapper的名称一致,比如UserMapper.java接口和UserMapper.xml必须都是UserMapper,也就是一致的。另一个是接口和Mapper的包名一致。

入“坑”mybatis后如何挣脱?的更多相关文章

  1. 入坑wsl

    用了一个月的mac os, 又回归windows了, mac确实好看, 终端配合iterm2也很舒服, 奈何终究我们不合适...生态毕竟没有windows那么丰富; 切回windows最无法忍受的就是 ...

  2. RoboGuice 3.0 (一)入坑篇

    RoboGuice是什么? 一个Android上的依赖注入框架. 依赖注入是什么? 从字面理解,这个框架做了两件事情,第一是去除依赖,第二是注入依赖.简单理解就是,将对象的初始化委托给一个容器控制器, ...

  3. webpack入坑之旅(六)配合vue-router实现SPA

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  4. webpack入坑之旅(四)扬帆起航

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  5. webpack入坑之旅(三)webpack.config入门

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack,在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  6. webpack入坑之旅(二)loader入门

    这是一系列文章,此系列所有的练习都存在了我的github仓库中vue-webpack 在本人有了新的理解与认识之后,会对文章有不定时的更正与更新.下面是目前完成的列表: webpack入坑之旅(一)不 ...

  7. webpack入坑之旅(一)不是开始的开始

    最近学习框架,选择了vue,然后接触到了vue中的单文件组件,官方推荐使用 Webpack + vue-loader构建这些单文件 Vue 组件,于是就开始了webpack的入坑之旅.因为原来没有用过 ...

  8. gulp入坑系列(2)——初试JS代码合并与压缩

    在上一篇里成功安装了gulp到项目中,现在来测试一下gulp的合并与压缩功能 gulp入坑系列(1)--安装gulp(传送门):http://www.cnblogs.com/YuuyaRin/p/61 ...

  9. ReactNative for Android入坑(一)

    最近找工作发现有些公司要求会ReactNative,决定入坑. 搭建环境:官网详细的教程附链接. 坑一:FQ,建议整个搭建过程中FQ.(FQ链接,注册有200M试用流量,环境搭建够了)第一步:安装Ch ...

随机推荐

  1. JS实现单例模式的多种方案

    JS实现单例模式的多种方案 今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6 ...

  2. XAML 属性元素,标记扩展和注释

    这节来讲一下XAML中的属性元素,标记扩展,和注释. 属性元素 一般的,我们想要对一个标签的属性赋值,可以直接在标签内部键入属性名给其赋值,如我们给button的Content属性赋值: <Bu ...

  3. java并发编程:深入了解synchronized

    简介 synchronized是Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.同时它还保证了共享变量的内存可见性. ...

  4. centos7 启动引导顺序

    查看默认启动项 grub2-editenv list 查看启动项列表 awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg 设 ...

  5. ValueError: not enough values to unpack (expected 2, got 1)

    在python中使用字符串分片时遇到这个问题 [ValueError: not enough values to unpack (expected 2, got 1)] --------------& ...

  6. C/C++ 复习

    本文总结一下C++面试时常遇到的问题.C++面试中,主要涉及的考点有 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, ne ...

  7. Centos7.4永久修改系统时间

    [root@V3B01-zsy yum.repos.d]# date -s "2019-09-24 17:02:30" 2019年 09月 24日 星期二 17:02:30 CST ...

  8. session.flush()与session.clear()区别与使用环境

    session是有一级缓存的,目的是为了减少查询数据库的时间,提高效率,生命周期与session是一样的 session.flush() 是将session的缓存中的数据与数据库同步 事物提交失败 缓 ...

  9. Nginx下配置Https证书详细过程

    一.Http与Https的区别HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高 ...

  10. GO文件读写01---读文件

    打开文件 package main import ( "fmt" "os" ) /* buffer 缓冲区 utility 便利的工具 util 便捷工具(傻瓜 ...