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>
 
                    
                     
                    
                 
                    
                 
 
 
                
            
        