Mybatis是基于XML配置或者注解完成数据库操作
前面入门了Mybatis,完成了CRUD
现在仔细了解mybatis-config.xml中的配置
先看官网:Mybatis官网
一切以官网为准,补充说明官网
配置有上述这些
<?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="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--每一个mapper.xml都需要在mybatis的核心配置文件注册-->
<mappers>
<mapper resource="com/learn/dao/UserMapper.xml"/>
</mappers>
</configuration>
其中xml配置信息的约束文件,应该都很熟悉
这是主配置文件约束:configuration
<?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">
而我们的mapper.xml文件是这种约束:
<?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">
这是一种XML的Schema约束
不了解的可以看:真的了解XML吗? - XML 基础
这些约束限制了标签,可以查看有什么标签
configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)
最外层是configuration 根标签,表示这是Mybatis核心配置文件mybatis-config.xml
properties标签提供了引入外部文件或者设置变量的方法
在这个标签内定义的属性可以在该xml文件引用(就会Java的全局变量一样)
如:
<properties>
<property name="id" value="zhangsan"/>
</properties>
这样是设置了一个id = zhangsan 键值对,在该xml使用时直接引用id即可,取值直接${id}
就可以取出,这就让我们可以动态配置信息,在后面就可以用外部文件配置数据库连接信息
(和Map类似)
可以引入外部文件
提供了两种方法:
如:
<properties resource="db.properties"/>
<properties url="file:D:\JavaProject\mybatis\mybatis-cache\src\main\resources\db.properties"/>
如果是绝对路径:url前要加上file:,这是只是windows帮我们省略了
读取的文件也得以键值对(a:b或者a=b)的方式存储数据,不然就读不出(Java的properties文件)
不以name=value的形式,IDEA也会提醒你
如:在db.properties文件编写(也可以用:分隔,不过IDEA会警告)
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username=root
password=root
<?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="db.properties"/>
<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>
<package name="com.learn.dao"/>
</mappers>
</configuration>
这样一样可以完成数据库的连接,这就是获取了配置文件中是键值对属性
Java传值
很明显,如果是XML或者properties文件中配置,就无法对数据加密
加密就需要Java程序
除了在XML或者properties文件中配置,也可以在Java程序中配置
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
// ... 或者 ...
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
这个涉及到Mybatis工作流程,后面再细说
如果数据很重要,可以选择Java加密传输
配置读取顺序
如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性
占位符
从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值
<dataSource type="POOLED">
<!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' -->
<property name="username" value="${username:ut_user}"/>
</dataSource>
这个特性默认是关闭的,需要在属性中打开
<properties resource="org/mybatis/example/config.properties">
<!-- 启用默认值特性 -->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
</properties>
可以看出,它也是引用了外部配置文件
属性名
可以看出,Mybatis读取键值对是以:或者=为分割
所以,如果属性名存在冒号、等号,或者在 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>
最好还是别瞎写
只能引入一个外部文件
很明显,一个xml里只能有一个properties标签,标签中也只能有一个resource
所以,如果想要配不同环境的话,需要写多个核心配置文件
这是一个很重要的标签,通过该标签改变Mybatis的内部配置
有很多属性,可以自行查看官网
常用的有:
<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>
其实大部分都用不到,settings标签改变的是Mybatis内置的一些属性
还记得我们前面配置mapper.xml时resultType
标签里的这个resultType,如果输出结果是某个类的对象时,就需要写完整的包名
<select id="getUserList" resultType="com.learn.pojo.User">
select * from mybatis.user
</select>
很繁琐,通过类型别名可以解决
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
有多种配置方法:
<typeAliases>
<typeAlias type="com.learn.pojo.User" alias="User"/>
</typeAliases>
这样就设置好了一个别名
在mapper.xml中就可以直接使用User
<select id="getUserList" resultType="User">
select * from mybatis.user
</select>
<typeAliases>
<package name="com.learn.pojo"/>
</typeAliases>
不过,因为是自动扫描的,类的别名就是该类名(大小写都可以),不能取其他别名
上面的我们自己的类需要别名,Mybatis内置了一些常用属性的别名
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
可以看到,基本类型是前面加了下划线的,和封装类型不同
MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型
这是Mybatis对javaType和jdbcType类型之间的转换
比如,Java实体类中用Date型表示时间,数据库中用varchar型表示,就需要用类型处理器,把实体类中的时间数据转换后放入数据库
Mybatis内置了很多类型处理器,详情看官网
绝大多数的类型转换Mybatis都考虑到了
如果想自定义类型处理器,有两种方法:
例如,前面说的javaType中的Date类型与jdbcType中的varchar类型之间的转化
package com.learn.util;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Myhandler implements TypeHandler<Date> {
@Override
// 设置sql中指定索引的参数,即将javaType转化为jdbcType
public void setParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
//设置数据存储到数据库中的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
ps.setString(i, sdf.format(parameter));
}
@Override
// 根据列名称从结果集获取值,并将jdbcType转换成javaType
public Date getResult(ResultSet rs, String columnName) throws SQLException {
String columnValue = rs.getString(columnName);
if (null != columnValue) {
return new Date(Long.valueOf(columnValue));
}
return null;
}
@Override
// 根据列名称从结果集获取值,并将jdbcType转换成javaType
public Date getResult(ResultSet rs, int columnIndex) throws SQLException {
String columnValue = rs.getString(columnIndex);
if (null != columnValue) {
return new Date(Long.valueOf(columnValue));
}
return null;
}
@Override
public Date getResult(CallableStatement cs, int columnIndex) throws SQLException {
String columnValue = cs.getString(columnIndex);
if (null != columnValue) {
return new Date(Long.valueOf(columnValue));
}
return null;
}
}
然后在核心配置文件上加入:
<!--类型处理器 -->
<typeHandlers>
<!-- 注册自定义handler,说明它作用的jdbcType和javaType -->
<typeHandler jdbcType="VARCHAR" javaType="date" handler="com.learn.util.Myhandler" />
</typeHandlers>
然后在Mapper.xml中引入,就配置完成了
这位大佬写的挺好的:MyBatis配置文件(四)--typeHandlers
没必要自定义类型处理器
Mybatis-config.xml配置文件有很多属性,这一篇详细介绍了约束、properties、settings、typeAliases、typeHandlers
后续还有objectFactory(对象工厂)、plugins(插件) environment(环境变量) transactionManager(事务管理器)
dataSource(数据源)databaseIdProvider(数据库厂商标识)mappers(映射器)
学海无涯苦作舟
看到这了,点个赞呗(^_−)☆