Mybatis-全局配置文件(config.xml)
概述
properties
settings
typeAliases
typeHandlers
plugins
environments
databaseIdProvider
mappers
概述
Mybatis有两个很重要的配置文件:全局配置文件(config)和映射文件(mapper)
Mybatis的配置文件包含了影响Mybatis行为的设置(setting)和属性(properties)信息。
通过对文档的查看,我们可以发现配置文件的配置结构如下:
下面我们一一了解这些属性和设置信息。
properties
Mybatis可以使用properties标签来引入外部properties配置文件的内容
一般properties标签用于引入数据源的配置,也就是数据库的相关配置。
该标签有两个属性值:resource 和 url,resource属性用于引入类路径下的资源,url用于引入网络路径或磁盘路径下的资源
在conf目录下创建dbconfig.properties文件,里面写上如下内容:
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=qks218126
然后在mybatis-config.xml中添加properties标签并指定路径,修改property标签内value的值:
<?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>
<properties resource="dbconfig.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="EmployeeMapper.xml"/>
</mappers>
</configuration>
注意,properties标签一定要放在最前面,否则Mybatis会报错,引用的时候找不到引的外部文件
运行上一篇博客写的测试方法:
可以看到成功了。
但是在整合开发中一般不会需要独立创建一个properties文件并引入,这些信息Spring会最终帮我们做好
settings
这是Mybatis中极为重要的标签,它的属性基本都会对Mybatis的运行时行为产生影响,每一项设置项用setting标签表示
由于该配置项过多,所以这里只拿出mapUnderscoreToCamelCase
属性作为讲解,具体配置信息可以看Mybatis的官方文档。
通过查看文档介绍可以知道,该项配置的作用是设置是否开启下划线命名到驼峰命名的转换,也就是说是否开启经典那数据库下划线命名到经典Java属性驼峰命名的转换。
该属性值默认为False,此时要求数据库字段要与java bean字段一一对应,比如数据库字段为last_name,那么java实体类中的字段也必须存在且也为last_name
如果该属性的值为true,此时要求数据库下划线字段要与java实体类的驼峰命名字段一一对应,比如数据库字段为last_name,则要求java实体类中中存在且命名为lastName。
开启下划线与驼峰的转换:
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
此标签要求在environments标签之前
此时我的实体类的字段为:
private Integer id;
private String lastName;
private String email;
private String gender;
数据库的字段为:
接下来进行测试:
可以看到测试成功。
typeAliases
概述
别名处理器,作用是给java类型起一个名字,引用时可以用别名代替全名
别名不区分大小写
比如将com.atguigu.mybatis.bean.Employee取别名为Employee,那么映射文件内resultType的值就可以只写成Employee:
<typeAliases>
<typeAlias type="com.atguigu.mybatis.bean.Employee" alias="Employee"/>
</typeAliases>
<select id="getEmpById" resultType="Employee">
select * from btl_employee where id = #{id}
</select>
如果不指定alise参数,那默认为类名,比如这里就会默认成employee
该配置项还支持批量取别名:
<typeAliases>
<package name="com.atguigu.mybatis.bean"/>
</typeAliases>
name的值为某一个包,package标签标识为这个包下面的所有类都取别名,默认为类名。
假如包下有不同路径下的类的名字冲突,那么可以通过@Alias(“name”)注解来解决,注解的值为主动为类起的别名。
注意,这个注解不能单独使用
优先级高于默认别名,低于typeAlias标签内alias主动设置的别名,要用优先级高的,否则会报错
默认别名
Mybatis已经为许多常见得Java类型内建了相应的别名,这是应当在构建私有别名时应当注意的
下面是默认数据类型别名的表格:
Alias | Mapped Type |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
double | Double |
short | Short |
int | Integer |
integer | Integer |
float | Float |
boolean | Boolean |
iterator | Iterator |
date | Date |
collection | Collection |
decimal | BigDecimal |
arraylist | ArrayList |
bigdecimal | BigDecimal |
list | List |
object | Object |
hashmap | HashMap |
map | Map |
typeHandlers
类型处理器,作用就是架起java数据类型和数据库数据类型映射的桥梁
比如数据库中varchar类型的数据,放在java中要转成String类型的数据。下面是常用转换的表格:
Type Handler | Java Types | JDBC Types |
---|---|---|
BooleanTypeHandler | java.lang.Boolean.boolen | Any compatible BOOLEAN |
ByteTypeHandler | java.lang.Byte.byte | Any compatible NUMERIC or SMALLINT |
ShortTypeHandler | java.lang.Short.short | Any compatible NUMERIC or SMALLINT |
IntegerTypeHandler | java.lang.Integer.int | Any compatible NUMERIC or INTEGER |
LongTypeHandler | java.lang.Long.long | Any compatible NUMERIC or BIGINT |
FloatTypeHandler | java.lang.Float.float | Any compatible NUMERIC or FLOAT |
DoubleTypeHandler | java.lang.Double.double | Any compatible NUMERIC or DOUBLE |
StringTypeHandler | iava.lang.String | CHAR, VARCHAR |
DateOnlyTypeHandler | java.util.Date | DATE |
ByteArrayTypeHandler | byte[] | Any compatible byte stream type |
BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
DateTypeHandler | java.util.Date | java.util.Date |
TimeOnlyTypeHandler | java.util.Date | TIME |
plugins
表示Mybatis的插件
插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行:
-
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
-
ParameterHandler (getParameterObject, setParameters)
-
ResultSetHandler (handleResultSets, handleOutputParameters)
-
StatementHandler (prepare, parameterize, batch, update, query)
插件后面会拿出来单独学习
environments
Mybatis可以配置多种环境,每种环境由子标签environment决定
有属性default,值表示指定一个环境的标识符,用于切换环境
environment
配置一个具体的环境信息,子标签必须有transactionManager(必需)和dataSource(必需)
有属性id,表示当前环境的唯一标识
transactionManager
事物管理器,有属性type,表示事务管理器的类型
Mybatis中有两种事务管理器,分别是JDBC和MANAGED,JDBC表示使用JDBC的方式进行提交、回滚和事务控制,而MANAGED表示使用J2EE的容器来进行事务的控制。
dataSource
数据源,有属性type,表示使用数据源类型
type有三个取值:UNPOOLED:表示不使用连接池技术;POOLED:表示使用连接池技术;JNDI:表示使用JNDI技术。
案例
<environments default="development">
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.nextdriver}"/>
<property name="url" value="${jdbc.nexturl}"/>
<property name="username" value="${jdbc.nextusername}"/>
<property name="password" value="${jdbc.nextpassword}"/>
</dataSource>
</environment>
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
databaseIdProvider
作用是让Mybatis支持不同公司的数据库,有type属性,作用是得到数据库厂商的标识,Mybatis就能根据数据库厂商标识来执行不同的sql,默认为DB_VENDOR
Mysql的标识为MySQL,Oracle的标识为Oracle,Sql Server的标识为SQL Server等等,一般跟原名一致,“SQL”三个字母要大写。
databaseIdProvider有子标签property,表示为数据库标识起别名
<databaseIdProvider type="DB_VENDOR">
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
</databaseIdProvider>
比如上面的配置中就为Mysql和Oracle数据库的标识起了别名。
当我们需要指定映射文件中的sql语句用于哪一个厂商的数据库时,我们需要在标签内添加属性databaseId,值为上面property指定的value。
比如我要指定某个sql语句只用在Mysql数据库中,此时映射文件xml的sql语句应该写为:
<select id="getEmpById" resultType="emp" databaseId="mysql">
select * from btl_employee where id = #{id}
</select>
测试:
成功拿到。
mappers
可以将写好的映射文件注册到全局配置文件当中,每一个mapper子标签标识注册一个sql映射文件
mapper子标签有三个属性,resource标识类路径下的sql映射文件,url标识网络路径或磁盘路径下的映射文件,前两个属性用于注册映射文件,第三个属性class用于注册接口。
使用resource:
<mappers>
<mapper resource="EmployeeMapper.xml"/>
</mappers>
如果使用class注册接口,那么映射文件应当与接口类在同一目录下并且同名:
把之前用的mapper注释,并且重新写一个用class注册的mapper:
<mappers>
<!-- <mapper resource="EmployeeMapper.xml"/>-->
<mapper class="com.atguigu.mybatis.dao.EmployeeMapper"/>
</mappers>
此时运行测试方法:
成功。
当然,mapper和映射文件处于同一目录下,也可以用这种方式进行注册:
<mappers> <mapper resource="./com/atguigu/mybatis/dao/DepartmentMapper.xml"/> </mappers>
使用class进行基于注解的接口注册
注意,class还有另外一个用途,注册那些使用注解来描写sql语句的接口。
比如,我们会在实际开发中遇到下面的场景,某一个dao接口的方法使用了类似@Select注解的注解,并且值为sql语句,项目中也不存在映射文件,对应mapper标签中使用的属性是class而不是resource或者url:
public interface EmployeeMapperAnnotation {
@Select("select * from btl_employee where id = #{id}")
Employee getEmpById(Integer id);
}
同时mapper标签里使用了class,值为接口的全类名:
<mappers>
<mapper class="com.atguigu.mybatis.dao.EmployeeMapperAnnotation"/>
</mappers>
这就体现class的作用了,它允许我们单纯使用注解进行sql语句的描写,这个时候只需要在dao对应接口的方法上使用对应注解,注解内写上sql语句即可,不需要另写映射xml文件。
对其进行测试:
@Test
public void test2() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(inputStream);
try (SqlSession openSession = sqlSessionFactory.openSession()) {
EmployeeMapperAnnotation mapper = openSession.getMapper(EmployeeMapperAnnotation.class);
System.out.println(mapper.getClass());
Employee employee = mapper.getEmpById(1);
System.out.println(employee.toString());
}
}
结果:
成功。
不难发现这种方式耦合度会升高,并且复杂的sql语句会显得dao接口较为臃肿。