• myBatis03 主配置文件


    myBatis主配置文件相关配置参考文档:https://mybatis.org/mybatis-3/zh/configuration.html

    0、项目文件结构

    1、主配置文件相关配置项目

    2、相关属性介绍

    2.1、属性(properties)

    用来定义一些常用的属性,可以放到外部文件定义,也可以放在标记内不定义,定义的属性可以在配置文件中使用${属性名}

        <!-- 引入外部属性配置文件 -->
        <properties resource="jdbc.Properties">
            <!-- 内部额外定义的属性,这些属性都可以在配置文件中通过${属性名}使用 -->
            <property name="jdbc.other" value="other"/>
        </properties>
    

    jdbc.Properties文件创建在src/main/resources根目录中,具体内容如下:

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://47.100.229.xxx:3306/springStudy?useSSL=false&serverTimezone=UTC
    jdbc.username=root
    jdbc.password=xxx
    

    定义的属性可以在配置文件中使用

    2.2、设置(settings)

    这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。

    配置例子:

        <!-- 全局配置参数,相关的参数参照myBatis文档 -->
        <settings>
            <!-- 是否开启缓存 -->
            <setting name="cacheEnabled" value="true"/>
            <!-- 是否开启懒加载 -->
            <setting name="lazyLoadingEnabled" value="true"/>
    
        </settings>
    

    myBatis提供的相关配置项目及含义

    设置名描述有效值默认值
    cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true | false true
    lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 true | false false
    aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 true | false false (在 3.4.1 及之前的版本中默认为 true)
    multipleResultSetsEnabled 是否允许单个语句返回多结果集(需要数据库驱动支持)。 true | false true
    useColumnLabel 使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。 true | false true
    useGeneratedKeys 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 true | false False
    autoMappingBehavior 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 NONE, PARTIAL, FULL PARTIAL
    autoMappingUnknownColumnBehavior 指定发现自动映射目标未知列(或未知属性类型)的行为。
    • NONE: 不做任何反应
    • WARNING: 输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN
    • FAILING: 映射失败 (抛出 SqlSessionException)
    NONE, WARNING, FAILING NONE
    defaultExecutorType 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 SIMPLE REUSE BATCH SIMPLE
    defaultStatementTimeout 设置超时时间,它决定数据库驱动等待数据库响应的秒数。 任意正整数 未设置 (null)
    defaultFetchSize 为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。 任意正整数 未设置 (null)
    defaultResultSetType 指定语句默认的滚动策略。(新增于 3.5.2) FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置) 未设置 (null)
    safeRowBoundsEnabled 是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 true | false False
    safeResultHandlerEnabled 是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。 true | false True
    mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 true | false False
    localCacheScope MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。 SESSION | STATEMENT SESSION
    jdbcTypeForNull 当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 JdbcType 常量,常用值:NULL、VARCHAR 或 OTHER。 OTHER
    lazyLoadTriggerMethods 指定对象的哪些方法触发一次延迟加载。 用逗号分隔的方法列表。 equals,clone,hashCode,toString
    defaultScriptingLanguage 指定动态 SQL 生成使用的默认脚本语言。 一个类型别名或全限定类名。 org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
    defaultEnumTypeHandler 指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5) 一个类型别名或全限定类名。 org.apache.ibatis.type.EnumTypeHandler
    callSettersOnNulls 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。 true | false false
    returnInstanceForEmptyRow 当返回行的所有列都是空时,MyBatis默认返回 null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集(如集合或关联)。(新增于 3.4.2) true | false false
    logPrefix 指定 MyBatis 增加到日志名称的前缀。 任何字符串 未设置
    logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 SLF4J | LOG4J(deprecated since 3.5.9) | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 未设置
    proxyFactory 指定 Mybatis 创建可延迟加载对象所用到的代理工具。 CGLIB | JAVASSIST JAVASSIST (MyBatis 3.3 以上)
    vfsImpl 指定 VFS 的实现 自定义 VFS 的实现的类全限定名,以逗号分隔。 未设置
    useActualParamName 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1) true | false true
    configurationFactory 指定一个提供 Configuration 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3) 一个类型别名或完全限定类名。 未设置
    shrinkWhitespacesInSql 从SQL中删除多余的空格字符。请注意,这也会影响SQL中的文字字符串。 (新增于 3.5.5) true | false false
    defaultSqlProviderType Specifies an sql provider class that holds provider method (Since 3.5.6). This class apply to the type(or value) attribute on sql provider annotation(e.g. @SelectProvider), when these attribute was omitted. A type alias or fully qualified class name Not set
    nullableOnForEach Specifies the default value of 'nullable' attribute on 'foreach' tag. (Since 3.5.9) true | false false

    2.3、类型别名(typeAliases)

    类型别名可为 Java 类型设置一个缩写名字。可以在Mapper文件中使用。

    配置例子:

        <!-- 类型别名,声明的短名称可以在Mapper文件中替代使用 -->
        <typeAliases>
            <typeAlias alias="employee" type="db.Domain.Employee"></typeAlias>
            <!--
                自动为包内所有类创建类型别名,默认是首字母小写的类名称
                也可以在类上方通过@Alias("别名")类设置所需要的别名
            -->
            <package name="db.Domain"/>
        </typeAliases>
    

    下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。

    别名映射的类型
    _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

    2.4、类型处理器(typeHandlers)

    在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。

    为了演示改效果:在数据库中增加isDelete字段,数据库类型用的Bit,程序里边用是/否

    数据库表结构:

    模型类新代码:

    package db.Domain;
    
    
    import org.springframework.stereotype.Component;
    
    import java.sql.Date;
    
    @Component(value = "employee")
    public class Employee {
        private String emplId;
        private String name;
        private String gender;
        private Date hireDate;
        private int salary;
        //程序中用String,数据库用布尔类型
        private String isDelete;
    
        public Employee(String emplId, String name, String gender, Date hireDate, int salary,String isDelete) {
            this.emplId = emplId;
            this.name = name;
            this.gender = gender;
            this.hireDate = hireDate;
            this.salary = salary;
            this.isDelete = isDelete;
        }
    
        public String getEmplId() {
            return emplId;
        }
        public void setEmplId(String emplId) {
            this.emplId = emplId;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        public Date getHireDate() {
            return hireDate;
        }
        public void setHireDate(Date hireDate) {
            this.hireDate = hireDate;
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
        public String getDelete() {return isDelete;}
        public void setDelete(String delete) {isDelete = delete;}
    
        @Override
        public String toString() {
            return "Employee{" +
                    "emplId='" + emplId + '\'' +
                    ", name='" + name + '\'' +
                    ", gender='" + gender + '\'' +
                    ", hireDate=" + hireDate +
                    ", salary=" + salary +
                    ", isDelete=" + isDelete +
                    '}';
        }
    
        //实例化后执行的方法
        public void init()
        {
            //完成对其它的业务处理
            System.out.println("init执行");
        }
    }

    参考配置:

        <!--
            从数据库的类型转为Java的类型,将Java类型的参数转换为数据库对应类型
            MyBatis默认提供了一些类型处理器,基本不需要自己定义
            jdbcType必须是枚举值 JDBCType.XXX
            了解即可,使用少
        -->
        <typeHandlers>
            <typeHandler handler="db.TypeHandles.isDeleteTypeHandle"
                         javaType="java.lang.String"
                         jdbcType="BIT"></typeHandler>
        </typeHandlers>

    定义类型转换类:

    package db.TypeHandles;
    
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeHandler;
    
    import java.sql.*;
    
    //是否删除字段,数据库BIT类型,程序操作:是否
    public class isDeleteTypeHandle implements TypeHandler<String> {
    
        //是设置为true,否设置为false
        @Override
        public void setParameter(PreparedStatement ps, int i, String b, JdbcType jdbcType) throws SQLException {
            System.out.println("参数值="+b);
            if(b.equals("是"))
                ps.setBoolean(i,true);
            if(b.equals("否"))
                ps.setBoolean(i,false);
        }
    
        @Override
        public String getResult(ResultSet rs, String s) throws SQLException {
            boolean r = rs.getBoolean(s);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    
        @Override
        public String getResult(ResultSet rs, int i) throws SQLException {
            boolean r = rs.getBoolean(i);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    
        @Override
        public String getResult(CallableStatement cs, int i) throws SQLException {
            boolean r = cs.getBoolean(i);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    }

    在Mapper文件中使用类型转换器:jdbcType的取值必须是枚举JDBCType.xxx内部包含的某一个类型。

    <?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="db.Dao.EmployeeDao">
        <!--主键查询-->
        <select id="queryByEmplId" resultType="db.Domain.Employee">
            select * from Employee where emplId=#{emplId}
        </select>
        <!--条件查询-->
        <select id="queryListBySalary" resultType="employee" >
            select * from Employee where salary BETWEEN #{start} and #{end}
        </select>
        <!--新增-->
        <insert id="insert" parameterType="db.Domain.Employee">
            insert into employee(emplId,`name`,gender,hireDate,salary,isDelete)
                values(#{emplId},#{name},#{gender},
                       #{hireDate},#{salary},
                       #{isDelete,javaType=java.lang.String,jdbcType=BIT,typeHandler=db.TypeHandles.isDeleteTypeHandle})
        </insert>
        <!--修改-->
        <update id="update" parameterType="db.Domain.Employee">
            update employee set `name`=#{name},gender=#{gender},salary=#{salary},
                                isDelete=#{isDelete,javaType=java.lang.String,jdbcType=BIT,typeHandler=db.TypeHandles.isDeleteTypeHandle}
            where emplId=#{emplId}
        </update>
        <delete id="delete">
            delete from employee where emplId=#{emplId}
        </delete>
    </mapper>

    测试输出结果,自动显示为是和否。

    2.5、对象工厂(objectFactory)

    每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。 如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现。

    配置例子:

        <!--
            对象工厂,用来完成查询结果映射对ResultType时进行的的业务处理
            每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。
            默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。
            如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现
            了解即可,使用少
         -->
        <objectFactory type="db.ObjectFactory.ExampleObjectFactory">
    
        </objectFactory>
    

    定义工厂类:

    工厂类内部调用的模型类,必须提供带参数的构造方法,否则无法给参数复制。

    package db.ObjectFactory;
    
    import db.Domain.Employee;
    import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
    
    import java.util.List;
    
    //自定义对象生成工程
    public class ExampleObjectFactory extends DefaultObjectFactory {
        @Override
        public <T> T create(Class<T> type) {
            return super.create(type);
        }
    
        @Override
        public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
            T ret = super.create(type, constructorArgTypes, constructorArgs);
            //如果是Employee类型,Employee需要提供带参数的构造函数,否则获取的对象属性没有数据值
            if(Employee.class.isAssignableFrom(type))
            {
                Employee emp = (Employee)ret;
                System.out.println("工厂对象输出:"+emp.toString());
            }
            return  ret;
        }
    }
    

    运行结果:

    2.6、插件(plugins)

    有点复杂,文档没有详细说明每个拦截位置的要求。

    MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

    • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
    • ParameterHandler (getParameterObject, setParameters)
    • ResultSetHandler (handleResultSets, handleOutputParameters)
    • StatementHandler (prepare, parameterize, batch, update, query)

    配置例子:

        <!--
            MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用
            了解即可,使用少
        -->
        <plugins>
            <plugin interceptor="db.Plugin.ExamplePlugin">
    
            </plugin>
        </plugins>
    

    插件类定义:

    package db.Plugin;
    
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.plugin.Interceptor;
    import org.apache.ibatis.plugin.Intercepts;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.plugin.Signature;
    
    import java.util.Properties;
    
    //拦截器注解,拦截范围定义
    @Intercepts({@Signature(
            type= Executor.class,
            method = "update",
            args = {MappedStatement.class,Object.class})})
    public class ExamplePlugin implements Interceptor {
        private Properties properties = new Properties();
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("拦截器前执行");
            Object returnObject = invocation.proceed();
            System.out.println("拦截器后执行");
            return returnObject;
        }
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    }
    

    运行结果:删除,新增,修改都会有输出。

    2.7、环境配置(environments)

    MyBatis 可以配置成适应多种环境,方便开发、测试,上线不同的环境参数。

    配置例子:

    <!--
            在主配置文件中允许同时配置多个环境
            通过default切换所用的配置
        -->
        <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>
            <!-- 上线环境 -->
            <environment id="oneline">
                <!-- 事务类型 -->
                <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>
    

    2.8、映射器(mappers)

    用来引入表的配置,可以引入Mapper文件,也可以引入类定义

    引入Mapper文件:

        <!-- 映射器配置 -->
        <!-- 引入表的接口类 -->
        <mappers>
            <mapper resource="db/mapper/EmployeeMapper.xml"/>
        </mappers>
    

    引入类文件:采用注解的方式时用。

    <mappers>
      <mapper class="org.mybatis.builder.AuthorMapper"/>
      <mapper class="org.mybatis.builder.BlogMapper"/>
      <mapper class="org.mybatis.builder.PostMapper"/>
    </mappers>
    

    批量引入:

    <!-- 将包内的映射器接口实现全部注册为映射器 -->
    <mappers>
      <package name="org.mybatis.builder"/>
    </mappers>

    3、相关代码

    3.1 模型类

    package db.Domain;
    
    
    import org.springframework.stereotype.Component;
    
    import java.sql.Date;
    
    @Component(value = "employee")
    public class Employee {
        private String emplId;
        private String name;
        private String gender;
        private Date hireDate;
        private int salary;
        //程序中用String,数据库用布尔类型
        private String isDelete;
    
        public Employee(String emplId, String name, String gender, Date hireDate, int salary,String isDelete) {
            this.emplId = emplId;
            this.name = name;
            this.gender = gender;
            this.hireDate = hireDate;
            this.salary = salary;
            this.isDelete = isDelete;
        }
    
        public String getEmplId() {
            return emplId;
        }
        public void setEmplId(String emplId) {
            this.emplId = emplId;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        public Date getHireDate() {
            return hireDate;
        }
        public void setHireDate(Date hireDate) {
            this.hireDate = hireDate;
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
        public String getDelete() {return isDelete;}
        public void setDelete(String delete) {isDelete = delete;}
    
        @Override
        public String toString() {
            return "Employee{" +
                    "emplId='" + emplId + '\'' +
                    ", name='" + name + '\'' +
                    ", gender='" + gender + '\'' +
                    ", hireDate=" + hireDate +
                    ", salary=" + salary +
                    ", isDelete=" + isDelete +
                    '}';
        }
    
        //实例化后执行的方法
        public void init()
        {
            //完成对其它的业务处理
            System.out.println("init执行");
        }
    }

    3.2 接口类

    package db.Dao;
    
    import db.Domain.Employee;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    //数据访问接口 - 注解方式
    public interface EmployeeDao {
    
        //查询单个对象,单个参数时@Param可以省略
        public Employee queryByEmplId(@Param("emplId") String empId);
    
        //查询多个对象,多个参数时需要通过@Param声明
        public List<Employee> queryListBySalary(@Param("start") int start, @Param("end") int end);
    
        //新增数据
        public int insert(Employee emp);
    
        //更新数据
        public int update(Employee emp);
    
        //删除数据
        public void delete(@Param("emplId") String empId);
    
    }

    3.3 属性配置

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://47.100.229.xxx:3306/springStudy?useSSL=false&serverTimezone=UTC
    jdbc.username=root
    jdbc.password=xxx

    3.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>
    
        <!-- 引入外部属性配置文件 -->
        <properties resource="jdbc.Properties">
            <!-- 内部额外定义的属性,这些属性都可以在配置文件中通过${属性名}使用 -->
            <property name="jdbc.other" value="other"/>
        </properties>
    
        <!-- 全局配置参数,相关的参数参照myBatis文档 -->
        <settings>
            <!-- 是否开启缓存 -->
            <setting name="cacheEnabled" value="true"/>
            <!-- 是否开启懒加载 -->
            <setting name="lazyLoadingEnabled" value="true"/>
    
        </settings>
    
        <!-- 类型别名,声明的短名称可以在Mapper文件中替代使用 -->
        <typeAliases>
            <typeAlias alias="employee" type="db.Domain.Employee"></typeAlias>
            <!--
                自动为包内所有类创建类型别名,默认是首字母小写的类名称
                也可以在类上方通过@Alias("别名")类设置所需要的别名
            -->
            <package name="db.Domain"/>
        </typeAliases>
    
        <!--
            从数据库的类型转为Java的类型,将Java类型的参数转换为数据库对应类型
            MyBatis默认提供了一些类型处理器,基本不需要自己定义
            jdbcType必须是枚举值 JDBCType.XXX
            了解即可,使用少
        -->
        <typeHandlers>
            <typeHandler handler="db.TypeHandles.isDeleteTypeHandle"
                         javaType="java.lang.String"
                         jdbcType="BIT"></typeHandler>
        </typeHandlers>
    
        <!--
            对象工厂,用来完成查询结果映射对ResultType时进行的的业务处理
            每次 MyBatis 创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成实例化工作。
            默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认无参构造方法,要么通过存在的参数映射来调用带有参数的构造方法。
            如果想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现
            了解即可,使用少
         -->
        <objectFactory type="db.ObjectFactory.ExampleObjectFactory">
    
        </objectFactory>
    
        <!--
            MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用
            了解即可,使用少
        -->
        <plugins>
            <plugin interceptor="db.Plugin.ExamplePlugin">
    
            </plugin>
        </plugins>
    
        <!--
            在主配置文件中允许同时配置多个环境
            通过default切换所用的配置
        -->
        <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>
            <!-- 上线环境 -->
            <environment id="oneline">
                <!-- 事务类型 -->
                <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="db/mapper/EmployeeMapper.xml"/>
        </mappers>
    </configuration>

    3.5 映射文件

    <?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="db.Dao.EmployeeDao">
        <!--主键查询-->
        <select id="queryByEmplId" resultType="db.Domain.Employee">
            select * from Employee where emplId=#{emplId}
        </select>
        <!--条件查询-->
        <select id="queryListBySalary" resultType="employee" >
            select * from Employee where salary BETWEEN #{start} and #{end}
        </select>
        <!--新增-->
        <insert id="insert" parameterType="db.Domain.Employee">
            insert into employee(emplId,`name`,gender,hireDate,salary,isDelete)
                values(#{emplId},#{name},#{gender},
                       #{hireDate},#{salary},
                       #{isDelete,javaType=java.lang.String,jdbcType=BIT,typeHandler=db.TypeHandles.isDeleteTypeHandle})
        </insert>
        <!--修改-->
        <update id="update" parameterType="db.Domain.Employee">
            update employee set `name`=#{name},gender=#{gender},salary=#{salary},
                                isDelete=#{isDelete,javaType=java.lang.String,jdbcType=BIT,typeHandler=db.TypeHandles.isDeleteTypeHandle}
            where emplId=#{emplId}
        </update>
        <delete id="delete">
            delete from employee where emplId=#{emplId}
        </delete>
    </mapper>

    3.6 类型转换类

    package db.TypeHandles;
    
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeHandler;
    
    import java.sql.*;
    
    //是否删除字段,数据库BIT类型,程序操作:是否
    public class isDeleteTypeHandle implements TypeHandler<String> {
    
        //是设置为true,否设置为false
        @Override
        public void setParameter(PreparedStatement ps, int i, String b, JdbcType jdbcType) throws SQLException {
            System.out.println("参数值="+b);
            if(b.equals("是"))
                ps.setBoolean(i,true);
            if(b.equals("否"))
                ps.setBoolean(i,false);
        }
    
        @Override
        public String getResult(ResultSet rs, String s) throws SQLException {
            boolean r = rs.getBoolean(s);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    
        @Override
        public String getResult(ResultSet rs, int i) throws SQLException {
            boolean r = rs.getBoolean(i);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    
        @Override
        public String getResult(CallableStatement cs, int i) throws SQLException {
            boolean r = cs.getBoolean(i);
            if(r==true)
                return "是";
            if(r==false)
                return "否";
            return null;
        }
    }

    3.7 对象工厂类

    package db.ObjectFactory;
    
    import db.Domain.Employee;
    import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
    
    import java.util.List;
    
    //自定义对象生成工程
    public class ExampleObjectFactory extends DefaultObjectFactory {
        @Override
        public <T> T create(Class<T> type) {
            return super.create(type);
        }
    
        @Override
        public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
            T ret = super.create(type, constructorArgTypes, constructorArgs);
            //如果是Employee类型,Employee需要提供带参数的构造函数,否则获取的对象属性没有数据值
            if(Employee.class.isAssignableFrom(type))
            {
                Employee emp = (Employee)ret;
                //自动调用后续的处理方法
                emp.init();
                System.out.println("工厂对象输出:"+emp.toString());
            }
            return  ret;
        }
    }

    3.8 插件类

    package db.Plugin;
    
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.plugin.Interceptor;
    import org.apache.ibatis.plugin.Intercepts;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.plugin.Signature;
    
    import java.util.Properties;
    
    //拦截器注解,拦截范围定义
    @Intercepts({@Signature(
            type= Executor.class,
            method = "update",
            args = {MappedStatement.class,Object.class})})
    public class ExamplePlugin implements Interceptor {
        private Properties properties = new Properties();
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("拦截器前执行");
            Object returnObject = invocation.proceed();
            System.out.println("拦截器后执行");
            return returnObject;
        }
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    }

    3.9 测试代码

    import db.Dao.EmployeeDao;
    import db.Domain.Employee;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Date;
    import java.util.List;
    
    public class myTest {
        @Test
        public void TestMyBaisc() throws IOException {
            //1 读取配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //2 构建SqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //3 构建SqlSession,并执行mapper内操作
            try (SqlSession session = sqlSessionFactory.openSession()) {
                //获取接口代理实现
                EmployeeDao dao = session.getMapper(EmployeeDao.class);
                //单数据查询
                {
                    System.out.println("==单数据查询");
                    Employee empl = dao.queryByEmplId("001");
                    System.out.println(empl.toString());
                }
                //数据删除
                {
                    System.out.println("==数据删除");
                    dao.delete("005");
                    session.commit();
                }
                //数据新增
                {
                    System.out.println("==数据新增");
                    Employee empl = new Employee("005","李晓明","男",new Date(2020,10,10),2000,"是");
                    int result = dao.insert(empl);
                    session.commit();
                    System.out.println("行数:"+result);
                }
                //多数据查询
                {
                    System.out.println("==多数据查询 - 新增后");
                    List<Employee> list = dao.queryListBySalary(20,5000);
                    for (Employee item : list) {
                        System.out.println(item.toString());
                    }
                }
                //数据修改
                {
                    System.out.println("==数据修改");
                    Employee empl = new Employee("003","刘超","男",new Date(2020,10,10),2000,"是");
                    int result = dao.update(empl);
                    session.commit();
                    System.out.println("行数:"+result);
                }
                //多数据查询
                {
                    System.out.println("==多数据查询 - 修改后");
                    List<Employee> list = dao.queryListBySalary(20,5000);
                    for (Employee item : list) {
                        System.out.println(item.toString());
                    }
                }
            }
            System.out.println("测试完成1");
        }
    }

      

  • 相关阅读:
    C# 开源框架(整理)
    设计模式六大原则
    注册3D组件
    asp.net mvc(模式)和三层架构(BLL、DAL、Model)的联系与区别 (转)
    MVC5中利用NOPI导出EXCLE
    C# 连接 Oracle 的几种方式
    web.config 为某个单独页面设置编码格式
    解析ASP,NET MVC 中 web.config XML文件 取出数据库类型
    SNMP4J与ObjectSNMP对比分析
    SNMP简单概述
  • 原文地址:https://www.cnblogs.com/feihusurfer/p/15876717.html
Copyright © 2020-2023  润新知