Mybatis进阶篇
核心配置文件
1、mybatis-config.xml
2、Mybatis 的配置文件包含了会深深影响Mybatis行为的设置和属性信息
-
Configuration(配置)
-
properties(属性)
-
settings(设置)
-
typeHandlers(类型处理器)
-
typeAliases(类型别名)
-
objectFactory(对象工厂)
-
plugins(插件)
- environment(环境变量)
- transactionManager(事物管理器)
- dataSource(数据源)
- environment(环境变量)
-
databaseldProvider(数据库厂商标识)
-
mappers(映射器)
-
环境配置(Environments)
MyBatis可以配置成适应多种环境
不过要记住:尽管可以配置多个环境,单每个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>
</environments>
当前可以清楚的看到最外层的标签为【environments】,这个标签相当于一个容器,将所有环境囊括到这个容器中。在看容器中的【environment】,这个就是完整的一套环境,其中的标签就是这一套环境的属性。
理解了这些就明白了,【environments】中可以存在多个【environment】,还有一点需要注意的就是【environments】标签中的**(default)属性,这里填写的是不同环境的ID**,说白了就是当前配置的哪套环境生效。
事务管理器(TransactionManager)
在配置一整套的【environment】环境的时候,需要着重注意的是【transactionManager】标签
在这个标签的type属性中可选的有两种类型的事务管理器,分别是
- JDBC——这配置就是直接使用了JDBC的提交和回滚机制
- Managed——这个配置几乎没做什么,官方文档解释的是使用以前老一套的EJB,现在已经淘汰了。
如果正在使用Spring+Mybatis就不需要配置事务管理器。
数据源(DataSource)
首先这个标签在【environment】中的作用是为了链接数据库,跟其有相似功能的还有(dbcp,c3p0,druid德鲁伊),这些都在干同一件事情链接数据库。
这个标签的type属性中可选的有三种类型,分别是(Unpooled,pooled,jndi)
-
UnPooled
没有连接池。
-
Pooled
使用"池"的概念将JDBC链接对象组织起来,在程序中一出现"池",那就代表了对象的复用**,为了提高运行效率,同时节省了请求量大的时频繁创建对象浪费的资源。
-
JNDI
这个代表正常的连接,这个数据源是以前的EJB使用的。
属性配置文件
我们可以通过引用Properties配置文件中的属性来应用到Mybatis配置文件中。
例如当前配置文件名称为:db.porperties,内容如下
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=root
那么引用文件中属性并应用在核心配置文件中的方式为
-
先引用配置文件
//该标签一定要位于【configuration标签的首行】 <porperties source="db.porperties" />
-
引用配置文件中的属性
<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>
类型别名
1、类型别名就是在引用位于包下类的时候,将长的路径名设置一个简短的名字。
2、存在的意义仅在于用来减少引用完全体类名的时候,路径冗余。
一共有两种方式来实现将类名简洁化,分别为
- typeAlias标签分别有两个属性,type,alias,格式如下
<typeAliases>
<!--type为引用具体的类,alias为自己起的别名-->
<typeAlias type="com.darling.Pojo.Users" alias="Users" />
</typeAliases>
这里说的更详细一点,【typeAliases】标签写在Mybatis-config.xml核心配置文件中,在核心配置文件中定义之后就可以在注册的Mapper.xml中编写SQL语句的时候,直接使用自己定义的别名了。
- package标签只有一个属性
<typeAliases>
<package name="com.darling.Pojo" />
</typeAliases>
这个标签的涵义就是扫描给定目录(包)下的Java类,将扫描到的类使用类名直接作为别名使用,官方文档中推荐小写类名,举个栗子:
假设com.darling.Pojo包下有一个实体类Users,在核心配置文件中键入上述配置之后,那么实体类Users的别名就是Users或者users(推荐)。
适用场景
1、在实体类比较少的情况下,使用第一种。
2、在实体类比较多的情况下,使用第二种。
两者区别
前者可以自己进行DIY使用,后者只能以引用原本类名的方式进行应用(当然如果你使用第三方注解进行起别名的话,那这区别当我没说)。
映射器
我们在使用Mybatis的时,编写接口之后,都要在编写一个与之对应的Mapper.xml文件,这个文件就是独立出来专门写SQL语句的文件,当Mapper.xml文件编写完成之后,为了使其生效所以要去Mybatis的核心配置文件中注册。
方式一:
<!--以这种单独的方式进行注册的话,那就意味着一个xml对应这一个Mapper,都需要注册-->
<mappers>
<mapper resource="com/darling/dao/Mapper.xml" />
</mappers>
方法二:
<!--这种方式是引用自己编写的接口类来达到注册的目的,因为在编写对应的Mapper.xml时已经建立了两者之间的映射关系,所以这里也是可以的-->
<mappers>
<mapper class="com.darling.dao.Users" />
</mappers>
方法三:
<!--这种方式是以包容器为准来导入的,也就是说处于com.darling.dao下的所有xml都会被注册成功且使用-->
<mappers>
<package name="com/darling/dao" />
</mappers>
注意点:
1、接口和与之对应的Mapper.xml配置名称必须相同
2、在企业级开发中大部分的应用场景是编写的接口和与之对应的xml是在同一包下,但是可能会导致build项目的时候出问题,这时候应该加一个前置条件,必须在Maven的pom.xml配置文件中配置.xml格式的文件也要被正确导出。【这个问题是idea本体的设定导致的,如果忽略这一步的话,导致的后果是自己写的xml配置文件在target目录下无法被导出,也就是说无法被识别,那自然也就无法生效了】。
声明周期和作用域
声明周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题。
SQLSessionFactoryBuilder:
-
一旦创建了SqlSessionFactory,它就可以去养老了,并且不建议创建多个SQLSessionFactory。
-
为了节省不必要的资源开销,采用缩短作用域的方式减少使用次数,所以这里的SqlSessionFactory为局部对象。
SQLSessionFactory:
-
这个的作用跟数据库连接池一个道理
-
SqlSessionFactory一旦被创建就应该在应用荤腥期间一直存在,没有任何理由丢弃它或者重新创建它。
-
因此SQLSessionFactory的最佳作用域是全局的,处于最高层的级别。
-
最简单的创建方式就是使用单例模式或者静态单例模式来一开始就保证SQLSessionFactory是全局唯一,且不允许再次创建的。
SqlSession:
- 连接到链接池的一个请求!
- SqlSession的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或者方法作用域。
- 用完之后需要赶紧关闭,否则资源被占用。
结果集映射(非常重要)
结果集映射,顾名思义就是将一个对象映射到另一个对象,本质上就是传递。在Mybatis的应用场景中,这里互相映射的对象就是数据库表中的字段和自己编写的实体类中的属性,我们进行的操作说白了就是将数据库表中字段的值传递给本地实体类的属性,最终传递完的结果就是将数据库表中的字段在程序中换了一种组织方式并封装为对象,就是这么个理念。
接下来介绍一下Mybatis中结果集映射的实现过程。
应用结果集映射的场景
第一种情况是这个技术应用在数据库表中的字段名称和我们自己编写的实体类中的属性名称不一致的时候使用,第二种情况就是我们实体类中的属性不是基本数据类型的时候使用,例如我们自己写的引用类型,这样的话Mybatis是无法智能识别并自动映射出我们想要的结果的,熟悉了应用场景之后让我们继续往下看具体如何实现吧,这项技术也是工作中使用最频繁的技术点,所以务必提高关注度。
结果集映射实现过程(环境构造)
现在有一个数据库表,名称为Student.dbf,表结构和表数据如下所示:
ID | name | age |
---|---|---|
1 | 卡特琳娜 | 20 |
2 | 喜多川海梦 | 18 |
现在根据数据库表编写对应的实体类,注意实体类中的第二个参数名称是 username,跟数据表中的字段不对应。
/**
* 该类为对应数据库中student表中的字段创立的与之对应的属性,为了省一些篇幅,这里省去了构造方法,get/set,toString方法。
*/
public class Student {
//基本数据类型
private int id;
//基本数据类型
private String username;
//引用类型
private int age;
如果遇到上述情况的时候,就需要进行结果集映射的操作了。这里进行操作的地方是与定义的接口相对应的Mapper.xml中
<!-- 操作数据库的响应语句,对应接口中定义的方法-->
<select id="getUserList" resultMap="StudentMapper">
select * from student
</select>
<!-- 拓展操作语句,这是必然存在的--> <!--处理字符集映射,重点重点重点-->
<resultMap id="StudentMapper" type="com.darling.Pojo.Student" >
<result property="id" column="id" />
<result property="username" column="name" />
<result property="age" column="age" />
</resultMap>
解读一下,可以看到标签中的resultType属性变更成了resultMap,这个resultMap中储存的字符串就相当于一个指针,指向id为该名称的resultMap标签块中,所以我们可以看到,跟resultMap同时存在的还有resultMap标签块,这就相当于建立了标签和之间的联系。下面我们来解释一下标签的含义。
标签中,ID属性代表标识这个这个代码块(被指向的时候寻址使用),type属性就相当于原本标签中的resultType一样,都是返回值类型,只不过在这里定义了。
其中的中的property属性代表实体类中的字段,column属性代表数据表中的字段,这个标签的功能就相当于建立了这个不同名称的两个对象之间的联系。
如果世界总是这么简单就好了——————致以最高的敬意!~