【Mybatis】日常知识点随笔(持续更新)

目录

【K】Mybatis使用@Select注解书写简单sql

[【K】MySQL 数据类型与 Java 类型的对应关系](#【K】MySQL 数据类型与 Java 类型的对应关系)

【K】Mybatis相同代码复用

[1. 定义公共 SQL 片段](#1. 定义公共 SQL 片段)

[2. 引用公共 SQL 片段](#2. 引用公共 SQL 片段)

[3. 使用参数](#3. 使用参数)

[4. 复用和组合](#4. 复用和组合)

[5. 注意事项](#5. 注意事项)

【K】mysql如何实现插入一条数据后立刻获取该数据自增长id进行调用

背景解析

代码使用

【K】Mybatis新增数据,存在就更新,不存在就添加

常规方法

Replace关键字

【K】MyBatis执行多个sql语句

背景

代码举例

实例举例

分析总结

[【K】Mybatis 不同条件拼接不同sql](#【K】Mybatis 不同条件拼接不同sql)

举例1

[举例2: 判断某一个值](#举例2: 判断某一个值)

举例3

【K】-IFNULL处理N/A

背景知识

SQL语句分析

改进后的SQL语句

知识扩展

注意事项

【K】Mybatis条件查询<where>标签

【K】使用resultMap封装对象一对多

数据库模型

实体类

[MyBatis 配置](#MyBatis 配置)

举例

【K】Mybatis使用常见类型的类型别名


【K】Mybatis使用@Select注解书写简单sql

java 复制代码
//1. 基本查询
@Select("SELECT * FROM users WHERE id = #{id}")
User selectUserById(int id);

//2. 动态查询
@Select("<script>" +
        "SELECT * FROM users" +
        "<if test='id != null'>" +
        " WHERE id = #{id}" +
        "</if>" +
        "</script>")
List<User> selectUsersById(@Param("id") Integer id);

//3. 返回 Map
@Select("SELECT * FROM users")
@MapKey("id")
Map<Integer, User> selectUsersAsMap();

//4. 使用注解参数
@Select("SELECT * FROM ${tableName}")
List<User> selectUsersFromTable(@Param("tableName") String tableName);

//5. 结果映射
@Select("SELECT id, name, email FROM users WHERE id = #{id}")
@Results({
    @Result(property = "id", column = "id"),
    @Result(property = "name", column = "name"),
    @Result(property = "email", column = "email")
})
User selectUserDetailedById(int id);

//6. 联合查询
@Select("SELECT u.id, u.name, a.city FROM users u INNER JOIN address a ON u.id = a.user_id WHERE u.id = #{id}")
User selectUserWithAddress(int id);

//7. 分页查询
@Select("SELECT * FROM users LIMIT #{limit} OFFSET #{offset}")
List<User> selectUsersByPage(@Param("limit") int limit, @Param("offset") int offset);

【K】MySQL 数据类型与 Java 类型的对应关系

在 MyBatis 中,Java 类型和 MySQL 数据库类型之间的映射是通过 `typeHandlers` 来实现的。以下是一些常见的 MySQL 数据类型与 Java 类型的对应关系,以及在 MyBatis 的 XML 配置文件中如何配置它们的示例。

MySQL 数据类型 Java 类型 MyBatis XML 配置中的类型别名
CHAR String VARCHAR
VARCHAR String VARCHAR
BLOB byte[] BLOB
TEXT String VARCHAR
INTEGER int/Integer INTEGER
TINYINT byte/Byte TINYINT
SMALLINT short/Short SMALLINT
MEDIUMINT int/Integer INTEGER
BIGINT long/Long BIGINT
FLOAT float/Float FLOAT
DOUBLE double/Double DOUBLE
DECIMAL java.math.BigDecimal DECIMAL
DATE java.sql.Date DATE
TIME java.sql.Time TIME
DATETIME java.sql.Timestamp TIMESTAMP
TIMESTAMP java.sql.Timestamp TIMESTAMP
BOOLEAN boolean/Boolean BOOLEAN
ENUM String VARCHAR
SET String VARCHAR

在 MyBatis 的配置文件 `mybatis-config.xml` 中,你不需要为每种类型映射都显式定义 `typeHandler`,因为 MyBatis 已经内置了对这些常见类型的处理。但如果你需要自定义类型处理器,你可以这样配置:

XML 复制代码
<typeHandlers>
  <typeHandler handler="com.example.MyCustomTypeHandler"/>
</typeHandlers>

以下是一个包含所有类型映射的 MyBatis 映射文件 (`UserMapper.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.example.mapper.UserMapper">

  <resultMap id="UserResultMap" type="User">
    <result property="id" column="id" javaType="int" jdbcType="INTEGER" />
    <result property="username" column="username" javaType="String" jdbcType="VARCHAR" />
    <result property="password" column="password" javaType="String" jdbcType="VARCHAR" />
    <result property="email" column="email" javaType="String" jdbcType="VARCHAR" />
    <result property="profilePhoto" column="profile_photo" javaType="byte[]" jdbcType="BLOB" />
    <result property="age" column="age" javaType="Integer" jdbcType="TINYINT" />
    <result property="balance" column="balance" javaType="java.math.BigDecimal" jdbcType="DECIMAL" />
    <result property="birthDate" column="birth_date" javaType="java.sql.Date" jdbcType="DATE" />
    <result property="loginTime" column="login_time" javaType="java.sql.Timestamp" jdbcType="TIMESTAMP" />
    <result property="isActive" column="is_active" javaType="Boolean" jdbcType="BOOLEAN" />
  </resultMap>

  <select id="selectUsers" resultMap="UserResultMap">
    SELECT * FROM users
  </select>

  <!-- Other CRUD operations go here -->

</mapper>

在这个示例中,`<resultMap>` 定义了如何将数据库表 `users` 中的列映射到 Java 类 `User` 的属性上。每个 `<result>` 元素指定了一个属性到列的映射,包括 Java 类型 (`javaType`) 和 JDBC 类型 (`jdbcType`)。

请注意,实际开发中可能不需要为每个字段都显式指定 `jdbcType`,因为 MyBatis 通常能够推断出对应的类型。但在某些情况下,特别是当 MyBatis 无法准确推断类型时(例如对于 `null` 值),指定 `jdbcType` 可以避免类型相关的错误。

【K】Mybatis相同代码复用

在 MyBatis 中,为了避免重复编写相同的 SQL 片段,可以使用 `<sql>` 元素定义可重用的 SQL 代码块,并通过 `<include>` 元素在需要的地方引入这些代码块。这种方式提高了代码的可维护性和可读性。以下是如何使用这些元素来提取和复用相同的代码段的总结:

1. 定义公共 SQL 片段

使用 `<sql>` 标签定义公共的 SQL 片段,并为其指定一个唯一的 `id`。这个 `id` 将在后续的 `<include>` 标签中被引用。

XML 复制代码
   <sql id="common_sql_where">
       <if test="id != null">
           AND id = #{id}
       </if>
       <!-- 可以继续添加其他公共条件 -->
   </sql>

2. 引用公共 SQL 片段

在实际的查询语句中,使用 `<include>` 标签引入公共 SQL 片段。通过 `refid` 属性指定需要引入的公共 SQL 片段的 `id`。

XML 复制代码
   <select id="selectWithCommonWhere" resultType="YourResultType">
       SELECT * FROM your_table WHERE 1=1
       <include refid="common_sql_where"/>
   </select>

3. 使用参数

在公共 SQL 片段中,可以使用 MyBatis 的参数占位符 `#{}` 来引用传入的参数。确保传入的参数名称与 `<if>` 测试条件中的参数名称相匹配。

4. 复用和组合

可以将多个 `<sql>` 片段组合在一起,使用多个 `<include>` 标签来构建复杂的查询条件。

XML 复制代码
   <select id="selectAdvanced" resultType="YourResultType">
       SELECT * FROM your_table
       WHERE 1=1
       <include refid="common_sql_where"/>
       <!-- 可以继续引入其他公共 SQL 片段 -->
   </select>

5. 注意事项

  • 确保 `<include>` 标签中的 `refid` 正确无误地指向了预定义的 `<sql>` 片段的 `id`。

  • 在 `<sql>` 片段中定义的条件必须符合 SQL 语法,特别是在使用 `<if>` 条件时要注意不要遗漏必要的 SQL 关键字,比如 `AND`。

  • 当在 `<sql>` 片段中使用动态 SQL(如 `<if>`)时,要注意条件的逻辑组合,以避免生成无效的 SQL。

通过这种方式,可以有效地管理和复用 SQL 代码,减少冗余,并使得 SQL 语句的维护变得更加简单。

【K】mysql如何实现插入一条数据后立刻获取该数据自增长id进行调用

背景解析

XML 复制代码
useGeneratedKeys 取值范围true|false 默认值是:false。
含义:设置是否使用JDBC的.

getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。

代码使用

XML 复制代码
  <insert id="insert" parameterType="com.hy.common.entity.User"
          useGeneratedKeys="true" keyProperty="id">
    insert into user (name, age)
    values ( #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER})
  </insert>
java 复制代码
    @Override
    @Transactional(readOnly = false)
    public int insertUser() {
        User user = new User();
        user.setName("why");
        user.setAge(18);
 
        int count = userMapper.insert(user);
        System.out.println(count);   // 插入的条数:1
        int id = user.getId();   
        System.out.println(id); // 自增的id:666
 
        return id;
    }

【K】Mybatis新增数据,存在就更新,不存在就添加

常规方法

先查询是否存在,存在就更新,不存在就添加.

如果数据量过大, 使用foreach批量操作

举例: 集合唯一索引 id

可以查询所有的id集合idSet, 使用in idSet查询那些存在, 返回结果集oldSet.

然后遍历判断idSet是否存在oldSet, 存在走更新逻辑,不存在走添加逻辑.

Replace关键字

REPLACE关键字的使用

使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一,形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。

在使用REPLACE时,表中必须有唯一索引,而且这个索引所在的字段不能允许空值,否则REPLACE就和INSERT完全一样的。

在执行REPLACE后,系统返回了所影响的行数,如果返回1,说明没有重复的记录,如果返回2,说明有重复记录,系统先DELETE这条记录,然后再INSERT这条记录。

语法和INSERT非常的相似,如下面的REPLACE语句是插入或更新一条记录。

XML 复制代码
REPLACE INTO users (id,name,age) VALUES(1, '李嘉欣', 18); 

【K】MyBatis执行多个sql语句

背景

XML 复制代码
驱动默认不开启支持多个sql执行。
在数据库连接的url增加参数allowMultiQueries,值为true,多个SQL直接一以";"分隔即可

xxx.jdbcUrl=jdbc:mysql://xx.xx.xx:3306/xxxxx?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true

&allowMultiQueries=true

代码举例

XML 复制代码
<select id="getUserAndOrders" resultSets="user,orders">
  select * from user where id = #{id};
  select * from orders where user_id = #{id};
</select>

实例举例

场景:

删除用户的时候需要先删除用户的外键关联数据,否则会触发规则报错。

本人遇到的是循环拼接不同字段条件的修改sql执行。

直接写多条语句,用";"隔开即可

XML 复制代码
<delete id="deleteUserById" parameterType="String">
    delete from sec_user_role where userId=#{id};
    delete from sec_user where id=#{id};
</delete>

分析总结

执行多个SQL查询并返回多个结果集的原因简述:

  • 在某些业务场景中,需要从不同的数据表中提取数据并组合成一个复合数据对象。
  • 执行多个查询并一次性返回所有结果集可以减少数据库IO操作,提高性能。
  • 将相关查询逻辑集中到一个地方有助于提高代码的可读性和可维护性。

MyBatis执行多个查询并处理结果集的方法简述:

  • MyBatis允许通过resultSets属性在一个<select>元素中执行多个查询并命名各个结果集。
  • 可以使用SqlSession的selectList或selectMap方法来获取这些结果集。
  • 结果集可以映射到不同的Java对象,并可通过自定义resultMap进行详细配置。

总结:

MyBatis支持一次执行多个SQL查询并返回多个结果集,这有助于优化性能和提升代码质量。

【K】Mybatis 不同条件拼接不同sql

在MyBatis中,可以使用动态SQL功能来根据不同的条件拼接不同的SQL语句。动态SQL是MyBatis的一大特色,它允许在XML映射文件中构建灵活的SQL语句。主要通过<if>, <choose>, <when>, <otherwise>, <where>, <set>, <foreach>等元素来实现条件逻辑。

举例1

以下是一个使用MyBatis动态SQL的例子,我们将创建一个根据不同条件来查询用户的例子。

首先,定义一个User对象和一个UserMapper接口:

java 复制代码
// User.java
public class User {
    private Integer id;
    private String name;
    private String email;
    // getters and setters...
}

// UserMapper.java
public interface UserMapper {
    List<User> findUsers(Map<String, Object> params);
}

然后,在MyBatis的XML映射文件中,我们定义动态SQL查询:

XML 复制代码
<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <select id="findUsers" resultType="com.example.User">
        SELECT id, name, email
        FROM users
        <where>
            <if test="id != null">
                AND id = #{id}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="email != null">
                AND email = #{email}
            </if>
        </where>
    </select>
</mapper>

在这个例子中,<where>元素会智能地插入WHERE关键字,并且只有当内部的条件成立时才会插入相应的条件语句,并且会处理好条件语句前的AND或OR关键字。

现在,当我们调用findUsers方法时,可以传递一个包含id、name、email等键的Map对象。MyBatis会根据Map中的键值对是否存在来动态构建SQL语句。

XML 复制代码
// 使用MyBatis的SqlSession来执行查询
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    Map<String, Object> params = new HashMap<>();
    params.put("name", "John Doe");
    List<User> users = mapper.findUsers(params);
    // 处理查询结果...
} finally {
    sqlSession.close();
}

在上面的Java代码中,我们创建了一个包含"name"键的Map,并将其作为参数传递给findUsers方法。MyBatis会生成一个包含AND name = 'John Doe'条件的SQL语句,因为Map中只有"name"键。

举例2: 判断某一个值

不同条件拼接不同sql

XML 复制代码
</where>
    ORDER BY
<if test="name != null and name !='' and name == '1'.toString()">
    dept DESC
</if>
<if test="name != null and name !='' and name == '2'.toString()">
    type DESC
</if>

Postman访问

注意事项

前言:
name代码为String,
XML 代码为: <if test="name != null and name !='' and name == '1'.toString()">
  1. postman入参可以为"name": "1",或"name": 1
  2. '1'需要加上单引号
  3. 加单引号后为字符,类型为Charactor

举例3

某些特殊业务场景下的, 为了替换#{demoWay}的替换写法...

XML 复制代码
            <if test="demoWay != null  and test="demoWay != '' ">
                <if test="demoWay == 'equal' ">
                    <![CDATA[ and demo_str = #{demoStr} ]]> </if>
                <if test="demoWay == 'gt' ">
                    <![CDATA[ and demo_str > #{demoStr} ]]> </if>
                <if test="demoWay == 'lt' ">
                    <![CDATA[ and demo_str < #{demoStr} ]]> </if>
                <if test="demoWay == 'gte' ">
                    <![CDATA[ and demo_str >= #{demoStr} ]]> </if>
                <if test="demoWay == 'lte' ">
                    <![CDATA[ and demo_str <= #{demoStr} ]]> </if>
            </if>

这种动态SQL的方法使得SQL语句的构建非常灵活,可以根据传入的参数不同构建不同的查询条件,而不必编写多个几乎相同的查询语句。这样的设计既简化了代码,也使得维护更加容易。

【K】-IFNULL处理N/A

背景知识

在数据库中,有时需要生成具有特定格式的唯一ID。例如,这里的ID由当前日期(格式为yyyymmdd)和一个顺序号(四位数)组成。每当需要添加新的记录时,就要生成一个新的ID,该ID比当天已有的最大ID大1。

SQL语句分析

原始的SQL语句试图获取当天最大的ID,然后将其加1以生成新的ID。如果当天没有ID,就默认使用'0001'作为顺序号。

sql 复制代码
公司表获取最大ID且加1:
ID示例:yyyymmdd+0001

SELECT
    IFNULL(RIGHT(ac.id + 1, 4), '0001') numMax
FROM
    app_company ac
WHERE
    LEFT(ac.id, 8) = DATE_FORMAT(now(), '%Y%m%d')
ORDER BY
    RIGHT(ac.id, 4) DESC
LIMIT 1

这个查询有几个问题:

  • IFNULL函数不会处理非NULL的"无效"值(如'N/A')。
  • 在没有任何记录的情况下,RIGHT(ac.id + 1, 4)将不会返回任何结果,因此IFNULL将返回'0001'。
  • 使用ORDER BY和LIMIT来获取最大值效率较低。

改进后的SQL语句

改进后的SQL语句使用MAX函数来找出当天最大的ID,然后通过IFNULL处理当天没有任何ID的情况。这样就不需要ORDER BY和LIMIT子句,因为MAX函数已经能够找到最大的ID。

sql 复制代码
SELECT
    IFNULL(MAX(RIGHT(ac.id, 4)) + 1, '0001') numMax
FROM
    app_company ac
WHERE
    LEFT(ac.id, 8) = DATE_FORMAT(now(), '%Y%m%d')

知识扩展

  • IFNULL: MySQL中的IFNULL函数用来检查第一个表达式是否为NULL,如果是,就返回第二个参数的值。
  • MAX: MAX函数返回一组值中的最大值,如果集合为空,则返回NULL。
  • RIGHT: RIGHT函数从字符串的右侧返回指定数量的字符。
  • LEFT: LEFT函数从字符串的左侧返回指定数量的字符。
  • DATE_FORMAT: DATE_FORMAT函数用于格式化日期值。

注意事项

在实际使用中,直接在数据库层面进行ID的生成可能会有并发问题,特别是在高并发的环境下。为了确保ID的唯一性和顺序,可能需要采用其他机制,比如应用层的锁或者使用数据库的序列(在MySQL 8.0+中为AUTO_INCREMENT属性)。

此外,如果ac.id是字符型字段,直接进行+ 1操作可能会导致错误,因为字符型和数值型的操作不同。在这种情况下,可能需要先将ID的顺序号部分转换为数值型,进行加法操作后再转换回字符型。

【K】Mybatis条件查询<where>标签

MyBatis 的 <where> 标签用于动态生成 SQL 查询语句中的 WHERE 条件。该标签的主要作用是简化 SQL 编写,并自动处理 WHERE 关键字和条件之间的逻辑关系(如 AND 或 OR)。当内部条件为空时,它会智能地省略 WHERE 关键字,而当有条件时,则会自动加上 WHERE 关键字。这样可以避免在动态 SQL 中手动编写复杂的逻辑来判断是否需要添加 WHERE 关键字。

<where> 标签的基本规则:

<where> 标签内部可以包含 <if>、<choose>、<when>、<otherwise> 等子标签。

如果 <where> 标签内部的条件都不成立,则整个 <where> 标签不会生成任何内容。

如果 <where> 标签内部至少有一个条件成立,则会自动在这些条件前添加 WHERE 关键字。

<where> 标签会自动处理条件之间的第一个 AND 或 OR 关键字。

示例:

假设我们有一个 User 表,包含 id、name、email 等字段,现在我们要根据这些字段的不同组合来查询用户。

UserMapper 接口:

java 复制代码
public interface UserMapper {
    List<User> findUsers(Map<String, Object> params);
}

UserMapper.xml 映射文件:

XML 复制代码
<mapper namespace="com.example.mapper.UserMapper">
    <select id="findUsers" resultType="com.example.User">
        SELECT id, name, email
        FROM User
        <where>
            <if test="id != null">
                id = #{id}
            </if>
            <if test="name != null and name != ''">
                AND name = #{name}
            </if>
            <if test="email != null and email != ''">
                AND email = #{email}
            </if>
        </where>
    </select>
</mapper>

在上述例子中:

  • 如果 params 中没有任何一个键值对,则 SQL 语句将是 SELECT id, name, email FROM User。
    如果 params 中只有 name 键值对,则 SQL 语句将是 SELECT id, name, email FROM User WHERE name = '指定的name值'。
    如果 params 中有 name 和 email 键值对,则 SQL 语句将是 SELECT id, name, email FROM User WHERE name = '指定的name值' AND email = '指定的email值'。

这种方式确保了 WHERE 条件的灵活性和正确性,同时避免了手动编写复杂的逻辑来控制 SQL 语句的准确性。使用 <where> 标签可以大大提高 SQL 语句的可维护性和可读性。

【K】使用resultMap封装对象一对多

在 MyBatis 中,`resultMap` 是一个非常强大的映射工具,它能够处理复杂的数据库关系,如一对一、一对多和多对多的关系。通过正确使用 `resultMap`,可以在执行单个查询时获取关联的数据,而不必执行多次查询,这样可以提高应用程序的性能。

下面是一个使用 `resultMap` 来处理一对一和一对多关系的完整示例。

数据库模型

假设我们有以下三个表:

  1. 用户表 `user`

  2. 部门表 `department`

  3. 用户联系人表 `user_linkman`

用户表(user):

sql 复制代码
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `code` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(2) unsigned DEFAULT NULL,
  `department_id` int(11) NOT NULL COMMENT '部门id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

部门表(department):

sql 复制代码
CREATE TABLE `department` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门id',
  `department_name` varchar(255) DEFAULT NULL COMMENT '部门名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='部门表';

用户联系人表(user_linkman):

sql 复制代码
CREATE TABLE `user_linkman` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户联系人表主键id',
  `user_id` int(11) DEFAULT NULL COMMENT '用户id',
  `linkman_id` varchar(255) DEFAULT NULL COMMENT '联系人id',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COMMENT='用户联系人表';

实体类

用户实体类(User):

java 复制代码
package com.example.demo.entity;

import lombok.Data;
import java.util.List;

@Data
public class User {
    private String id;
    private String code;
    private String name;
    private int age;
    private Department department;      // 对应部门实体
    private List<UserLinkman> linkmenList; // 对应联系人列表
}

MyBatis 配置

在 MyBatis 的映射文件中,我们可以定义一个 `resultMap` 来描述如何从数据库结果集映射到我们的实体类。

XML 复制代码
<resultMap id="userResultMap" type="User">
    <id property="id" column="id" />
    <result property="code" column="code" />
    <result property="name" column="name" />
    <result property="age" column="age" />
    <association property="department" column="department_id" javaType="Department" select="selectDepartmentById" />
    <collection property="linkmenList" ofType="UserLinkman" column="id" select="selectLinkmanListByUserId" />
</resultMap>

<select id="selectDepartmentById" resultType="Department">
    SELECT id, department_name AS 'departmentName' FROM department WHERE id = #{id}
</select>

<select id="selectLinkmanListByUserId" resultType="UserLinkman">
    SELECT id, user_id AS 'userId', linkman_id AS 'linkmanId' FROM user_linkman WHERE user_id = #{id}
</select>

<select id="selectUserById" resultMap="userResultMap">
    SELECT * FROM user WHERE id = #{id}
</select>

在上述配置中,我们定义了一个 `userResultMap`:

  • `<association>` 用于处理一对一的关系,这里是用户和部门的关系。

  • `<collection>` 用于处理一对多的关系,这里是用户和联系人的关系。

通过这种配置,当我们调用 `selectUserById` 查询时,MyBatis 会自动执行 `selectDepartmentById` 和 `selectLinkmanListByUserId` 查询来填充 `User` 实体中的 `department` 和 `linkmenList` 属性。

举例

假设我们需要查询某次考试的所有单位信息,包括名称、参考人数、通过人数、通过率,以及本部门所有参考人员的信息。我们可以创建一个对应的 `resultMap`:

XML 复制代码
<resultMap id="CountResultMap" type="com.example.demo.entity.vo.ExamTestVo">
    <result column="department" jdbcType="VARCHAR" property="department"/>
    <result column="exam_num" jdbcType="VARCHAR" property="examNum"/>
    <result column="pass_num" jdbcType="VARCHAR" property="passNum"/>
    <result column="percent_pass" jdbcType="VARCHAR" property="percentPass"/>
    <collection property="userList" javaType="list" column="id" ofType="User" select="selectUserListByExamId" />
</resultMap>

这里的 `<collection>` 标签将会把某个考试 ID 对应的所有用户信息作为一个列表映射到 `ExamTestVo` 的 `userList` 属性中。这样,通过单个查询,我们就能获取一个考试的所有相关信息,包括每个单位的详细数据和参考人员的列表。

【K】Mybatis使用常见类型的类型别名

MyBatis 提供了一系列内置的类型别名,用于简化 XML 配置文件中的类型引用。这些别名代表了 Java 中的一些常见类型。使用类型别名可以让你的 MyBatis 配置文件更加简洁易懂。

下面是一些常见的 MyBatis 内置类型别名及其对应的 Java 类型:

Java 类型 MyBatis 别名
byte _byte
long _long
short _short
int _int
Integer _integer
double _double
float _float
boolean _boolean

还有一些引用类型的别名:

Java 类型 MyBatis 别名
String string
Byte byte
Long long
Short short
Integer int
Double double
Float float
Boolean boolean
Date date
BigDecimal decimal
BigDecimal bigdecimal
Object object
Map map
HashMap hashmap
List list
ArrayList arraylist
Collection collection
Iterator iterator

使用这些类型别名的例子:

XML 复制代码
<select id="selectUserById" resultType="_int">
    SELECT age FROM user WHERE id = #{id}
</select>

<select id="selectUserName" resultType="string">
    SELECT name FROM user WHERE id = #{id}
</select>

<select id="selectAllUsers" resultType="map">
    SELECT * FROM user
</select>

在上述例子中,`resultType="_int"` 表示查询的结果是一个基本类型 `int`,`resultType="string"` 表示查询的结果是 `String` 类型,而 `resultType="map"` 表示查询的结果是 `Map` 类型的集合。

要注意的是,当我们使用类型别名 `_int` 时,通常是在查询返回单个值的场景,比如统计数量或者查询某个特定的数值

有用请点赞,养成良好习惯!

疑问、交流、鼓励请留言!

相关推荐
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
cmdch201711 小时前
Mybatis加密解密查询操作(sql前),where要传入加密后的字段时遇到的问题
数据库·sql·mybatis
秋恬意14 小时前
什么是MyBatis
mybatis
CodeChampion14 小时前
60.基于SSM的个人网站的设计与实现(项目 + 论文)
java·vue.js·mysql·spring·elementui·node.js·mybatis
ZWZhangYu1 天前
【MyBatis源码分析】使用 Java 动态代理,实现一个简单的插件机制
java·python·mybatis
程序员大金2 天前
基于SSM+Vue的个性化旅游推荐系统
前端·vue.js·mysql·java-ee·tomcat·mybatis·旅游
奔跑草-2 天前
【服务器】MyBatis是如何在java中使用并进行分页的?
java·服务器·mybatis
秋恬意2 天前
接口绑定有几种实现方式
mybatis
谢家小布柔2 天前
MyBatis入门的详细应用实例
mybatis
雅俗共赏zyyyyyy2 天前
Mybatis分页插件的使用问题记录
mybatis