核心配置
- Mybatis-config.xml(基础配置)
作用
Mybatis-config.xml实现:
- 这在前面说过,加载解析都是在Configuration对象被创建时发生:
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration:
private void parseConfiguration(XNode root) {try {// issue #117 read properties firstpropertiesElement(root.evalNode("properties"));Properties settings = settingsAsProperties(root.evalNode("settings"));loadCustomVfsImpl(settings);loadCustomLogImpl(settings);typeAliasesElement(root.evalNode("typeAliases"));pluginsElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));reflectorFactoryElement(root.evalNode("reflectorFactory"));settingsElement(settings);// read it after objectFactory and objectWrapperFactory issue #631environmentsElement(root.evalNode("environments"));databaseIdProviderElement(root.evalNode("databaseIdProvider"));typeHandlersElement(root.evalNode("typeHandlers"));mappersElement(root.evalNode("mappers"));} catch (Exception e) {throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);}}
- 一个基础简单配置定义:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"/><settings><setting name="logImpl" value="STDOUT_LOGGING"/></settings><typeAliases><package name="org.example.pojo"/></typeAliases><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 class="org.example.daos.UserMapper"/><mapper class="org.example.daos.TeacherMapper"/><mapper class="org.example.daos.StudentMapper"/></mappers></configuration>
具体配置标签使用
这是官网的参考链接:Mybatis配置定义
在这里,将知识转化成自己的方式理解,这才是学到了。
以下是按照自己的理解总结:
Properties
定义配置属性,一般用在对DataSource参数的设置上:
- 针对不同地方定义属性值的代码实现:
- 使用java.util.Properties,put存放数值利用ConcurrentHashMap的不可重复特性,覆盖去重;
- 加载resource/url资源配置时,通过properties #load方法直接转化,对原始转化做了个完美的语法糖:
...// 原始基础原理:一步步的,先读取到缓冲字节区域buffer,然后经由buffer再写入/处理// 这里的buffer,我理解成:“倒爷”InputStream inputStream = getClass().getResourceAsStream(filePath);ServletOutputStream outputStream = response.getOutputStream();byte[] buffer = new byte[1024];int lens;while((lens = inputStream.read(buffer))> 0){outputStream.write(buffer, 0, lens);}...
- 关闭资源时,可以用try-resources语句,针对实现了AutoCloseable接口的资源类,程序会在使用完资源后后台自动帮忙关闭。
- 具体实现:
<!-- Properties标签: URL|Resource(只能二选一)resource 属性读取**类路径**下属性文件;url 属性**指定的路径**读取属性文件properties设置有三种途径(按照优先级高低):方法参数(builder.build(..., props)) >>>> url | resource定义的配置属性 >>>> properties标签下定义的属性--><!--例子1:引入外部properties文件,设置全部属性 ${} --><properties resource="db.properties"/>读取类路径下的资源<properties url=""/>URL:可以是网络资源,也可以本地服务器资源<!--例子2:引入外部properties文件,设置部分属性 ${}--><properties resource="db1.properties"><property name="user" value="root"/><property name="pwd" value="root"/></properties><!--例子3:引入外部properties文件,设置部分属性,当属性key一致时,优先使用properties外部资源的属性 ${}--><properties resource="db.properties"><property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=true
"/><property name="driver" value="com.mysql.cj.jdbc.Driver"/></properties>
Setting
针对Mybatis一些行为的设置,记住常用的几个,其他的,用的时候查阅参考链接即可:
<settings><!--指定日志的具体实现: STDOUT_LOGGING: --><setting name="logImpl" value="STDOUT_LOGGING"/>标准日志输出,一般用在本地调试,可在console中查看代码的执行过程<setting name="logImpl" value="LOG4J2"/>可通过log4j2配置文件定制化日志文件<setting name="mapUnderscoreToCamelCase" value="true"/>开启驼峰映射:Column(a_b)映射为属性(aB)
</settings>
typeAliases
一个目的:起别名。简化在mapper映射关系中,指定type时,可以简化。一般会为了省掉包名,只用类名来表示。
当然针对,类名可能存在一致的问题(多module开发),那就加上包名来以示区别。
<typeAliases><!--两种方式--><!--给具体的一个javabean起别名 --><typeAlias type="org.example.pojo.User" alias="User"/><!--通过扫描pojo包来设置别名:默认javabean别名为类名的首字母小写 @Alias("user"),也可以在javabean上指定别名通过注解@Alias --><package name="org.example.pojo"/>当前包下的所有bean,就会起效</typeAliases>
应用于mapper.xml中:
<select id="getUserById" resultType="org.example.pojo.User">这里的org.example.pojo.User可以简化为User/userSELECT * FROM mybatis.user where id = #{id}
</select>
typeHandlers
- 在从ResultSet结果集中获取值时,会用到类型处理器来做转化操作,例如:SqlDateTypeHandlerStringTypeHandler等;
- 也可自定义实现:重写已有类型处理器,或实现TypeHandler接口,或继承BaseTypeHandler类,参考官网链接。
Plugins
这里提一下,在追代码时看到,在handler处理器处理某个逻辑时,会有一处代码:
interceptorChain.pluginAll(xxx)
这就是plugin的作用之处:利用Mybatis自定义的拦截器Interceptor,在逻辑处理前后增添自定义功能
Environment
每个数据库对应一个SqlSessionFactory实例,每个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>
- ID: 可以设置dev,test,SIT,UAT,Stage,Prod等多个环境的配置;
- TransactionManager:type有两种:MANAGED(默认),JDBC
- datasource:数据源配置:UNPOOLED | POOLED | JNDI(内建的三种数据源类型),还可通过实现DataSourceFactory,扩展C3P0,DBCP,Druid.
mappers
这是涉及到下一个核心的SQL映射关系的引入:
<mappers><mapper resource="mappers/user-mappers.xml"/> <!--通过资源resource导入--><mapper class="org.example.daos.UserMapper"/> 通过class方式注入<package name="org.example.daos"/>通过package扫描注入
</mappers>
这里需要注意的是,对于将mapper配置放在src/main/java目录下的不能加载问题,第一篇初探有提到过。
总而言之,到这里会发现,(个人感慨)
-
Mybatis做的精明之处就是在于将我们原本复杂的逻辑通过config配置,在经过factory的构建,整合成一个SqlSession给到我们,我们只需要关注到业务的实现,底层的技术细节帮我们处理好了。
-
除过Mybatis内置的功能外,还给提供了很多对外扩展的接口,比如:
TypeHandler,plugin, DataSourceFactory, TransactionFactory&Transaction等等。 -
学习最好的方式就是看源码,根据内置的实现,模仿着去实现自定义,就能理解其中道理;
-
所以,技术框架的迭代,万变不离其宗,而且技术没有高低之分
-
后面,总结Spring会发现这种扩展性的接口会更多,也为学习更多的架构层面的策略,以及技术的掌握提供很好的途径。