mybatis
-
入门
-
XML配置
-
properties(属性)
-
settings(设置)
-
mapUnderscoreToCamelCase 驼峰命名
-
-
typeAliases(类型别名)
-
typeHandlers(类型处理器)
-
objectFactory(对象工厂)
-
plugins(插件)
-
environments(环境配置)
-
databaseIdProvider(数据库厂商标识)
-
mappers(映射器)
-
入门
1 引入配置文件创建SqlSessionFactory
mybatis-config1.xml是mybatis的核心配置文件,用来配置mybatis系统参数,数据库参数,缓存,另外还需要引入具体的mapper文件。mapper1.xml是mybatis写sql的文件,mapper文件必须有唯一的namespace
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="primerConfig/mapper1.xml"/>
</mappers>
</configuration>
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="string">
select username from manage_user where id = #{id}
</select>
</mapper>
@Test//引入配置文件
public void t1() throws Exception {
String resource = "primerConfig/mybatis-config1.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
String name = (String) sqlSession.selectOne("config1.selectManageUserName", "1");
sqlSession.close();
}
2 不引入配置文件创建SqlSessionFactory
不引入mybatis配置文件,需要Configuration类,相当于mybatisconfig中的<configuation>标签。另外mapper文件也不存在了,则由注解代替
package primer;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-26 10:39
* @notify
* @version 1.0
*/
import org.apache.ibatis.annotations.Select;
public interface PrimerMapper {
@Select("select username from manage_user where id = #{id}")
String selectManageUserName(int id);
}
package primer;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-26 10:39
* @notify
* @version 1.0
*/
import org.apache.ibatis.annotations.Select;
public interface PrimerMapper2 {
@Select("select username from manage_user where id = #{id}")
String selectManageUserName2(int id);
}
@Test//不引入配置文件创建SqlSessionFactory
public void t2() {
//连接池对象
PooledDataSourceFactory pooledDataSourceFactory = new PooledDataSourceFactory();
//数据源参数
Properties properties = new Properties();
properties.put("driver", "com.mysql.jdbc.Driver");
properties.put("url", "jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false");
properties.put("username", "root");
properties.put("password", "root");
pooledDataSourceFactory.setProperties(properties);
//获取数据源
DataSource dataSource = pooledDataSourceFactory.getDataSource();
//设置事务管理器
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//创建上下文环境
Environment environment = new Environment("development", transactionFactory, dataSource);
//组装配置
Configuration configuration = new Configuration(environment);
//添加mapper
configuration.addMapper(PrimerMapper.class);
configuration.addMapper(PrimerMapper2.class);
//获取sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
//打开链接
SqlSession sqlSession = sqlSessionFactory.openSession();
//方式1
String selectManageUserName = (String) sqlSession.selectOne("selectManageUserName", 1);
String selectManageUserName2 = (String) sqlSession.selectOne("selectManageUserName2", 1);
//方式2
PrimerMapper mapper = sqlSession.getMapper(PrimerMapper.class);
String s = mapper.selectManageUserName(1);
sqlSession.close();
}
XML配置
1 properties(属性)
标签properties用于设置mybatis全局配置参数。内部定义property属性,或者引入外部文件,给mybatis注入属性,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>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url"
value="jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</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-root}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-properties/mapper1.xml"/>
</mappers>
</configuration>

以上配置为内部配置property属性,我们也可以引入外部的配置文件。properties使用resource属性或者url属性。
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false jdbc.username=root jdbc.password=root test.a=123 test.b=456

属性注入的顺序是,先使用<property>属性值,在使用resource覆盖,最终直接写入属性值覆盖。最终生效的则是相反。

不管是<property>注入的属性还是外部文件,最终mybatis都将其封装到sqlSessionFactory->configuration->variables中。另外当我们使用${}时,如果没有映射到对应的key,也可以设置默认值。但我们需要先开启默认值。
删除<property>和外部配置文件的jdbc.password使其不存在。发现现在注入的值为${jdbc.password}字面量字符串。

<?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="configuration-properties/db.properties">
<!-- 启用默认值特性 -->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
<property name="test.c" value="678"/>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url"
value="jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="jdbc.username" value="root"/>
</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:root}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-properties/mapper1.xml"/>
</mappers>
</configuration>
开启默认值,并设置默认值。默认值的使用方式是使用 value="${jdbc.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="configuration-properties/db.properties">
<!-- 启用默认值特性 -->
<property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
<!-- 修改默认值的分隔符 默认的 : 和 ?: -->
<property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="-"/>
<property name="test.c" value="678"/>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url"
value="jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="jdbc.username" value="root"/>
</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-root}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-properties/mapper1.xml"/>
</mappers>
</configuration>
2 settings(设置)
2.1 mapUnderscoreToCamelCase 驼峰命名
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="configuration-sittings-mapUnderscoreToCamelCase/mapper1.xml"/> </mappers> </configuration>
<?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"> <mapper namespace="config1"> <select id="selectManageUserName" resultType="configurationSittingsMapUnderscoreToCamelCase.ManageUser"> select * from manage_user where id = #{id} </select> </mapper>
package configurationSittingsMapUnderscoreToCamelCase;/* * @auther 顶风少年 * @mail dfsn19970313@foxmail.com * @date 2019-12-27 07:35 * @notify * @version 1.0 */ import org.apache.ibatis.type.Alias; import java.util.Date; public class ManageUser { private String id; private String username; private String password; private Date createDate; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } }


在数据库中字段create_date映射pojo属性createDate是不行的。此时我们开启自动驼峰命名规则映射可以解决这个问题。
<?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> <!-- 开启驼峰命名映射--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="configuration-sittings-mapUnderscoreToCamelCase/mapper1.xml"/> </mappers> </configuration>

3 类型别名(typeAliases)
在写mapper文件时,必不可少的,我们要给PreparedStatement和Statement指定入参。或者结果集映射返回值。必然的我们需要指定类型。mybatis预选帮我们设置好了常用类型的别名。https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases
package configurationTypeAliases;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-27 07:35
* @notify
* @version 1.0
*/
import java.util.Date;
public class ManageUser {
private String id;
private String username;
private String password;
private Date createDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
<?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>
<!-- 设置别名 -->
<typeAliases>
<typeAlias type="configurationTypeAliases.ManageUser" alias="abc"/>
<!-- <package name="configurationTypeAliases"/>-->
</typeAliases>
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-typeAliases/mapper1.xml"/>
</mappers>
</configuration>
<?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">
<mapper namespace="config1">
<!-- 入参使用别名 -->
<select id="selectManageUserName" resultType="string" parameterType="abc">
select username from manage_user where id = #{id}
</select>
</mapper>
扫描包别名,通常的单个指定别名会比较麻烦,所以我们可以扫描包路径,生成别名。
<?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>
<!-- 设置别名 -->
<typeAliases>
<!-- <typeAlias type="configurationTypeAliases.ManageUser" alias="abc"/>-->
<package name="configurationTypeAliases"/>
</typeAliases>
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-typeAliases/mapper1.xml"/>
</mappers>
</configuration>
<?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">
<mapper namespace="config1">
<!-- 入参使用别名 -->
<select id="selectManageUserName" resultType="string" parameterType="manaGeuser">
select username from manage_user where id = #{id}
</select>
</mapper>

使用包扫描不限制类名大小写。同样我们可以强制要求pojo类的别名。使用@Alias注解
package configurationTypeAliases;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-27 07:35
* @notify
* @version 1.0
*/
import org.apache.ibatis.type.Alias;
import java.util.Date;
@Alias(value = "def")
public class ManageUser {
private String id;
private String username;
private String password;
private Date createDate;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}

一个类可以有多个别名,我们可以在sqlSessionFactory->configuration->typeAliasRegistry->TYPE_ALIASES下寻找定义的别名。其中已经有mybatis预定义的别名。

4 类型转换器(typeHandlers)
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。就是说,在mapper中,我们的Statement入参和返回值都需要经过类型转换器,入参从java类型转成jdbc类型,返回值从jdbc类型转换成java类型。mybatis已经定义了大部分常用的类型转换器。https://mybatis.org/mybatis-3/zh/configuration.html#typeHandlers 下边我们自定义一个String类型转换器,覆盖mybatis定义的转换器。给入参字符串自动拼接,和返回值自动拼接。
package configurationTypeHandlers;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-30 08:17
* @notify
* @version 1.0
*/
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedJdbcTypes(value = {JdbcType.VARCHAR,JdbcType.CHAR},includeNullJdbcType = true)
@MappedTypes(value = String.class)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
System.out.println(parameter);
ps.setString(i, parameter+"d");
}
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
System.out.println("columnName");
return rs.getString(columnName)+"---";
}
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
System.out.println("columnIndex");
return rs.getString(columnIndex)+"|||";
}
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
System.out.println("CallableStatement");
return cs.getString(columnIndex)+"%%%";
}
}
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="string">
select username from manage_user where username = #{username}
</select>
</mapper>
继承BaseTypeHandler类,set()方法是入参,get()是返回值。上边代码片段,我们试图将String和varchar char 互相转换。在ExampleTypeHandler上使用@MappedJdbcTypes和@MappedTypes指定要转换的类型。注意如果需要set()生效则需要在@MappedTypes使用includeNullJdbcType=true。然后在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>
<typeHandlers>
<typeHandler handler="configurationTypeHandlers.ExampleTypeHandler"/>
</typeHandlers>
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-typeHandlers/mapper1.xml"/>
</mappers>
</configuration>
<typeHandler/>有属性jdbcType和javaType会覆盖ExampleTypeHandler类上的@MappedJdbcTypes和@MappedTypes
5 对象工厂(ObjectFactory)
Statement返回结果集为pojo时,mybatis会帮我们实例化pojo对象。默认的会调用DefaultObjectFactory,我们可以继承此类,然后对返回pojo进行改造。setProperties()方法将<objectFactory/>中的<property/>属性映射到参数中,我们可将其设置为成员变量,在create()方法中使用。
package configurationObjectFactory;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-27 07:35
* @notify
* @version 1.0
*/
import java.util.Date;
public class ObjectFactoryManageUser {
private String id;
private String username;
private String password;
private Date createDate;
private String prp;
public ObjectFactoryManageUser() {
}
public void setPrp(String prp) {
this.prp = prp;
}
}
<?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>
<objectFactory type="configurationObjectFactory.ExampleObjectFactory">
<property name="prp" value="AAA"/>
</objectFactory>
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-ObjectFactory/mapper1.xml"/>
</mappers>
</configuration>
package configurationObjectFactory;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-30 10:47
* @notify
* @version 1.0
*/
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import java.util.List;
import java.util.Properties;
public class ExampleObjectFactory extends DefaultObjectFactory {
Properties properties = new Properties();
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs){
T ret = super.create(type,constructorArgTypes,constructorArgs);
if(ObjectFactoryManageUser.class.isAssignableFrom(type)){
ObjectFactoryManageUser objectFactoryManageUser =(ObjectFactoryManageUser) ret;
objectFactoryManageUser.setPrp((String) properties.get("prp"));
}
return ret;
}
@Override
public void setProperties(Properties properties) {
this.properties = properties;
}
}
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="configurationObjectFactory.ObjectFactoryManageUser">
select * from manage_user where id = #{id}
</select>
</mapper>

6 插件(plugins)
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。如果你想做的不仅仅是监控方法的调用,那么你最好相当了解要重写的方法的行为。 因为如果在试图修改或重写已有方法的行为的时候,你很可能在破坏 MyBatis 的核心模块。 这些都是更低层的类和方法,所以使用插件的时候要特别当心。以下代码片段是对返回值拦截。
package configurationPlugins;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-30 16:28
* @notify
* @version 1.0
*/
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.sql.Statement;
import java.util.Properties;
/*
注解接收数组,类型为@Signature
而@Signature三个参数分别是,要拦截的类,要拦截的方法,方法参数。
注意可拦截的类和方法为
//执行sql
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
//获取、设置参数
ParameterHandler (getParameterObject, setParameters)
//处理结果集
ResultSetHandler (handleResultSets, handleOutputParameters)
//记录sql
StatementHandler (prepare, parameterize, batch, update, query)
*/
@Intercepts(value = {@Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = {Statement.class})})
public class ExamplePlugin implements Interceptor {
private Properties properties = new Properties();
//拦截类
public Object intercept(Invocation invocation) throws Throwable {
System.out.println(properties.getProperty("timeout"));
return invocation.proceed();
}
//返回当前插件
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
//将xml配置的property绑定到成员变量上
public void setProperties(Properties properties) {
this.properties = properties;
}
}
<?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>
<!-- 配置插件 -->
<plugins>
<plugin interceptor="configurationPlugins.ExamplePlugin">
<property name="timeout" value="100"/>
</plugin>
</plugins>
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-plugins/mapper1.xml"/>
</mappers>
</configuration>
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="string">
select username from manage_user where id = #{id}
</select>
</mapper>

7 环境配置(environments)
使用mybatis,在可能的情况下我们会有多种环境,例如测试环境,生产环境等。我们可以通过配置environment来确定使用的环境。
<?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="development2">
<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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="development2">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root2"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="configuration-environments/mapper1.xml"/>
</mappers>
</configuration>
每个environment有唯一的id,在environment标签上使用default属性,表示要使用的是哪个environment。以上我们使用environment2,但是他的密码是错误的,所以连接失败。

另外我们还可以在创建sqlSessionFactory时,指定要使用的环境,但是这样会使default失效。

关于环境的事务管理器,数据源配置可查看 https://mybatis.org/mybatis-3/zh/configuration.html#environments
8 数据库厂商标识(databaseIdProvider)
在正式开发中,我们可能会需要配置多种数据库。不同的数据库会有不同的方言,下面我们模拟这种情况。
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<databaseIdProvider type="DB_VENDOR">
<property name="SQL Server" value="sqlserver"/>
<property name="DB2" value="db2"/>
<property name="Oracle" value="oracle" />
<property name="MySQL" value="mysql" />
</databaseIdProvider>
<mappers>
<mapper resource="configuration-databaseIdProvider/mapper1.xml"/>
</mappers>
</configuration>
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="string" databaseId="mysql">
select username from manage_user where id = 2
</select>
<select id="selectManageUserName" resultType="string">
select username from manage_user where id = 1
</select>
</mapper>
在mybatis配置文件中使用<databaseIdProvider/>标签,<property/>声明数据库名称和别名。在mapper中,可以给Statement指定数据库。可以看到,上边的代码片段,我们有两个id相同的查询语句。其中一个指定的有databaseId,mybatis会优先使用带有数据库标识的,如果发现标识不存在,或者数据库类型不匹配,才会转向使用不带标识的Statement。


9 映射器(mappers)
最终我们的目的是执行sql语句,我们在mybatis配置文件中引入mapper文件,或者mapper类。
1 使用相对于类路径的资源引用
<?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">
<mapper namespace="config1">
<select id="selectManageUserName" resultType="string">
select username from manage_user where id = #{id}
</select>
</mapper>
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 使用相对于类路径的资源引用 -->
<mapper resource="configuration-mappers/mapper1.xml"/>
</mappers>
</configuration>
2 使用完全限定资源定位符(URL)
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 使用相对于类路径的资源引用 -->
<!-- <mapper resource="configuration-mappers/mapper1.xml"/>-->
<!-- 使用完全限定资源定位符(URL)-->
<mapper url="file:\\\c:\workspace\mybatis\src\main\resources\configuration-mappers\mapper1.xml"/>
</mappers>
</configuration>
3 使用映射器接口实现类的完全限定类名,引入mapper接口
package configurationMappers;/*
* @auther 顶风少年
* @mail dfsn19970313@foxmail.com
* @date 2019-12-26 10:39
* @notify
* @version 1.0
*/
import org.apache.ibatis.annotations.Select;
public interface PrimerMapper {
@Select("select username from manage_user where id = #{id}")
String selectManageUserName(int id);
}
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 使用相对于类路径的资源引用 -->
<!-- <mapper resource="configuration-mappers/mapper1.xml"/>-->
<!-- 使用完全限定资源定位符(URL)-->
<!-- <mapper url="file:\\\c:\workspace\mybatis\src\main\resources\configuration-mappers\mapper1.xml"/>-->
<!-- 使用映射器接口实现类的完全限定类名-->
<mapper class="configurationMappers.PrimerMapper"/>
</mappers>
</configuration>
4 将包内的映射器接口实现全部注册为映射器
<?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/petstore?serverTimezone=GMT%2B8&characterEncoding=utf8&useUnicode=true&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 使用相对于类路径的资源引用 -->
<!-- <mapper resource="configuration-mappers/mapper1.xml"/>-->
<!-- 使用完全限定资源定位符(URL)-->
<!-- <mapper url="file:\\\c:\workspace\mybatis\src\main\resources\configuration-mappers\mapper1.xml"/>-->
<!-- 使用映射器接口实现类的完全限定类名-->
<!-- <mapper class="configurationMappers.PrimerMapper"/>-->
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<package name="configurationMappers"/>
</mappers>
</configuration>