Mybatis 全局配置文件(三)

news2024/11/18 20:46:18

文章目录

  • 第一章:概述
  • 第二章:properties (了解)
  • 第三章:settings
  • 第四章:typeAliases (别名处理器)
  • 第五章:typeHandlers (类型处理器)
  • 第六章:plugins(插件)
  • 第七章:environments (环境)
  • 第八章:databaseIdProvider
  • 第九章:mapper(映射)
  • Mybatis 的映射文件
    • 第一章:增删改查
    • 第二章:INSERT 获取自增主键的值
    • 第三章:INSERT 获取非自增主键的值
    • 第四章:参数处理
      • 4.1 单个参数
      • 4.2 多个参数
      • 4.3 命名参数
      • 4.4 POJO
      • 4.5 Map
      • 4.6 TO
      • 4.7 Collection 类型(List类型、Set类型)数组类型
      • 4.9 #取值时指定参数的相关规则
    • 第五章:select 元素
      • 5.1 概述
      • 5.2 resultType
        • 5.2.1 返回 List
        • 5.2.2 返回 Map
      • 5.3 resultMap
        • 5.3.1 自定义结果映射规则
        • 5.3.2 关联查询
          • 5.3.2.1 环境搭建
          • 5.3.2.2 级联属性封装查询结果
          • 5.3.2.3 association 定义关联对象
          • 5.3.2.4 association 分步查询
            • 分步查询中使用延迟加载:需要在 mybatis-config.xml 中配置如下的全局设置
          • 5.3.2.5 collection 定义关联集合封装规则
          • 5.3.2.6 collection 定义分步查询
          • 5.2.3.7 分步查询传递多列值
          • 5.2.3.8 fetchType
          • 5.2.3.9 discriminator 鉴别器
    • 小结

第一章:概述

  • Mybatis 的全局配置文件包含了影响 Mybatis 行为甚深的设置( settings )和属性( properties )信息。
  • 文档的顶层结构如下:
    • Configuration 配置:
      • properties 属性
      • settings 设置
      • typeAliases 类型命名
      • typeHandlers 类型处理器
      • objectFactory 对象工厂
      • plugins 插件
      • environments 环境
      • environment 环境变量
        • transactionManager 事务管理器
        • dataSource 数据源
        • databaseIdProvider 数据库厂商标识
      • mappers 映射器

第二章:properties (了解)

●Mybatis 可以使用 properties 标签来引入外部的 properties 属性配置文件中的内容。
●属性:
○resource:引入类路径下的配置文件。
○url:引入网络或磁盘上的配置文件。

●示例:

  • db.properties
jdbc.url=jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=123456
  • mybatis-config.xml
<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties" ></properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>

第三章:settings

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

  • 示例:

  • mybatis-config.xml

<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties" ></properties>

    <settings>
        <!-- 
            开启自动驼峰命名规则映射,可以将诸如last_name封装为lastName。
         -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>

第四章:typeAliases (别名处理器)

  • 类型别名是为 Java 类型设置一个短的名字,可以方便我们引用某个类。
<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties" ></properties>

    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <!--
            类型别名是为Java类型设置一个短的名字,可以方便我们引用某个类
        -->
        <typeAlias type="com.xuguoguo.domain.Employee" alias="emp"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>
  • 在类很多的情况下,可以批量设置别名。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties" ></properties>

    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <!--  
            通过package标签的name属性指定需要生成别名的包,默认会创建一个别名,就是类名的小写
        -->
        <package name="com.xuguoguo"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>
  • 可以在类上使用 @Alias 注解设置别名:
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • 需要注意的是,Mybatis 已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大小写不敏感的,我们在起别名的时候千万不要占用已有的别名。
    • 别名映射的类型
      在这里插入图片描述

第五章:typeHandlers (类型处理器)

  • 无论是 Mybatis 在预处理语句( PreparedStatement )中设置一个参数时,还是从结果集中取出一个值的时候,都会用类型处理器将获取的值以合适的方式转换为 Java 类型。
    在这里插入图片描述

  • 日期类型的处理:JDK 1.8 以前一直是个头疼的问题。我们通常使用 JSR 310 规范领导者 Stephen Colebourne 创建的 Joda-Time 来操作。JDK 1.8 已经实现全部的 JSR 310 规范了。日期时间处理上,我们可以使用 Mybatis 基于 JSR 310 编写的各种日期时间类型处理器。Mybatis 3.4 以前的版本需要我们手动注册这些处理器,以后的版本都是自动注册的。

  • 自定义类型处理器:我们可以重写类型处理器或者创建自己的类型处理器来处理器不支持的或非标准的类型。

  • 步骤:

  • ① 实现 org.apche.ibatis.type.TypeHandler 接口或者继承 org.apche.ibatis.type.BaseTypeHandler 。

  • ② 指定其映射某个 JDBC 类型。

  • ③ 在 Mybatis 的全局配置文件中注册。

第六章:plugins(插件)

  • 插件是 Mybatis 提供的一个非常强大的机制,我们可以通过插件来修改 Mybatis 的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行。
Executor(update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
ParameterHandler(getParameterObject, setParameters)
ResultSetHandler(handleResultSets, handleOutputParameters)
StatementHandler(prepare, parameterize, batch, update, query)

第七章:environments (环境)

  • Mybatis 可以配置多种环境,比如开发、测试和生产环境需要有不同的配置。

  • 每种环境使用一个 environment 标签进行配置并指定唯一标识符。

  • 可以通过 environments 标签中的 default 属性指定一个环境的标识符来快速的切换环境。

  • environment:指定具体环境

    • id:指定当前环境的唯一标识。
    • transactionManager:事务管理器。
      • type:事务管理器的类型。有 JDBC 、MANAGED 和自定义类型。
        • JDBC:使用了 JDBC 的提交和回滚设置,依赖于从数据源得到的连接来管理事务范围。
        • MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期。
        • 自定义:实现 TransactionFactory 接口,type = 全类名/别名。
    • dataSource:数据源。
      • type:数据源类型。有 UNPOOLED、POOLED、JNDI 和自定义类型。
        • UNPOOLED:不使用连接池。
        • POOLED:使用连接池。
        • JNDI:在EJB或应用服务器这类容器中查找指定的数据源。
        • 自定义:实现 DataSourceFactory 接口,定义数据源的获取方式。
  • 示例:

<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties" ></properties>

    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <!--
            通过package标签的name指定需要生成别名的包,默认会创建一个别名,就是类名的小写
        -->
        <package name="com.xuguoguo"/>
    </typeAliases>

    <!--
        environments,Mybatis可以配置多种环境
            environment:配置一个具体的环境信息;必须有transactionManager和dataSource标签。属性id代表当前环境的标识,可以达到快速切换环境
                transactionManager:事务管理器
                    type:事务管理器的类型,有JDBC和MANAGED两种类型,还可以自定义事务管理器
                dataSource:数据源
                    type:数据源的类型,有UNPOOLED、POOLED、JNDI和自定义类型。
    -->
    <environments default="development">
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>

第八章:databaseIdProvider

  • Mybatis 可以根据不同的数据库厂商执行不同的语句。
<databaseIdProvider type="DB_VENDOR">
    <!--
    为不同的数据库厂商起别名
    -->
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
    <property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
  • databaseIdProvider 标签的属性 type 的值是 DB_VENDOR ,会通过 DatabaseMetaData 中的 getDatabaseProductName() 方法返回的字符串进行设置。由于通常情况下这个字符串非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短。

  • Mybatis 的匹配规则如下:

    • ① 如果没有配置 databaseIdProvider 标签,那么 databaseId 的值就为 null 。
    • ② 如果配置了 databaseIdProvider 标签,使用标签配置的name去匹配数据库的信息,匹配上设置 databaseId = 配置指定的值,否则依旧为 null 。
    • ③ 如果 databaseId 不为 null ,Mybatis 只会找到配置 databaseId 的 SQL 语句。
    • ④ Mybatis 会同时加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。如果同时找到带有 databaseId 和不带databaseId 的相同语句,则后者会被舍弃。
  • 示例:

  • mybatis-config.xml

<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties"></properties>

    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <!--
            通过package标签的name指定需要生成别名的包,默认会创建一个别名,就是类名的小写
        -->
        <package name="com.xuguoguo"/>
    </typeAliases>

    <!--
        environments,Mybatis可以配置多种环境
            environment:配置一个具体的环境信息;必须有transactionManager和dataSource标签。属性id代表当前环境的标识,可以达到快速切换环境
                transactionManager:事务管理器
                    type:事务管理器的类型,有JDBC和MANAGED两种类型,还可以自定义事务管理器
                dataSource:数据源
                    type:数据源的类型,有UNPOOLED、POOLED、JNDI和自定义类型。

    -->
    <environments default="development">
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--
        databaseIdProvider:支持多数据库厂商
            type="DB_VENDOR":VendorDatabaseIdProvider
                - 作用: 得到数据库厂商的标识(驱动,Connection接口中的getMetaData()返回了DatabaseMetaData,DatabaseMetaData中有getDatabaseProductName()方法),
                        Mybatis就能数据数据库厂商标识来指定不同的SQL
    -->
    <databaseIdProvider type="DB_VENDOR">
        <!--
            为不同的数据库厂商起别名
        -->
        <property name="MySQL" value="mysql"/>
        <property name="Oracle" value="oracle"/>
        <property name="SQL Server" value="sqlserver"/>
    </databaseIdProvider>

    <mappers>
        <mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
    </mappers>
</configuration>
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findById" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>

    <!--
        select标签中databaseId用来指定在那种数据库环境下执行
    -->
    <select id="findById" resultType="com.xuguoguo.domain.Employee" databaseId="mysql">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>
    <!--
        select标签中databaseId用来指定在那种数据库环境下执行
    -->
    <select id="findById" resultType="com.xuguoguo.domain.Employee" databaseId="oracle">
        SELECT id,last_name as lastName,email,gender
        FROM employees
        WHERE id = #{id,jdbcType=INTEGER}
    </select>
</mapper>

第九章:mapper(映射)

  • mapper 逐个注册 SQL 映射文件
<mappers>
<mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>
</mappers>
  • 使用批量注册:如果有 SQL 映射文件存在,文件名必须和 Mapper 接口名相同且必须在同一个目录下
<mappers>
    <package name="com.xuguoguo.mapper"/>
</mappers>
  • 示例:
<?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>
    <!--
        Mybatis可以使用properties标签来引入外部properties配置文件的内容
            resource属性:引入类路径下的配置文件
            url属性:引入网络或磁盘上的配置文件
    -->
    <properties resource="db.properties"></properties>

    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <!--
            通过package标签的name指定需要生成别名的包,默认会创建一个别名,就是类名的小写
        -->
        <package name="com.xuguoguo"/>
    </typeAliases>

    <!--
        environments,Mybatis可以配置多种环境
            environment:配置一个具体的环境信息;必须有transactionManager和dataSource标签。属性id代表当前环境的标识,可以达到快速切换环境
                transactionManager:事务管理器
                    type:事务管理器的类型,有JDBC和MANAGED两种类型,还可以自定义事务管理器
                dataSource:数据源
                    type:数据源的类型,有UNPOOLED、POOLED、JNDI和自定义类型。

    -->
    <environments default="development">
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--
        databaseIdProvider:支持多数据库厂商
            type="DB_VENDOR":VendorDatabaseIdProvider
                - 作用: 得到数据库厂商的标识(驱动,Connection接口中的getMetaData()返回了DatabaseMetaData,DatabaseMetaData中有getDatabaseProductName()方法),
                        Mybatis就能数据数据库厂商标识来指定不同的SQL
    -->
    <databaseIdProvider type="DB_VENDOR">
        <!--
            为不同的数据库厂商起别名
        -->
        <property name="MySQL" value="mysql"/>
        <property name="Oracle" value="oracle"/>
        <property name="SQL Server" value="sqlserver"/>
    </databaseIdProvider>

    <!--
        mappers将SQL映射注册到全局配置中
    -->
    <mappers>

        <!--
                mapper:注册一个SQL映射
                    - resource:引用类路径下的SQL映射文件
                    - url:引用网络路径下的SQL映射文件
                    - class:引用接口,
                        - 有SQL配置文件,接口和配置文件必须放在同一目录下,且接口名和配置文件的名称必须相同
                        - 没有SQL配置文件,所有的SQL都是利用注解写在接口上
        -->
        <!--  mapper resource="com/xuguoguo/mapper/EmployeeMapper.xml"/>-->
        <!--
                package:批量注册,如果有SQL配置文件,接口和配置文件必须放在同一目录下,且接口名和配置文件的名称必须相同
         -->
        <package name="com.xuguoguo.mapper"/>
    </mappers>

</configuration>

Mybatis 的映射文件

第一章:增删改查

●示例:
●导入相关 jar 包的 Maven 坐标:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.5</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13</version>
    <scope>test</scope>
</dependency>
  • db.properties
jdbc.url=jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=123456
  • log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
   <param name="Encoding" value="UTF-8" />
   <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
   </layout>
 </appender>
 <logger name="java.sql">
   <level value="debug" />
 </logger>
 <logger name="org.apache.ibatis">
   <level value="info" />
 </logger>
 <root>
   <level value="debug" />
   <appender-ref ref="STDOUT" />
 </root>
</log4j:configuration>
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    public Employee() {
    }

    public Employee(Integer id, String lastName, String email, String gender) {
        this.id = id;
        this.lastName = lastName;
        this.email = email;
        this.gender = gender;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

    /**
     * 根据id查询员工的信息
     *
     * @param id
     * @return
     */
    Employee findById(Integer id);

    /**
     * 增加员工信息
     *
     * @param employee
     */
    void addEmp(Employee employee);

    /**
     * 修改员工信息
     *
     * @param employee
     */
    void updateEmp(Employee employee);


    /**
     * 根据id删除员工信息
     *
     * @param id
     */
    void deleteEmpById(Integer id);

}
  • EmployeeMapper.xml

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
    <select id="findById" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>

    <insert id="addEmp">
        INSERT INTO employee (last_name,email,gender)
        VALUES (#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
    </insert>

    <update id="updateEmp">
        UPDATE employee
        SET last_name = #{lastName,jdbcType=VARCHAR},email = #{email,jdbcType=VARCHAR},gender=#{gender,jdbcType=VARCHAR}
        WHERE id = #{id,jdbcType=INTEGER}
    </update>
    <delete id="deleteEmpById">
        DELETE FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </delete>
</mapper>

- mybatis-copnfig.xml

```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <properties resource="db.properties"></properties>
    <settings>
        <!-- 开启自动驼峰命名规则映射 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 使用${}引入db.properties属性文件中的内容 -->
                <property name="driver" value="${jdbc.driverClass}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <mappers>
        <package name="com.xuguoguo.mapper"/>
    </mappers>

</configuration>
  • 测试:
package com.xuguoguo;

import com.xuguoguo.domain.Employee;
import com.xuguoguo.mapper.EmployeeMapper;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;


public class EmployeeTest {
    SqlSessionFactory sqlSessionFactory = null;
    SqlSession sqlSession = null;
    EmployeeMapper employeeMapper = null;

    @Before
    public void before() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession(true);
        employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
    }

    @After
    public void after() {
        if (null != sqlSession) {
            sqlSession.close();
        }
    }

    @Test
    public void testFindById() {

        Employee employee = employeeMapper.findById(1);
        System.out.println("employee = " + employee);
    }

    @Test
    public void testAddEmp() {
        Employee employee = new Employee();
        employee.setEmail("jerry@qq.com");
        employee.setGender("男");
        employee.setLastName("jerry");

        employeeMapper.addEmp(employee);
    }

    @Test
    public void testUpdateEmp(){

        Employee employee = employeeMapper.findById(2);
        employee.setGender("女");

        employeeMapper.updateEmp(employee);
    }

    @Test
    public void testDeleteEmpById(){
        employeeMapper.deleteEmpById(2);

    }

}

第二章:INSERT 获取自增主键的值

  • MySQL 等数据库支持自增主键,自增主键的值是通过 statement.getGenerateKeys() 方法获取的。

  • 通过使用
    useGeneratedKeys=“true” 开启自增主键获取主键值的策略。

  • 通过使用
    keyProperty=“id” 指定对应的主键属性,Mybatis 获取主键值以后,将这个值封装给 JavaBean 的哪个属性。

  • 示例:

<?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="com.xuguoguo.mapper.EmployeeMapper">
    <!--
        MySQL支持自增主键,自增主键值的获取,Mybatis是利用statement.getGeneratedKeys()
            useGeneratedKeys="true":使用自增主键获取主键值策略
            keyProperty="id":指定对应的主键属性,Mybatis获取主键值以后,将这个值封装给JavaBean的哪个属性
    -->
    <insert id="addEmp" useGeneratedKeys="true" keyProperty="id" parameterType="com.xuguoguo.domain.Employee">
        INSERT INTO employee (last_name,email,gender)
        VALUES (#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})
    </insert>
</mapper>

第三章:INSERT 获取非自增主键的值

  • Oracle 不支持自增主键,Oracle 是使用序列来模拟自增的。

  • 每次插入的数据的主键都是从序列中拿到的值。

  • 示例:

<?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="com.xuguoguo.mapper.EmployeeMapper">
    <!--
        Oracle不支持自增主键,Oracle是使用序列来模拟自增的。
        每次插入的数据的主键都是从序列中拿到的值。
    -->
    <insert id="addEmp" useGeneratedKeys="true" keyProperty="id" parameterType="com.xuguoguo.domain.Employee">
        <!--
            插入时的主键是从序列中拿到的
                keyProperty:查询的主键封装给JavaBean的哪个属性
                order:
                    - BEFORE:当前的SQL在插入SQL之前运行
                        - 运行顺序:先运行selectKey中的SQL语句,查询出id,然后将id封装给JavaBean中的id属性,在运行插入SQL的时候,就可以取出id属性对应的值
                    - AFTER: 先运行插入SQL,再运行当前的SQL 
                        - 运行顺序:先运行插入的SQL(会从序列中取出新值作为id),再运行selectKey查询id,然后将id封装给JavaBean的id属性,并发情况下可能有问题。
                resultType:查出的数据的返回值类型
        -->
        <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
            <!--
                编写查询主键的SQL语句
            -->
            SELECT employee_seq.nextval FROM dual
        </selectKey>

        INSERT INTO employee (id,last_name,email,gender)
        VALUES (#{id,jdbcType=INTEGER},#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})

    </insert>
</mapper>
  • 示例:
<?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="com.xuguoguo.mapper.EmployeeMapper">
    <!--
        Oracle不支持自增主键,Oracle是使用序列来模拟自增的。
        每次插入的数据的主键都是从序列中拿到的值。
    -->
    <insert id="addEmp" useGeneratedKeys="true" keyProperty="id" parameterType="com.xuguoguo.domain.Employee">
        <!--
            插入时的主键是从序列中拿到的
                keyProperty:查询的主键封装给JavaBean的哪个属性
                order:
                    - BEFORE:当前的SQL在插入SQL之前运行
                        - 运行顺序:先运行selectKey中的SQL语句,查询出id,然后将id封装给JavaBean中的id属性,在运行插入SQL的时候,就可以取出id属性对应的值
                    - AFTER: 先运行插入SQL,再运行当前的SQL
                        - 运行顺序:先运行插入的SQL(会从序列中取出新值作为id),再运行selectKey查询id,然后将id封装给JavaBean的id属性,并发情况下可能有问题。
                resultType:查出的数据的返回值类型
        -->
        <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
            <!--
                编写查询主键的SQL语句
            -->
            SELECT employee_seq.currval FROM dual
        </selectKey>

        INSERT INTO employee (id,last_name,email,gender)
        VALUES (employee_seq.nextval},#{lastName,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},#{gender,jdbcType=VARCHAR})

    </insert>
</mapper>

第四章:参数处理

4.1 单个参数

  • Mybatis 不需要经过任何处理,Mybatis 可以直接使用
    #{参数名} 取出参数值。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

    /**
     * 根据id查询员工的信息
     *
     * @param id
     * @return
     */
    Employee findById(Integer id);
    
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
    
    <select id="findById" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{abc,jdbcType=INTEGER}
    </select>
</mapper>

4.2 多个参数

  • 任意多个参数,都会被 Mybatis 重新包装成一个 Map 传入。Map 中的 key 就是 param1, param2 ,…,value 是传入的参数值。

  • #{}
    就是从 map 中获取指定的 key 的值。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;
import com.xuguoguo.domain.Employee;
public interface EmployeeMapper {
/**
* 根据id和lastName查询员工信息
*
* @param id
* @param lastName
* @return
*/
Employee findByIdAndLastName(Integer id, String lastName);
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findByIdAndLastName" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{param1,jdbcType=INTEGER} AND last_name = #{param2,jdbcType=VARCHAR}
    </select>

</mapper>

4.3 命名参数

  • 当多个参数的时候,可以使用

    • @Param 注解明确指定 Mybatis 中传入参数 Map 中的 key ,Map 中的 key 就是使用
    • @Param 注解指定的值,value 就是传入的参数值。
  • #{指定的key}
    就可以取出对应的参数值。

  • 示例:

  • Employee.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;
import org.apache.ibatis.annotations.Param;

public interface EmployeeMapper {

    /**
     * 根据id和lastName查询员工信息
     *
     * @param id
     * @param lastName
     * @return
     */
    Employee findByIdAndLastName(@Param("id") Integer id,@Param("lastName") String lastName);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findByIdAndLastName" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER} AND last_name = #{lastName,jdbcType=VARCHAR}
    </select>

</mapper>

4.4 POJO

  • 如果多个参数正好是业务逻辑的数据模型,我们就可以直接传入 POJO 。
    #{属性名} 取出传入 POJO 的属性值。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {
    
    Employee findByPOJO(Employee employee);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findByPOJO" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER} AND last_name = #{lastName,jdbcType=VARCHAR}
    </select>

</mapper>

4.5 Map

  • 如果多个参数不是业务模型的数据,没有对应的 POJO ,不经常使用,为了方便,我们可以传入 Map 。

  • #{key}
    取出传入 map 中对应的值。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

import java.util.Map;

public interface EmployeeMapper {

    Employee findByMap(Map<String, Object> map);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
    
    <select id="findByMap" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{id,jdbcType=INTEGER} AND last_name = #{lastName,jdbcType=VARCHAR}
    </select>

</mapper>

4.6 TO

  • 如果多个参数不是业务模型中的数据,但是经常使用,推荐编写一个 TO(Transfer Object)数据传输对象。

  • 示例:

  • Page.java

package com.xuguoguo.to;

/**
 * 分页的参数
 */
public class Page {

    /**
     * 每页显示条数
     */
    private Integer pageSize;

    /**
     * 起始页码
     */
    private Integer pageNum;

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    @Override
    public String toString() {
        return "Page{" +
                "pageSize=" + pageSize +
                ", pageNum=" + pageNum +
                '}';
    }
}
  • EmployeeMapper.java
package com.xuguoguo.mapper;
import com.xuguoguo.domain.Employee;
import com.xuguoguo.to.Page;
import java.util.List;
public interface EmployeeMapper {
    List<Employee> findByPage(Page page);
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">


    <select id="findByPage" resultType="com.xuguoguo.domain.Employee">

        SELECT id,last_name as lastName,email,gender
        FROM employee
        LIMIT #{pageNum},#{pageSize}

    </select>
</mapper>

4.7 Collection 类型(List类型、Set类型)数组类型

  • 如果传入的参数是 Collection 类型(List 类型、Set 类型)或数组类型,那么 Mybatis 会针对这些类型进行特殊处理:如果是 Collection 类型,那么 Mybatis 内部封装参数的 Map 的 key 就是 collection ;如果是 List 类型,那么 Mybatis 内部封装参数的 Map 的 key 可以是 list ;而如果是数组类型, Mybatis 内部封装参数的 Map 的 key 是 array 。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;
import com.xuguoguo.domain.Employee;
import java.util.List;
import java.util.Set;
public interface EmployeeMapper {
    List<Employee> findBySet(Set<Integer> id);
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
    
    <select id="findBySet" resultType="com.xuguoguo.domain.Employee">
        SELECT id,last_name as lastName,email,gender
        FROM employee
        WHERE id = #{collection}
    </select>
</mapper>

4.8 # 和 $ 取值区别

  • #{}
    获取参数的值,预编译到 SQL 中,安全。

  • ${}
    获取参数的值,拼接到 SQL 中,有 SQL 注入问题。

  • 注意:

  • 大多数情况下,我们取参数的值的时候使用
    #{} 。

  • 原生 JDBC 不支持占位符的地方,我们就可以使用
    ${} 。

  • 比如:排序

  • 比如:财务系统在设计之初按照年份分表,查询的时候应该这样写:
    Order BY ${name}

SELECT * FROM ${year}_salary WHERE xxx;
  • 示例:
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

import java.util.Map;

public interface EmployeeMapper {
   
   Employee findByMap(Map<String,Object> map);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findByMap" resultType="com.xuguoguo.domain.Employee" parameterType="java.util.Map">
        SELECT id,last_name as lastName,email,gender
        FROM ${tableName}
        WHERE id = #{id}
    </select>

</mapper>
  • 测试:
package com.xuguoguo;

import com.xuguoguo.domain.Employee;
import com.xuguoguo.mapper.EmployeeMapper;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;


public class EmployeeTest {
    SqlSessionFactory sqlSessionFactory = null;
    SqlSession sqlSession = null;
    EmployeeMapper employeeMapper = null;

    @Before
    public void before() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        sqlSession = sqlSessionFactory.openSession(true);
        employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
    }

    @After
    public void after() {
        if (null != sqlSession) {
            sqlSession.close();
        }
    }

    @Test
    public void testFindById() {
        Map<String, Object> map = new HashMap<>();
        map.put("id",1);
        map.put("tableName","employee");

        Employee employee = employeeMapper.findByMap(map);
        System.out.println("employee = " + employee);

    }   
}

4.9 #取值时指定参数的相关规则

  • Mybatis 在参数位置支持如下的属性:

  • javaType

  • jdbcType

  • mode(用于存储过程)

  • numericScale

  • resultMap

  • typeHandler

  • jdbcTypeName

  • expression

  • 在某种特定的条件下,jdbcType 通常需要被设置。

    • 在我们的数据为 null 的时候,有些数据库可能不能识别 Mybatis 对 null 的默认处理,比如 Oracle 。
    • Mybatis对 null 的默认处理时的 jdbcType 是 OTHER ,这种类型 MySQL 能正确识别,但是 Oracle 不能。
      • ① 我们在使用 Oracle 保存 null 的时候,需要设置 jdbcType 为 NULL 。
      • ② 在全局配置文件 mybatis-config.xml 中设置 jdbcTypeForNull 的值是 NULL(推荐这种,Oracle 和 MySQL 都支持)。
  • 示例:修改 Mybatis 对 Oracle 的 NULL 值的默认处理

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {
   
   int addEmp(Employee employee);
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
   
    <insert id="addEmp" useGeneratedKeys="true" keyProperty="id" parameterType="com.xuguoguo.domain.Employee">
        <selectKey>
            SELECT employee_seq.nextval FROM dual
        </selectKey>

        INSERT INTO employee (id,last_name,email,gender)
        <!--
            在Oracle数据库中,如果是null值,需要设置jdbcType=NULL
        -->
        VALUES (#{id,jdbcType=INTEGER},#{lastName,jdbcType=VARCHAR},#{email,jdbcType=NULL},#{gender,jdbcType=VARCHAR})
    </insert>
</mapper>

第五章:select 元素

5.1 概述

  • select 元素用于定义查询操作。
  • id:唯一标识符。用来引用这条语句,需要和接口的方法名一致。
  • parameterType:参数类型。可以不传,Mybatis 会根据 TypeHandler 自动推断。
  • resultType:返回值类型。别名或者全类名,如果返回的是集合,定义集合中元素的类型。不能和 resultMap 同时使用。
  • resultMap:实现高级结果集映射。不能和 resultType 一起使用。

5.2 resultType

5.2.1 返回 List
  • 对于 resultType 来说,如果返回的是一个集合,需要写集合中的类型。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

   List<Employee> findByGender(String gender);
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <!--
        resultType:如果返回的是一个集合,需要写集合里面的类型
    -->
    <select id="findByGender" resultType="com.xuguoguo.domain.Employee">
        SELECT * FROM employee
        WHERE gender = #{gender,jdbcType=VARCHAR}
    </select>

</mapper>
5.2.2 返回 Map
  • 返回一条记录封装 Map ,key 就是列名,值就是对应的值。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import java.util.Map;

public interface EmployeeMapper {

   Map<String, Object> findById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findById" resultType="java.util.Map">
        SELECT * FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>

</mapper>
  • 返回多条记录将其封装为 Map<主键类型,对象类型>,key 是这条记录的主键,值是这条记录。

  • 示例:

  • EmployeeMapper.java

package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;
import org.apache.ibatis.annotations.MapKey;

import java.util.Map;

public interface EmployeeMapper {

   @MapKey("id")
   Map<Integer, Employee> findById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <select id="findById" resultType="java.util.Map">
        SELECT id,last_name as lastName,gender,email FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>

</mapper>

5.3 resultMap

5.3.1 自定义结果映射规则
  • 示例:
  • EmplyeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

  Employee findById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <!--
        resultMap 自定义关系结果映射规则
            id:唯一方便引用的id
            type:自定义规则的JavaBean类型
    -->
    <resultMap id="emp" type="com.xuguoguo.domain.Employee">
        <!--
            id:指定主键列的封装规则
                column:指定哪一列
                property:指定column对应的JavaBean属性
         -->
        <id property="id" column="id"/>
        <!--
            result:定义普通列的封装规则
               column:指定哪一列
               property:指定column对应的JavaBean属性
        -->
        <result property="lastName" column="last_name"/>
        <!-- 其它不指定的列会自动封装 -->
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
    </resultMap>

    <select id="findById" resultMap="emp">
        SELECT * FROM employee
        WHERE id = #{id,jdbcType=INTEGER}
    </select>

</mapper>
5.3.2 关联查询
5.3.2.1 环境搭建
  • SQL 脚本:
DROP TABLE IF EXISTS `department`;
CREATE TABLE `department`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `department` VALUES (1, '开发部');
INSERT INTO `department` VALUES (2, '测试部');

DROP TABLE IF EXISTS `employee`;
CREATE TABLE `employee`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `department_id` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `fk_department_id`(`department_id`) USING BTREE,
  CONSTRAINT `fk_department_id` FOREIGN KEY (`department_id`) REFERENCES `department` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `employee` VALUES (1, 'tom', '男', 'tom@qq.com', 1);
INSERT INTO `employee` VALUES (2, 'aa', '女', NULL, 2);
5.3.2.2 级联属性封装查询结果
  • 示例:查询一个员工信息以及其所在部门信息
  • Department.java
package com.xuguoguo.domain;

public class Department {

    private Integer id;

    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    private Department department;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", department=" + department +
                '}';
    }
}
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

 Employee findEmpAndDeptById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">
    
    <resultMap id="emp" type="com.xuguoguo.domain.Employee">
        <id property="id" column="id"/>
        <result property="lastName" column="last_name"/>
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
        <result property="department.id" column="did"/>
        <result property="department.name" column="dept_name"/>
    </resultMap>

    <select id="findEmpAndDeptById" resultMap="emp">
        SELECT e.id as id,e.last_name as last_name,e.gender as gender,e.email as email,d.id as did,d.name as dept_name
        FROM employee e INNER JOIN department d
        ON e.department_id = d.id
        WHERE e.id = #{id,jdbcType=INTEGER}
    </select>

</mapper>
5.3.2.3 association 定义关联对象
  • 示例:查询一个员工信息以及其所在部门信息
  • Department.java
package com.xuguoguo.domain;

public class Department {

    private Integer id;

    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    private Department department;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", department=" + department +
                '}';
    }
}
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

 Employee findEmpAndDeptById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <resultMap id="emp" type="com.xuguoguo.domain.Employee">
        <id property="id" column="id"/>
        <result property="lastName" column="last_name"/>
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
        <!--
            association:可以指定联合的JavaBean对象
                property:指定哪个属性是联合的对象
                javaType:指定联合对象的类型
        -->
        <association property="department" javaType="com.xuguoguo.domain.Department">
            <id property="id" column="did"/>
            <id property="name" column="dept_name"/>
        </association>
    </resultMap>

    <select id="findEmpAndDeptById" resultMap="emp">
        SELECT e.id as id,e.last_name as last_name,e.gender as gender,e.email as email,d.id as did,d.name as dept_name
        FROM employee e INNER JOIN department d
        ON e.department_id = d.id
        WHERE e.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
5.3.2.4 association 分步查询
  • 示例:查询一个员工信息以及其所在部门信息
  • Department.java
package com.xuguoguo.domain;

public class Department {

    private Integer id;

    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    private Department department;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", department=" + department +
                '}';
    }
}
  • DepartmentMapper.java
<?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="com.xuguoguo.mapper.DepartmentMapper">

    <select id="findById" resultType="com.xuguoguo.domain.Department">
        SELECT *
        FROM department
        WHERE id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

    Employee findEmpAndDeptById(Integer id);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <resultMap id="emp" type="com.xuguoguo.domain.Employee">
        <!--
            分步查询:
                ①按照员工id查询员工信息
                ②根据查询员工信息中的department_id去部门表中查询部门信息
                ③部门设置到员工中
        -->
        <id property="id" column="id"/>
        <result property="lastName" column="last_name"/>
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
        <!--
            association 定义关联对象的封装规则
                property:关联对象的属性
                select:表明当前属性是调用select查询的结果
                column:指定将那一列的值传给这个方法

             流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的关联对象的属性
        -->
        <association property="department" select="com.xuguoguo.mapper.DepartmentMapper.findById" column="did" />
    </resultMap>

    <select id="findEmpAndDeptById" resultMap="emp">
        SELECT e.id as id,e.last_name as last_name,e.gender as gender,e.email as email,e.department_id as did
        FROM employee e
        WHERE e.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
分步查询中使用延迟加载:需要在 mybatis-config.xml 中配置如下的全局设置
<settings>
    <!-- 开启自动驼峰命名规则映射 -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!-- 开启对jdbcType的NULL的支持 -->
    <setting name="jdbcTypeForNull" value="NULL"/>
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 开启按需加载 -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
5.3.2.5 collection 定义关联集合封装规则
  • 示例:查询一个部门信息的同时并查询下面的所有员工信息
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • Department.java
package com.xuguoguo.domain;

import java.util.List;

public class Department {

    private Integer id;

    private String name;

    private List<Employee> employees;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", employees=" + employees +
                '}';
    }
}
  • DepartmentMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Department;

public interface DepartmentMapper {

    Department findById(Integer id);

}
  • DepartmentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.DepartmentMapper">

    <resultMap id="dept" type="com.xuguoguo.domain.Department">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
         <!--
            collection 定义关联集合类型的属性的封装规则
                ofType 定义集合中元素的类型
         -->
        <collection property="employees" ofType="com.xuguoguo.domain.Employee">
            <!-- 定义这个集合中元素的封装规则 -->
            <id property="id" column="eid"/>
            <result property="lastName" column="lastName"/>
            <result property="gender" column="gender"/>
            <result property="email" column="email"/>
        </collection>
    </resultMap>

    <select id="findById" resultMap="dept">
        SELECT d.id as id,d.name as name,e.id as eid,e.last_name as lastName,e.email as email,e.gender as gender
        FROM department d
        INNER JOIN employee e
        ON d.id = e.department_id
        WHERE d.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
5.3.2.6 collection 定义分步查询
  • 示例:查询一个部门信息的同时并查询下面的所有员工信息
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}
  • Department.java

```java
package com.xuguoguo.domain;

import java.util.List;

public class Department {

    private Integer id;

    private String name;

    private List<Employee> employees;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", employees=" + employees +
                '}';
    }
}

- EmployeeMapper.java

```java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

import java.util.List;

public interface EmployeeMapper {

    List<Employee> findByDepatmentId(Integer departmentId);

}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <resultMap id="emp" type="com.xuguoguo.domain.Employee">

        <id property="id" column="id"/>
        <result property="lastName" column="last_name"/>
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
    </resultMap>

    <select id="findByDepatmentId" resultMap="emp">
        SELECT e.id as id,e.last_name as last_name,e.gender as gender,e.email as email,e.department_id as did
        FROM employee e
        WHERE e.department_id = #{departmentId,jdbcType=INTEGER}
    </select>
</mapper>
  • DepartmentMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Department;

public interface DepartmentMapper {

    Department findById(Integer id);

}
  • DepartmentMapper.xml
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Department;

public interface DepartmentMapper {

    Department findById(Integer id);

}
  • DepartmentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.DepartmentMapper">

    <resultMap id="dept" type="com.xuguoguo.domain.Department">
        <id property="id" column="id"/>
        <result property="name" column="name"/>

        <collection property="employees" select="com.xuguoguo.mapper.EmployeeMapper.findByDepatmentId" column="{id}">
        </collection>
    </resultMap>

    <select id="findById" resultMap="dept">
        SELECT d.id as id,d.name as name
        FROM department d
        WHERE d.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
5.2.3.7 分步查询传递多列值
  • 有的时候,分步查询不是传递一个值,而是传递多列值,这个时候我们需要使用 {key1=column1,key2=clomn2…} 的形式来多列值封装 map 传递。

  • 示例:

  • DepartmentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.DepartmentMapper">

    <resultMap id="dept" type="com.xuguoguo.domain.Department">
        <id property="id" column="id"/>
        <result property="name" column="name"/>

        <collection property="employees" select="com.xuguoguo.mapper.EmployeeMapper.findByDepatmentId" column="{departmentId=id}">
        </collection>
    </resultMap>

    <select id="findById" resultMap="dept">
        SELECT d.id as id,d.name as name
        FROM department d
        WHERE d.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
5.2.3.8 fetchType
  • 在 collection 和 association 标签的 fetchType 属性有 eager 和 lazy 属性,其中 eager 属性表示立即加载,而 lazy 属性表示延迟加载。一旦指定了 fetchType 可以覆盖全局的延迟加载策略。
5.2.3.9 discriminator 鉴别器
  • Mybatis 可以使用 discriminator 判断某列的值,然后根据某列的值改变封装行为。

  • 示例:判断 Employee,如果查出的是女生,就把部门信息查询出来,否则不查询;如果查询出来的是男生,就把 last_name 这一列的值赋值给 email

  • Department.java

package com.xuguoguo.domain;

public class Department {

    private Integer id;

    private String name;
    
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Department{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
  • Employee.java
package com.xuguoguo.domain;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Employee {

    private Integer id;

    private String lastName;

    private String email;

    private String gender;

    private Department department;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", gender='" + gender + '\'' +
                ", department=" + department +
                '}';
    }
}
  • DepartmentMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Department;

public interface DepartmentMapper {

    Department findById(Integer id);

}
  • DepartmentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.DepartmentMapper">

    <resultMap id="dept" type="com.xuguoguo.domain.Department">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
    </resultMap>

    <select id="findById" resultMap="dept">
        SELECT d.id as id,d.name as name
        FROM department d
        WHERE d.id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
  • EmployeeMapper.java
package com.xuguoguo.mapper;

import com.xuguoguo.domain.Employee;

public interface EmployeeMapper {

    Employee findById(Integer id);
    
}
  • EmployeeMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xuguoguo.mapper.EmployeeMapper">

    <resultMap id="emp" type="com.xuguoguo.domain.Employee">

        <id property="id" column="id"/>
        <result property="lastName" column="last_name"/>
        <result property="email" column="email"/>
        <result property="gender" column="gender"/>
        <!--
            discriminator 鉴别器
             column:指定要判断的列名
             javaType:指定要判断的列对应的java类型
        -->
        <discriminator javaType="string" column="gender">
            <case value="" resultType="com.xuguoguo.domain.Employee">
                <association property="department" javaType="java.lang.Integer" select="com.xuguoguo.mapper.DepartmentMapper.findById" column="did"/>
            </case>
            <case value="" resultType="com.xuguoguo.domain.Employee">
                <id property="id" column="id"/>
                <result property="lastName" column="last_name"/>
                <result property="email" column="last_name"/>
                <result property="gender" column="gender"/>
            </case>
        </discriminator>

    </resultMap>


    <select id="findById" resultMap="emp">
        SELECT e.id as id,e.last_name as last_name,e.gender as gender,e.email as email,e.department_id as did
        FROM employee e
        WHERE e.department_id = #{departmentId,jdbcType=INTEGER}
    </select>
</mapper>

小结

提示:本章节中主体摘录了对Mybatis持久层框架技术的配置文件的编写摘录,!

多学一招,偷偷的努力,然后惊艳所有人!!!卷就完了……

本小节完毕,敬请期待后续更新(可留言需要学习哪方面的内容哈)!如果需要源码或者工具的朋友们可关注微信公众号"锅锅编程生活"或者扫描二维码关注回复关键字/后台留言获取即可!`

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1407003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s-基础知识(Service,NodePort,CusterIP,NameSpace,资源限制)

Node Node 是 Pod 真正运行的主机&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。 Annotations 原文链接 Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象&#xff0c;Annotations 则是用来记录一些附加信息&#xff0c;用来辅助应…

深入理解JS语法与变量

深入理解JS语法与变量 前言初识JavaScriptJavaScript的语言风格和特性 JavaScript的书写位置认识输出语句学会处理报错REPL 环境 变量定义变量改变变量变量的合法命名变量的默认值变量的常见错误等号表示赋值同时声明多个变量 变量声明提升注意事项 结语 前言 在现代Web开发中…

Vue构建项目断点调试过程问题总结

Vue构建项目断点调试过程问题总结 问题背景 前端开发过程中&#xff0c;碰到问题时需要debug&#xff0c;快速分析和解决问题。一般除了console.log的方式打印日志外&#xff0c;更方便直观的方式就是打断点debug。本文对vue项目debug过程可能碰到的问题进行总结&#xff0c;…

Kafka(二)原理详解

一 、kafka核心总控制器&#xff08;Controller&#xff09; 在Kafka集群中会有一个或者多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controller&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。 作用&#xff1a;leader副…

FireAlpaca:轻量级、免费的Mac/Win绘图软件,让你的创意如火燃烧!

FireAlpaca是一款轻量级、免费的绘图软件&#xff0c;适用于Mac和Win系统&#xff0c;让你的创作过程更加快捷、简便。无论是绘制漫画、插图、设计作品还是进行简单的图片编辑&#xff0c;FireAlpaca都能满足你的需求。 首先&#xff0c;FireAlpaca具有直观友好的用户界面&…

国辰智企资产管理系统:实现资产精细化管理的首选

在市场竞争日益激烈、金融环境不断变化的背景下&#xff0c;有效的资产管理已成为企业保持竞争优势和实现财务目标的关键。传统资产管理方法已显不足以适应现代经济环境的快速变化。为了迎接这一挑战&#xff0c;越来越多企业纷纷采用先进的资产管理系统&#xff0c;以提高效率…

【面试突击】微信亿级朋友圈的社交系统设计

微信亿级朋友圈的社交系统设计 先来说一下业务需求吧&#xff1a; 每个用户可以发朋友圈&#xff0c;可以点赞&#xff0c;评论可以设置权限&#xff0c;不看某些人朋友圈、不让某些人看你的朋友圈可以刷朋友圈中其他人的动态 对于这样的系统设计&#xff0c;主要从业务来考虑…

Springboot项目启动报错:Command line is too long问题解决

启动项目报错:Error running ‘xxxxxxxx’: Command line is too long. Shorten command line for ‘xxxxxxxx’ or also for Application default configuration 方法一 点击提示中的&#xff1a;default&#xff1a;然后在弹出窗口中选择&#xff1a;JAR xxxx xxx&#xff0…

搭建k8s集群实战(一)系统设置

1、架构及服务 Kubernetes作为容器集群系统&#xff0c;通过健康检查重启策略实现了Pod故障自我修复能力&#xff0c;通过调度算法实现将Pod分布式部署&#xff0c;并保持预期副本数&#xff0c;根据Node失效状态自动在其他Node拉起Pod&#xff0c;实现了应用层的高可用性。 …

手势识别MATLAB代码

手势识别是智能设备常用的需求, 下面我们用MATLAB来识别手部的形态: 主程序main.m clc;clear all;close all;%清除命令行和窗口 imimread(DSC05815.JPG); [skin,bwycbcr,w,h] hand_segmentation(im); im1bwycbcr; % se strel(ball,[1 1 1;1 1 1;1 1 1]); im1 imdilate(im…

HarmonyOS鸿蒙学习笔记(22)@Builder实战

Builder标签是一种更轻量的UI元素复用机制&#xff0c;下面通过一个简单的例子来具体说明&#xff1a; 比如如下布局效果&#xff1a;上面是一个轮播的Swiper,下面是一个Grid 布局代码如下&#xff1a; build() {Navigation() {Scroll() {Column({ space: CommonConstants.CO…

html+css浮动小练习

以下是代码&#xff1a; <!DOCTYPE html> <!-- 2024.1.23 --> <html lang"en"> <head><meta charset"UTF-8"><title>浮动布局练习</title><style>.leftfix{float: left;}.rightfix{float:right;}/* 问题…

Leetcode—24. 两两交换链表中的节点【中等】

2023每日刷题&#xff08;八十七&#xff09; Leetcode—24. 两两交换链表中的节点 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x),…

如何进行H.265视频播放器EasyPlayer.js的中性化设置?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…

HTML 入门手册(二)

目录 HTML 入门手册(一) 10-表单 11-input标签 11.1文本框 (text) 11.2密码框 (password) 11.3单选按钮 (radio) 11.4复选框 (checkbox) 11.5普通按钮 11.6提交按钮 (submit) 11.7重置按钮 (reset) 11.8隐藏域 (hidden) 11.9文件上传 (file) 11.10数字输入 (numbe…

Power Apps 向Power Automate传一个数组参数

Power Apps传Power Automate数组参数 背景Power Apps传参方法画布开发我们现在power apps中设置一个集合**ArrCollect**准备一个按钮 Power Automate接收总结画布流 背景 我们通常会从Power Apps界面传递参数给Flow中&#xff0c;但是很多时候仅仅是一个字符串类型的已经不适用…

超融合系统疑难故障定位与解决实践 3 例(含信创技术栈)

当 IT 系统出现故障&#xff0c;问题定位往往是运维人员最头疼的环节。尤其是超融合系统&#xff0c;由于整体涉及的技术栈比较复杂&#xff0c;且有越来越多的用户基于信创环境进行部署&#xff0c;非常考验厂商和技术人员的专业能力&#xff1a;厂商研发和售后工程师不仅应能…

web安全学习笔记【07】——非http\https抓包

#知识点&#xff1a; 1、Web常规-系统&中间件&数据库&源码等 2、Web其他-前后端&软件&Docker&分配站等 3、Web拓展-CDN&WAF&OSS&反向&负载均衡等 ----------------------------------- 1、APP架构-封装&原生态&H5&flutter…

2024年了你还在用百度翻译?手把手教会你使用AI翻译!一键翻译网页和PDF文件!

一些结论 沉浸式翻译是一款免费的AI驱动的双语网页翻译扩展工具。 主要功能包括&#xff1a;一键网页翻译&#xff0c;PDF翻译&#xff0c;输入框翻译&#xff0c;鼠标悬停翻译等多种翻译场景。 目前核心功能均免费使用。 沉浸式翻译是什么&#xff1f; 沉浸式翻译是一款免费的…

低噪声放大器LNA 之 噪声系数

​ 一、噪声系数的定义 在定义噪声系数之前&#xff0c;先看一个放大器输入输出端信噪比&#xff08;信号功率与噪声功率之比&#xff0c;写作SNR&#xff09; 对比图&#xff1a; ​​从上图可用看出&#xff0c;从输入端到输出端&#xff0c;信号和噪声功率都得到了放大&…