学习总结自《深入浅出MyBatis技术原理与实战》
下面我们将详细学习MyBatis的配置,配置文件会对整个MyBatis体系产生深远的影响,下面我们先来看一下MyBatis配置文件XML文件的层次结构:
注意:这些层次是不能够颠倒的,否则会出现异常。上面的就是MyBatis配置文件的全部元素。
下面我们详细学习各个元素:
1.properites元素
它是一个配置属性的元素,让我们能在配置文件的上下文中使用它,对于它,MyBatis提供了三种配置方式:
1).property子元素
2)properties配置文件
3)程序参数传递
在这三种方式中第二种是我们的首选,用法如下:
1.首先我们需要创建一个propertis文件,其内容如下:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc?&useSSL=false&serverTimezone=UTC
username=root
password=root
2.然后再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>
<properties resource="jdbc.properties"/>//引入properties配置文件
<typeAliases>
<typeAlias alias="role" type="mybaits.pojo.Role"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="autoCommit" value="false"/>
</transactionManager>
<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 resource="mybaits\mapper\RoleMapper.xml"/>
</mappers>
</configuration>
其他两种了解即可。
优先级:当三种方式同时出现时,它们之间是存在优先级的。
properties元素体内指定的属性首先被读取,其次根据properties元素中的resource属性读取类路径下属性文件,或者根据url属性指定的路径读取属性文件并覆盖已读取的同名属性,最后读取作为方法参数传递的属性,并覆盖同名的。
2.settings元素
settings再MyBatis中是最复杂的配置,同时也是最为重要的配置内容之一,他会改变MyBatis运行时的行为。 使用它我们能开发出高性能的程序,当然,即使不配置它MyBatis也能正常工作。
在大部分的时候我们不需要配置它或者只需要配置少数几项即可 ,这里不做详细介绍。
3.typeAliases元素
它是一个指代的名称(别名),因为我们遇到的类的全限定名过长,所以我们需要用一个简短的名称去指代它,而这个名称可以再配置文件上下文中使用。
注意:再MyBatis中别名是不区分大小写的。
别名分为系统定义别名和自定义别名:
1)系统定义别名:MyBatis系统定义了一些经常使用的类型的别名,例如数值,字符串,日期等等,我们可以再MyBatis中直接使用它们:
2)自定义别名:
<typeAliases>
<typeAlias alias="role" type="mybaits.pojo.Role"/>
</typeAliases>
上面我们把role代替其全路径,减少配置的复杂度。
如果POJO过多的时候用上面的配置也会很麻烦,这时我们可以使用下面方法:
首先使用@Alias注解在Pojo类上标注
@Alias("role")//设置别名
public class Role{
}
然后
<typeAliases>
<package name="com.learn.chapter2.po"/>
<package name="com.learn.chapter3.po"/>
</typeAliases>
例如:
配合上面的配置,MyBatis会自动扫描包,将扫描到的类装载到上下文中。如果没有@Alias注解,MyBatis也会扫描和装载只不过它会将我们的类名的第一个字母变成小写作为别名。
4.typeHandler元素
MyBatis在预处理语句中设置一个参数时或者从结果集中取出一个值时,会用到注册了的typeHandler进行处理。
typeHandler的作用就是将参数从javaType转化为jdbcType,或者从数据库取出结果时把jdbcType转化为javaType。
和别名一样,他也分为系统定义的和自定义的,一般来说,使用MyBatis系统定义就可以实现大部分功能。
1)系统定义的typeHandler
2)自定义typeHandler
在我们使用自定义typeHandler之前首先需要明确两个问题:
我们自定义的typeHandler需要处理什么类型?
现有的typeHandler适合我们使用吗?
下面我们以重复覆盖一个字符串参数的typeHandler来实例学习:
首先配置XML文件确定我们需要处理什么类型的参数和结果:
<typeHandlers>
<typeHandler jdbcType="VARCHAR" javaType="string" handler="com.learn.chapter3.MyStringTypeHandler"/>
</typeHandlers>
然后编写handler所表示的类:
MyStringTypeHandler.java
@MappedTypes({String.class})//定义的是JavaType类型,可以指定那些java类型被拦截
@MappedJdbcTypes(jdbcType.VARCHAR)//定义的是jdbcType类型,他需要满足org.apache.ibatis.type.JdbcType所列的枚举类型
public class MyStringTypeHandler implements TypeHandler<String>{
private Logger log=Logger.getLogger(MyStringTypeHandler.class);
public void setParameter(PreparedStatement ps,int index,String vlaue,Jdbc jt)throws SQLException{
log.info("使用我的TypeHandler");
ps.setString(index,value);
}
public String getResult(ResultSet rs,String colName) throws SQLException{
log.info("使用我的Typehandler,ResultSet列名获取字符串");
return rs.getString(colName);
}
public String getResult(ResultSet rs,int index) throws SQLException{
log.info("使用我的TypeHandler,ResultSet下标获取字符串");
return rs.getString(index);
}
public String getResult(CallableStatement cs,int index) throws SQLException{
log.info("使用我的TypeHandler,CallableStatement下标获取字符串");
return cs.getString(index);
}
}
下面我们还需要去标识哪些参数或者结果类型取用typeHandler进行转换,在没有任何标识的情况下,MyBatis是不会启用我们自定义的typeHandler进行转换的,所以还要给予对应的标识,比如配置jdbcType和javaType,或者直接用typeHandler属性指定,因此我们需要修改映射器的XML配置。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mybaits.mapper.RoleMapper">
<resultMap type="role" id="roleMap">//resultMap提供映射规则
<id cloumn="id" property="id" javaType="long" jdbcType="BIGINT"/>
<result column="role_name" property="roleName" javaType="string" jdbcType="VARCHAR"/>
<result column="note" property="note" typeHandler="com.learn.chapter3.typeHandler.MyStringTypehandler"/>
</resultMap>
<select id="getRole" parameterType="long" resultType="roleMap">
select id,role_name as roleName,note from t_role where id = #{id}
</select>
<insert id="insertRole" parameterType="roleMap">
insert into t_role(role_name,note) values (#{roleName},#{note})
</insert>
<delete id="deleteRole" parameterType="long">
delete from t_role where id = #{id}
</delete>
</mapper>
如果在配置typeHandler的时候也进行包配置,那么MyBatis就会扫描包里面的typeHandler以减少配置的工作,配置代码如下:
<typeHandlers>
<package name="com.learn.chapter3.typeHandler"/>
</typeHandlers>