深入浅出MyBatis映射器

 更新时间:2024年04月16日 09:37:32   作者:Davieyang.D.Y  
映射器是MyBatis最复杂也最重要的组件,也是基于MyBatis应用程序开发中,本文主要介绍了深入浅出MyBatis映射器,具有一定的参考价值,感兴趣的可以了解一下

映射器是MyBatis最复杂也最重要的组件,也是基于MyBatis应用程序开发中,占工作量比较大的工作,甚至能达到8成;映射器由Mapper接口和XML或者注解组成,在映射器中可以配置参数,各类SQL语句,存储过程、缓存、级联等复杂处理,并通过简易的映射规则将数据映射到指定的POJO或其对象上,这也是MyBatis核心运转逻辑

在XML和注解之间的选择其实很明显,其一面对复杂SQL,尤其比较长的SQL,注解会显得很无力;其二注解的可读性较差,尤其是对于那些需要复杂配置的SQL;其三注解没有XML上下文相互引用的优势

MyBatis映射器可配置元素

MyBatis映射器配置文件中可以包含以下主要元素,这些元素用于定义与数据库交互的各种操作和相关配置:

  • <select>:代表SQL的SELECT语句,用于从数据库中查询数据,可以设置属性如id(唯一标识该查询)、parameterType(传入参数的全限定类名或别名)、resultTyperesultMap(指定查询结果的映射类型或引用的结果映射)。可以通过fetchSizetimeout等属性控制查询行为,以及使用flushCacheuseCache等属性管理缓存。
  • <insert>:用于执行INSERT语句向数据库中插入数据。配置属性包括idparameterType(插入数据对象的类型)。可以设置useGeneratedKeyskeyProperty(或keyColumn)来启用自动增长主键并将其值映射到指定的Java属性上。statementType属性可以指定语句类型,如STATEMENTPREPAREDCALLABLE
  • <update>:定义UPDATE语句,用于更新数据库中的记录。同样具有idparameterType属性,指定更新操作的唯一标识和传入参数类型。可以设置flushCache属性决定是否刷新二级缓存。
  • <delete>:定义DELETE语句,删除数据库中的数据。包含idparameterType属性,分别表示操作标识和删除条件所对应的参数类型。通常也支持flushCache属性以控制缓存刷新。
  • <sql>:定义可重用的SQL片段,其中的SQL语句可以被其他元素(如<select><insert>等)通过include属性引用。有助于减少重复编写相同的SQL子句,提高代码复用性。
  • <resultMap>:定义结果集映射规则,将查询结果与Java对象的属性进行关联。包括id(唯一标识该结果映射)、type(结果对象的全限定类名或别名)。可以通过<id><result><association><collection>等子元素详细描述如何将查询结果的列映射到对象的属性、嵌套对象或集合属性上。
  • <parameterMap>:注意: 在较新版本的MyBatis中,已不再推荐使用<parameterMap>,而是直接使用parameterType属性。老版本中用于定义输入参数的映射规则,与<resultMap>类似,但主要用于处理复杂的参数结构。新版本中通常直接使用parameterType属性指定参数类型。
  • <cache>:定义二级缓存配置,可以设置缓存的类型、大小、超时策略、清除策略等属性。适用于那些查询结果相对稳定且希望在多次请求之间共享结果的场景。
  • <cache-ref>:引用其他命名空间中定义的缓存配置,避免重复定义。通过namespace属性指定要引用的缓存配置所在的命名空间。这些元素构成了MyBatis映射器的基本构建块,通过它们可以灵活地配置各种数据库操作,并精确地控制SQL语句的执行、参数传递、结果映射以及缓存策略等细节。在实际使用中,可以根据业务需求选择合适的元素组合来实现高效的数据库访问

Select元素

<select>元素在 MyBatis 映射器配置文件中用于定义 SQL SELECT 查询语句及其相关属性。以下是<select> 元素常见的属性及其详细解释:

  • id:必填属性,它和Mapper的命名空间组合起来是唯一的,形成唯一标识符,供MyBatis调用,比如:id="getUserById"
  • parameterType:可选属性,用于指定传入查询语句的参数类型,可以是全限定类名或也可以是类型别名,但必须是MyBatis的内置别名或者自定义别名,当查询需要接受参数时,使用此属性声明参数类型,参数可以是简单类型(如 int、String),复杂类型(如自定义 Java Bean),或者 Map 类型。若使用类型别名,需在全局配置文件或当前映射文件中提前定义。
  • resultType:可选属性,用于指定查询结果的预期类型。
    格式:全限定类名或类型别名,在允许自动匹配的情况下,结果集将通过Java Bean的规范映射,或者定义为int、double、float、map等参数;当查询结果是一条记录映射到单个对象时,使用此属性指定对象类型。MyBatis 会自动将查询结果的每一行数据映射到指定类型的对象实例。若使用类型别名,需在全局配置文件或当前映射文件中提前定义(不能和resultMap同时使用)
  • resultMap:可选属性,其作用是引用已定义的 <resultMap>,用于定制更复杂的查询结果映射规则,应与 <resultMap> 元素的id 属性值匹配;当查询结果需要进行精细的列到属性映射,或者涉及嵌套结果集、联合查询、自动关联等复杂情况时,使用此属性替代 resultType,指定的 必须在同一映射文件中预先定义。
  • flushCache:可选属性,其作用是控制是否在调用SQL后要求MyBatis清空之前查询的本地缓存和二级缓存,默认值:false(默认情况下,查询不会刷新缓存)
  • useCache:可选属性,指示是否对查询结果启用二级缓存。默认值:true(默认情况下,查询结果会被缓存)
  • timeout:可选属性,设置查询语句的超时时间(单位:秒),默认值由JDBC驱动或全局配置中的 defaultStatementTimeout 决定。
  • fetchSize:可选属性,为 JDBC Statement 设置预取结果集的大小,默认值由JDBC 驱动决定。
  • statementType:较少使用,用来指定执行 SQL 语句的方式,默认值:PREPARED(预编译语句)有3个选项:STATEMENT:静态 SQL(非预编译)、PREPARED:预编译语句(推荐)、CALLABLE:存储过程调用
  • resultOrdered:较少使用,其作用是指示 MyBatis 是否应该保持结果集的顺序与 SQL 中 ORDER BY 子句指定的顺序一致。默认值:false(默认情况下,MyBatis 不保证结果集顺序与 ORDER BY 完全一致)
  • resultSetType:较少使用其作用是指定 ResultSet 的类型(仅在使用 STATEMENT 语句类型时有意义)默认值:FORWARD_ONLY(默认情况下,使用只进游标),选项包括:FORWARD_ONLY:只进游标(不可回滚)、SCROLL_SENSITIVE:敏感滚动游标(可回滚,但可能无法看到其他事务的最新更改)、SCROLL_INSENSITIVE:不敏感滚动游标(可回滚,且不受其他事务更改影响)
  • resultSets::极少使用,其作用是当查询语句返回多个结果集或光标时,使用此属性指定结果集的名称或索引。

总结起来,<select>元素的主要属性用于定义查询语句的身份标识、输入参数类型、输出结果映射方式、缓存策略、查询超时、预取大小等执行特性。这些属性帮助开发者精细控制查询行为,确保与数据库交互的高效性和灵活性。在实际应用中,最常用的属性通常是idparameterTyperesultType或 resultMapflushCache和 useCache其他属性在特定场景下可能会发挥作用,但并不常用。

Select元素实例 单个参数

    <select id="countUserByFirstName" parameterType="string" resultType="int">
        select count(*) total from t_user where user_name like concat ('%',#{firstName, jdbcType=VARCHAR, javaType=String},'%')
    </select>

SQL很容易懂,里边的元素可以参考对应上边每一项的解释理解,有了SQL,就需要对应的Mapper接口和方法(也就是Dao Data Access Object)public Integer countUserByFirstName(String firstName)

在MyBatis的配置文件的settings元素中,有autoMappingBehavior和mapUnderscoreToCamelCase两个可配置的选项,他们是控制自动映射和驼峰映射的开关,一般来说自动映射会用的多一些,这样可以使用SQL的别名机制,更加灵活,而驼峰映射要求比较严格;autoMappingBehavior配置项有3个选择,NONE表示不自动映射,PARTIAL是默认值,表示只对没有嵌套的结果集自动映射,FULL表示对所有的结果集自动映射包括嵌套结果集,通常默认即可

假设我们有如下这么一个POJO

package com.ssm.pojo;
import org.apache.ibatis.type.Alias;
@Alias("role")
public class Role{
	private int id;
	private String roleName;
	private String note;
	/**  setters and getters */
}

在这个POJO里有三个属性id、roleName、note,如果在Mapper里编写SQL列名和属性名保持一致,它就会形成自动映射,例如

    <select id="getRole" parameterType="int" resultType="role">
        select id, role_name as roleName, note from t_role where id = #{id}
    </select>

列名role_name被别名roleName代替了,和POJO上的属性名保持一致,如此MyBatis就能将查询结果集和POJO的属性一一对应,自动完成映射无需再进行任何配置

如果严格按照驼峰命名法,比如数据库字段为role_name,POJO属性名为roleName,数据库字段名为user_name,POJO属性名为userName,那么只要在配置项把mapUnderscoreToCamelCase设置为true即可,如果这样,那么SQL就可以写成

select id, role_name, note from t_role where id = #{id}

MyBatis会严格按照驼峰命名的方式自动映射,只是这样要求数据字段和POJO的属性名严格对应

自动映射和驼峰映射都建立在SQL列名和POJO属性名的映射关系上,在实际使用中会更复杂,比如可能有些字段有主表和从表关联的级联关系,又比如typeHandler的转换规则复杂,此时resultType元素无法满足这些需求需要更强大的映射规则需要考虑使用resultMap等等

Select元素实例 使用Map传递多个参数

假设有这样一个Mapper接口定义,它通过键值对传递多个参数

public List<Role> findRolesByMap(Map<String, Object>parameterMap);

此时传递给映射器的一个Map对象,使用它在SQL中设置对应的参数,如下所示

    <select id="findRoleByMap" parameterType="map" resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

这里使用两个数据库字段进行了一个模糊查询,传参方式是使用map,执行代码如下所示

RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
Map<String, Object>parameterMap = new HashMap<>();
parameterMap.put("roleName", "1");
parameterMap.put("note","1");
List<Role> roleList = roleDao.findRolesByMap(parameterMap);

严格来说Map几乎适用于所有场景,但其可读性比较差,且不能限定其传递的数据类型

Select元素实例 使用注解传递多个参数

MyBatis提供了@Param(org.apache.ibatis.annotations.Param),可以通过它定义映射器的参数名称,如下代码所示

public List<Role> findRolesByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

Mapper文件如下所示

    <select id="findRolesByAnnotation" "resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

Select元素实例 使用JavaBean传递多个参数

先定义一个POJO

package com.ssm.pojo.parameter;

public class RoleParams{
	private String roleName;
	private String note;
	/** setter and getter */
}

把Mapper接口定义为

public List<Role> findRolesByBean(RoleParams roleParam);

Mapper文件如下所示

    <select id="findRolesByBean" "resultType="role" parameterType="com.ssm.pojo.parameter.RoleParams">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note},'%')
    </select>

执行代码如下

sqlSession = SqlSessionFactoryUtils.openSqlSession();
RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
RoleParams roleParams = new RoleParams();
roleParams.setNote("1");
roleParams.setRoleName("1");
List<Role>roleList = roleDao.findRolesByBean(roleParams);

在某些场景下也会混合使用,例如通过角色名称和备注查询角色,同时需要支持分页

分页的POJO如下定义

package com.ssm.pojo.parameter;
public class PageParams{
	private int start;
	private int limit;
	/** setters and getters */
}

Mapper接口如下

public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParams PageParam);

Mapper文件如下写法

    <select id="findByMix" "resultType="role">
        select id, role_name as roleName, note from t_role 
        where role_name like concat('%', #{params.roleName}, '%') and note like concat('%', #{params.note},'%')
        limit #{page.start}, #{page.limit}
    </select>

MyBatis对params和page这类JavaBean参数提供EL(中间语言)支持,为编程带来了很多便利

结果集映射resultMap

自动映射和驼峰映射规则比较简单,无法定义更多的属性和满足复杂的场景,例如枚举需要typeHandler,还有数据级联等等,因此select元素提供了resultMap属性,用于指定具体的resultMap作为映射规则,如下定义所示

<result Map id="roleMap" type="role">
	<id property="id" column="id"/>
	<result property="roleName" column="role_name"/>
	<result property="note" column="ntoe"/>
</resultMap>
<select id="getRoleUserResultMap" parameterType="int" resultMap="roleMap">
	select id, role_name, note from t_role where id = #{id}
</select>
    <!-- 定义结果映射,用于将数据库中的数据映射成Role对象 -->
    <resultMap id="userMap" type="com.ssm.pojo.User">
        <id property="userid" column="userid"/> <!-- 主键映射 -->
        <result property="username" column="username"/> <!-- 角色名映射 -->
        <result property="password" column="password"/> <!-- 备注映射 -->
        <result property="sex" column="sex"/>
        <result property="phone" column="phone"/>
        <result property="email" column="email"/>
        <result property="phonenumber" column="phonenumber"/>
        <result property="comment" column="comment"/>
    </resultMap>
    <!-- 定义结果映射,用于将数据库中的数据映射成Role对象 -->
    <resultMap id="roleMap" type="com.ssm.pojo.Role">
        <id property="id" column="id"/> <!-- 主键映射 -->
        <result property="roleName" column="roleName"/> <!-- 角色名映射 -->
        <result property="note" column="note" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/> <!-- 备注映射 -->
    </resultMap>

分页参数RowBounds

MyBatis不仅支持分页,还内置了一个专门处理分页的类RowBounds,如下代码所示

/**
 * RowBounds类用于设置SQL查询的偏移量和限制结果集的大小。
 */
package org.apache.ibatis.session;

public class RowBounds {
    // 无偏移量,无限制的行数
    public static final int NO_ROW_OFFSET = 0;
    // 最大整数2147483647
    public static final int NO_ROW_LIMIT = Integer.MAX_VALUE;
    // 默认的RowBounds实例,无偏移,无限制
    public static final RowBounds DEFAULT = new RowBounds();
    private final int offset; // 偏移量,从第几行开始
    private final int limit; // 限制返回的行数

    /**
     * 构造函数,默认偏移量为0,限制的行数为最大整数值。
     */
    public RowBounds() {
        this.offset = 0;
        this.limit = Integer.MAX_VALUE;
    }

    /**
     * 构造函数,设置自定义的偏移量和限制的行数。
     * 
     * @param offset 查询结果的偏移量,即从第几行开始。
     * @param limit 返回结果集的最大行数。
     */
    public RowBounds(int offset, int limit) {
        this.offset = offset;
        this.limit = limit;
    }

    /**
     * 获取偏移量。
     * 
     * @return 偏移量,从第几行开始。
     */
    public int getOffset() {
        return this.offset;
    }

    /**
     * 获取限制的行数。
     * 
     * @return 返回结果集的最大行数。
     */
    public int getLimit() {
        return this.limit;
    }
}

Mapper接口定义如下

public List<Role> findByRowBounds(@Param("roleName") String rolename, @Param("note") String note, RowBounds rowBounds);

Mapper映射文件如下

<select id="findByRowBounds" resultType="role">
	select id, role_name as roleName, note from t_role 
	where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note}, '%')
</select>

映射代码中没有任何关于RowBounds参数的信息,MyBatis自身会自动识别和启用它

执行代码如下

Logger log = Logger.getLogger(Main.class);
SqlSession sqlsession = null;
try{
	sqlsession = SqlSessionFacotryUtils.openSqlSession();
	RoleDao roleDao = sqlSession.getMapper(RoleDao.class);
	List<Role> roleList = roleDao.findByRowBounds("role", "note", new RownBounds(0,20));
	log.info(roleList.size());
}finally{
	if(sqlSession!=null){
		sqlSession.close();
	}
}	

RowBounds分页一般来说只适合做少量数据的分页,其原理是在执行SQL的查询后,根据偏移量和限制条数返回结果,因此大量的数据查询性能会比较差

insert元素

在MyBatis框架中,<insert>标签用于定义SQL插入语句。以下是其常用的属性及其说明:

  • id:作为命名空间内的唯一标识符,与Mapper接口中的方法名相对应,用于MyBatis在执行时找到对应的SQL语句。<insert id="insertUser" ...>,在同一个Mapper的XML文件中,id属性值必须唯一,否则MyBatis在解析时会抛出异常。
  • parameterType:指定传入SQL语句的参数类型,通常是一个Java类的全限定名(如包名加类名)或别名。支持基本数据类型、JavaBean对象、Map等复杂数据类型。<insert parameterType="com.example.User" ...>,MyBatis可以根据参数对象的属性名自动映射到SQL语句中的占位符(如${}或#{}),无需手动指定每一个参数。
  • useGeneratedKeys:表示是否启用JDBC的getGeneratedKeys方法来获取数据库自动生成的主键。默认值为false。<insert useGeneratedKeys="true" ...>,当数据库表有自增主键或其他自动生成的主键时,设置为true可以让MyBatis自动获取并返回生成的主键值。这需要数据库驱动和数据库本身支持该功能。
  • keyProperty:当useGeneratedKeys="true"时,此属性指定插入后生成的主键值应该赋给传入参数对象(parameterType指定的对象)的哪个属性。如果主键是复合主键,可以使用逗号分隔多个属性名。<insert keyProperty="id" ...> 或 <insert keyProperty="primaryKey1, primaryKey2" ...>,只有当useGeneratedKeys="true"且数据库支持时,keyProperty才生效。否则,即使指定了该属性,也不会有任何效果。
  • statementType:指定语句的执行类型。可选值包括STATEMENT、PREPARED(默认)和CALLABLE。分别对应使用JDBC的Statement、PreparedStatement和CallableStatement。<insert statementType="PREPARED" ...>,通常情况下,保持默认的PREPARED即可,因为它能防止SQL注入攻击,并允许预编译SQL语句提高性能。除非有特定需求,否则不需要更改此属性。
  • flushCache:控制是否在执行插入操作后刷新MyBatis的一级缓存(本地Session缓存)。默认值为true,即每次插入后清空缓存。<insert flushCache="false" ...>,若希望在插入后保留缓存以优化后续查询,可以设置为false。但请注意,这可能会影响数据的一致性,特别是多事务并发环境下,需要谨慎使用。
  • timeout:设置执行语句的超时时间(单位:秒)。超过这个时间仍未得到数据库响应时,MyBatis将抛出异常。<insert timeout="30" ...>注意: 根据数据库操作的实际耗时和系统对响应时间的要求来合理设置。过短可能导致正常操作因超时而失败,过长则可能导致应用响应缓慢。
  • keyColumn:仅对于insert和update有用,通过生成的键值设置表中的列名,这些设置仅在某些数据库如PG中是必须的,当主键列不是表中的第一列时需要设置,如果是复合主键,则需要再把没一个名称用逗号隔开
  • 其他:parameterMap、databaseId

insert元素实例自增主键场景

    <!-- 插入一个新的Role记录 -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" >
        INSERT INTO t_role(roleName, note) VALUES (#{roleName}, #{note})
    </insert>

这个语句非常简单,因为表的id只自增主键,因此在插入数据的时候并没有为该字段做任何事,数据库会自动完成,但实际开发过程中往往插入一条记录,需要根据当前表的主键值处理关联表,MyBatis中可以通过getGeneratedKeys方法获得数据库生成的主键,默认它是false状态,也就是不会返回主键值,当打开了这个开关后,还需要配置其属性keyPropertykeyColumn,从而告诉系统把生成的主键放入POJO的对应属性中,如果存在多个主键,就要用逗号将他们分隔

    <!-- 
    插入一个新的Role记录
    
    参数:
    - parameterType: 指定插入操作时使用的参数类型,这里是 com.ssm.pojo.Role,表示插入的角色对象。
    - databaseId: 指定该SQL语句适用于哪个数据库,这里是 mysql。
    - useGeneratedKeys: 指定是否使用数据库自动生成的键值。如果为 true,则表示使用自动生成的键值。
    - keyProperty: 指定生成的键值应该被设置到对象的哪个属性上,这里是 id。
    
    返回值: 无返回值,仅执行插入操作。
     -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" useGeneratedKeys="true" keyProperty="id" >
        INSERT INTO t_role(roleName, note) VALUES (#{roleName}, #{note})
    </insert>

如此,将useGeneratedKeys配置为true表示采用JDBC的Statement对象的getGeneratedKeys方法返回主键,而keyProperty代表用哪个POJO的属性匹配这个主键,这个例子里是id,说明它会用数据生成的主键赋值给这个POJO的属性id

insert元素实例自定义主键场景

有时候主键未必是自增的,而是依赖于某些规则,例如取消角色表的id自增规则,将其规则改为当角色表记录为空时id设置为1,当角色表记录不为空时,id设置为当前id加3,对于这样的特殊规则主键的场景,MyBatis也提供了支持,它主要依赖selectKey元素,允许自定义键值生成规则

    <!-- 
     插入一个新的Role记录
     参数:
     - parameterType: 指定插入操作时使用的参数类型,这里是com.ssm.pojo.Role,代表插入的角色对象。
     - databaseId: 指定此SQL适用于哪个数据库,这里是mysql。
     - useGeneratedKeys: 指定是否使用数据库生成的主键值。如果为true,MyBatis会自动获取生成的主键值并设置到对象中。
     - keyProperty: 指定哪个属性会接收生成的主键值,这里是id。
     返回值: 插入操作成功后,返回值为插入的记录的主键ID。
    -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role" databaseId="mysql" useGeneratedKeys="true" keyProperty="id" >
        <!-- 
         使用selectKey标签来动态生成主键ID。在插入新记录之前执行,通过查询当前角色表中最大ID值,若不存在则默认为1,若存在则在最大ID上加3,以保证ID的唯一性。
        -->
        <selectKey keyProperty="id" resultType="int" order="BEFORE">
            select if (max(id) = null, 1, max(id) + 3) from t_role
        </selectKey>
        <!-- 插入新的Role记录,#{id}, #{roleName}, #{note}分别代表角色的ID,角色名和备注信息。这些值会从传入的Role对象中获取。 -->
        INSERT INTO t_role(id, roleName, note) VALUES (#{id}, #{roleName}, #{note})
    </insert>

其他的很容易看明白,唯独这个order,设置为BEFORE,说明它将于当前定义的SQL前执行,也就是它会在插入数据前生成主键的SQL,如果还有一些需要在SQL执行后的动作,例如插入语句内部可能有嵌入索引调用,这样可以把它设置为AFTER,就会在执行插入后再完成任务

update元素和delete元素

   <!-- 更新Role的信息 -->
    <!-- 
    函数级别注释:该标签用于更新Role表中的信息。
    参数:
    - roleName: 角色名,类型为String,用于更新角色的名称。
    - note: 备注信息,类型为String,用于更新角色的备注。
    - id: 角色ID,类型为Integer,用于指定要更新的角色。
    返回值:无返回值。
     -->
    <update id="updateRole" parameterType="com.ssm.pojo.Role">
        UPDATE t_role SET roleName = #{roleName}, note = #{note} WHERE id = #{id}
    </update>

    <!-- 
    函数级别块注释:
    根据提供的ID删除数据库中特定的Role记录。
    
    参数:
    id - 需要删除的Role记录的ID,类型为int。
    
    返回值:
    无返回值。
     -->
    <delete id="deleteRole" parameterType="int">
        DELETE FROM t_role WHERE id = #{id}
    </delete>

sql元素

在实际开发过程中,往往很多表的列都非常多,在编写代码的时候,重复写列名是个很枯燥的事情,即便编译器提供了很多方法,但还是很麻烦,MyBatis提供了sql元素,简化了该场景下的编码工作

    <!-- 定义查询角色信息时需要返回的列名 -->
    <sql id = "roleCols">
        id, roleName, note
    </sql>


    <!-- 根据ID查询Role信息,返回Role对象。该查询针对Oracle数据库。 -->
    <select id="getRoleById" parameterType="int" resultMap="roleMap" databaseId="oracle">
        SELECT <include refid="roleCols"/>FROM t_role WHERE id = #{id}
    </select>

    <!-- 插入新的Role信息。在插入前,通过selectKey为新Role生成一个唯一的ID。 -->
    <insert id="insertRole" parameterType="com.ssm.pojo.Role">
        <selectKey keyProperty="id" resultType="int" order="BEFORE" statementType="PREPARED">
            select if (max(id) = null, 1, max(id)+3) from t_role
        </selectKey>
        insert into t_role(<include refid="roleCols"/>) values(#{id}, #{roleName}, #{note})
    </insert>

sql元素还支持变量传递

    <!-- 定义一个SQL片段,用于查询角色表中的id、roleName和note列 -->
    <!-- 通过传入的别名(alias)动态拼接SQL语句中的表名前缀 -->
    <sql id ="roleCols2">
        ${alias}.id, ${alias}.roleName, ${alias}.note}
    </sql>


    <!-- 根据ID查询Role信息,返回Role对象。该查询针对Oracle数据库。 -->
    <select id="getRoleById" parameterType="int" resultMap="roleMap" databaseId="oracle">
        SELECT <include refid="roleCols">
        <property name="alias" value="r"/>
    </include>
        FROM t_role r WHERE id = #{id}
    </select>

include元素中定义了一个“alias”的变量,其值是SQL中表t_role的别名“r”,sql元素可以通过EL引用这个变量

到此这篇关于深入浅出MyBatis映射器的文章就介绍到这了,更多相关MyBatis映射器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • Java安全后端返回文件流方式

    Java安全后端返回文件流方式

    这篇文章主要介绍了Java安全后端返回文件流方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • 解读ResultSet的遍历方法

    解读ResultSet的遍历方法

    这篇文章主要介绍了ResultSet的遍历方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • 解析spring加载bean流程的方法

    解析spring加载bean流程的方法

    这篇文章主要介绍了解析spring加载bean流程的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • Mybatis批量修改的操作代码

    Mybatis批量修改的操作代码

    这篇文章主要介绍了Mybatis批量修改的操作代码,包括整体批量修改的详细代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2017-09-09
  • Java基于正则实现的日期校验功能示例

    Java基于正则实现的日期校验功能示例

    这篇文章主要介绍了Java基于正则实现的日期校验功能,涉及java文件读取、日期转换及字符串正则匹配相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • 基于Springboot的高校社团管理系统的设计与实现

    基于Springboot的高校社团管理系统的设计与实现

    本文将基于Springboot+Mybatis开发实现一个高校社团管理系统,系统包含三个角色:管理员、团长、会员。文中采用的技术有Springboot、Mybatis、Jquery、AjAX、JSP等,感兴趣的可以了解一下
    2022-07-07
  • ClassLoader类加载源码解析

    ClassLoader类加载源码解析

    这篇文章主要为大家详细解析了ClassLoader类加载源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • Mybatis plus中使用in查询出错如何解决

    Mybatis plus中使用in查询出错如何解决

    这篇文章主要介绍了Mybatis plus中使用in查询出错的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • SpringBoot集成pf4j实现插件开发功能的代码示例

    SpringBoot集成pf4j实现插件开发功能的代码示例

    pf4j是一个插件框架,用于实现插件的动态加载,支持的插件格式(zip、jar),本文给大家介绍了SpringBoot集成pf4j实现插件开发功能的示例,文中通过代码示例给大家讲解的非常详细,需要的朋友可以参考下
    2024-07-07
  • 深入解析Java中volatile的底层原理

    深入解析Java中volatile的底层原理

    这篇文章主要介绍了深入解析Java中volatile的底层原理,volatile关键字用于保证变量的可见性和禁止指令重排序,即当一个线程修改了volatile变量的值,其他线程能够立即看到这个变量的最新值,而不是使用缓存中的旧值,需要的朋友可以参考下
    2023-07-07

最新评论