(尚硅谷)2022 版 MyBatis 教程笔记一


前言

SSM 框架中的 MyBatis 框架,半自动化持久层框架,学习笔记。

1、MyBatis 简介

1.1 MyBatis 特性

在这里插入图片描述
解释:

  • 既可以自己手动写 sql 语句,又可以通过逆向工程自动生成;
  • 结果集映射,只需要配置参数,具体如何放到结果集中,框架会帮你实现好

1.2 MyBatis下载

这里不想下载也可以不下载,这边自己下载可以获取官方的英文文档,可以对照 MyBatis 中文网站来看看最新版中的对应配置或者文件是否进行了修改。

后面在 maven 中使用 mybatis 的时候会自动导包的。

下载官方网站:mybatis/mybatis-3
中文文档网站:MyBatis中文网

在这里插入图片描述
在这里插入图片描述
在下载完成并且解压之后,在文件夹下面找到这样的 pdf 文件,即为官方文档:

在这里插入图片描述

1.3 和其他持久层技术的对比

在这里插入图片描述
在这里插入图片描述

2、搭建 MyBatis 工程步骤

2.1 开发环境

IDE:idea 2021.3.2
构建工具:maven 3.6.3
MySQL 版本:MySQL 8.0
MyBatis 版本:MyBatis 3.5.10

2.2 创建 MyBatis 工程

  1. 新建一个空白的 projects,修改他的 JDK 版本,以及它的输出路径,这里不是 java 或者 web 工程,所以输出路径不重要。

在这里插入图片描述

1. 确保 maven 的配置

  1. File | Settings | Build, Execution, Deployment | Build Tools | Maven 设置中,确认 maven 用的是我们自己下载的 maven 版本,以及我们自己设置的 maven 本地仓库;
  2. 这边可以一劳永逸的进行设置,参考之前的笔记(尚硅谷)Maven 新版教程 - 锦囊一,其中 4.3 节讲解了如何配置新打开的所有工程的 maven 设置。

在这里插入图片描述

2.3 新建一个 maven 模块

  1. 选择 JDK 版本,并且设置它的 maven 坐标:

在这里插入图片描述
在这里插入图片描述

1. 打包方式修改为 jar 包

  1. 首先在 pom.xml 文件中设置 packing 标签,将打包方式设置为 jar 包;
  2. 然后点击右上角的小图标自动导入 jar 包,或者使用你自己设置的快捷键自动导包。

在这里插入图片描述

2. 引入依赖

  1. pom.xml 文件中将依赖复制粘贴进来,这里面主要包括 MyBatis 核心、junit 测试、MySQL 连接驱动、log4j 日志的包;
  2. 加入依赖之后记得自动导包;
<dependencies>
    <!-- Mybatis核心 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.10</version>
    </dependency>
    <!-- junit测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.29</version>
    </dependency>

    <!-- log4j日志 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

3. 创建 MyBatis 的核心配置文件

  1. src/main/resources 包下面新建一个核心配置文件,一般命名为 mybatis-config.xml
  2. 核心配置文件主要用于配置连接数据库的环境以及 MyBatis 的全局配置信息,这里用的是优化版;
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入properties文件,此时就可以${属性名}的方式访问属性值-->
    <properties resource="jdbc.properties"/>

    <!--设置类型别名-->
    <typeAliases>
        <!--<typeAlias type="com.atguigu.User"></typeAlias>-->
        <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写-->
        <package name="com.atguigu.mybatis.pojo"/>
    </typeAliases>

    <!--environments:配置多个连接数据库的环境-->
    <environments default="development">

        <environment id="development">
            <!--transactionManager:设置事务管理方式-->
            <transactionManager type="JDBC"/>
            <!--dataSource:配置数据源,使用使用数据库连接池缓存数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

    </environments>

    <!--引入映射文件-->
    <mappers>
        <!--<mapper resource="mappers/UserMapper.xml"/>-->
        <!--以包为单位引入映射文件-->
        <package name="com.atguigu.mybatis.mapper"/>
    </mappers>
</configuration>

解释:

  • !DOCTYPE 后面的标签是配置文件的根标签;

src/main/resources 文件夹下创建关于数据库连接的配置文件 jdbc.properties:

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=root
jdbc.password=abc123

注意:

  • 设置 properties 的时候为了区分同名的不同功能的参数,在配置文件中某一参数前面加上前缀,例如: jdbc.xxx
  • 将当前的配置文件通过 properties 标签引入 mybatis 配置文件中。

4. 创建 mapper 接口

  1. MyBatis 中的 mapper 接口相当于以前的 DAO 接口,但是区别在于,mapper 仅仅是接口,我们不需要提供实现类(面向接口编程);
  2. 根据 xml 文件配置或者注解配置,调用接口的方法自动对应 Sql 语句;

新建一个文件夹专门用来放置用到的 mapper 接口:

在这里插入图片描述
在这里插入图片描述

新建一个 mapper 接口:

在这里插入图片描述

mapper 接口中编写要用到的和数据库交互的方法:

在这里插入图片描述

5. 创建 MyBatis 的映射文件

在这里插入图片描述
在这里插入图片描述

  1. 映射文件的命名规则:
  • 表所对应的 实体类的类名+Mapper.xml ,例如:表 t_user,映射的实体类为 User,所对应的映射文件为 UserMapper.xml
  • 因此一个映射文件对应一个实体类,对应一张表的操作;
  • MyBatis 映射文件用于编写 SQL,访问以及操作表中的数据;

新建一个放置 mapper 映射文件的文件夹:

在这里插入图片描述
在这里插入图片描述

注意:

  1. 在 resources 包下面创建 directory 和创建 package 是不一样的,不能用com.atguigu.mybatis.mapper 这种方式创建多个文件夹,这样创建出来的是一个包名;应该用 com/atguigu/mybatis/mapper 这种方式。

新建一个 mapper 映射文件:

在这里插入图片描述
映射文件中编写具体的 mapper 接口想要实现的方法的 sql 语句:

在这里插入图片描述

注意,MyBatis 中可以面向接口操作数据,要保证两个一致:

  • mapper 接口的全类名和映射文件的命名空间(namespace)保持一致,这里全类名指的是该接口在 src\mian\java 包下的什么位置;
  • mapper 接口中方法的方法名和映射文件中编写 SQL 的标签的 id 属性保持一致;
  • 表–实体类–mapper接口–映射文件

6. 加入 log4j 日志功能

在这里插入图片描述

  1. 之前我们在加入依赖那一步已经添加了 log4j 的依赖
  2. src/main/resources 目录下加入 log4j.xml 的配置文件:

在这里插入图片描述
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>

7. 通过 junit 测试功能

  1. test\java 包下面新建一个用来测试的 java 类:
    在这里插入图片描述
    在这里插入图片描述
    测试类代码:
  2. 加载核心配置文件,以字节输入流的方式获取,因为是流的方式,所以要抛出异常;
  3. 获取 SqlSessionFactoryBuilder,一个创建 SqlSessionFactory 的类;
  4. 获取 sqlSessionFactory, 通过核心配置文件所对应的字节输入流创建工厂类 SqlSessionFactory,生产 SqlSession对象(工厂模式:将我们创建对象的过程进行封装,直接提供想要的对象);
  5. 创建 SqlSession 对象,此时通过 SqlSession 对象所操作的 sql 都必须手动提交或回滚事务(SqlSession sqlSession = sqlSessionFactory.openSession(););
  6. 获取 mapper 接口对象,我们只有接口,没有实现类,sqlSession.getMapper 方法,当我们传进去一个方法的类对象的时候,这个方法能帮助我们获取这个类的实例化对象(代理模式:帮助我们返回一个接口的实现类对象);
  7. 调用 mapper 接口中的方法来进行测试
/**
 * SqlSession默认不自动提交事务,若需要自动提交事务
 * 可以使用SqlSessionFactory.openSession(true);
 */
@Test
public void testMyBatis() throws IOException {
    //加载核心配置文件,以字节输入流的方式获取,因为是流的方式,所以要抛出异常
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    //获取SqlSessionFactoryBuilder
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    //获取sqlSessionFactory,工厂模式:将我们创建对象的过程进行封装,直接提供想要的对象
    // 通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象
    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);

    //创建SqlSession对象,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务
    //SqlSession sqlSession = sqlSessionFactory.openSession();
    //创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //获取mapper接口对象,我们只有接口,没有实现类,
    // getMapper当我们传进去一个方法的类对象的时候,这个方法能帮助我们获取这个类的实例化对象
    // 代理模式:帮助我们返回一个接口的实现类对象
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    //测试功能
    int result = mapper.insertUser();
    //提交事务
    //sqlSession.commit();
    System.out.println("result:" + result);
}

解释:

  • 设置 SqlSession sqlSession = sqlSessionFactory.openSession(true); 表示 SqlSession 对象所操作的 sql 会进行自动提交;

在这里插入图片描述

执行上述方法控制台打印的日志文件如下,配置文件没有问题:

在这里插入图片描述
解释:

  • 第一行输出表示执行的 sql 语句;
  • 第二行日志信息表示 mapper 接口输入的参数,这里 insertUser() 方法没有输入参数;
  • 第三行返回的是执行的结果,表示更新了一条数据。

3、核心配置文件详解(了解)

这里配置文件了解即可,到时候需要用哪个标签,就从官方文档中去找:
在这里插入图片描述

<?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?,settings?,typeAliases?,typeHandlers?,
        objectFactory?,objectWrapperFactory?,reflectorFactory?,
        plugins?,environments?,databaseIdProvider?,mappers?
    -->

    <!--引入properties文件,此时就可以${属性名}的方式访问属性值-->
    <properties resource="jdbc.properties" />

    <!--设置类型别名-->
    <typeAliases>
        <!--
            typeAlias:设置某个类型的别名
            属性:
                type:设置需要设置别名的类型
                alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名,即类名且不区分大小写
        -->
        <!--<typeAlias type="com.atguigu.User"></typeAlias>-->
        <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写-->
        <package name="com.atguigu.mybatis.pojo"/>
    </typeAliases>

    <!--
        environments:配置多个连接数据库的环境
        属性:
            default:设置默认使用的环境的id
    -->
    <environments default="development">
        <!--
            environment:配置某个具体的环境
            属性:
                id:表示连接数据库的环境的唯一标识,不能重复
        -->
        <environment id="development">
            <!--
                transactionManager:设置事务管理方式
                属性:
                    type="JDBC|MANAGED"
                    JDBC:表示当前环境中,执行SQL时,使用的是JDBC中原生的事务管理方式,事务的提交或回滚需要手动处理
                    MANAGED:被管理,例如Spring
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource:配置数据源
                属性:
                    type:设置数据源的类型
                    type="POOLED|UNPOOLED|JNDI"
                    POOLED:表示使用数据库连接池缓存数据库连接,即会将创建的连接进行缓存,下次使用可以从缓存中直接获取,不需要重新创建
                    UNPOOLED:表示不使用数据库连接池,即每次使用连接都需要重新创建
                    JNDI:表示使用上下文中的数据源
            -->
            <dataSource type="POOLED">
                <!--设置连接数据库的驱动-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--设置连接数据库的连接地址-->
                <property name="url" value="${jdbc.url}"/>
                <!--设置连接数据库的用户名-->
                <property name="username" value="${jdbc.username}"/>
                <!--设置连接数据库的密码-->
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--引入映射文件-->
    <mappers>
        <!--<mapper resource="mappers/UserMapper.xml"/>-->
        <!--
            以包为单位引入映射文件
            要求:
            1、mapper接口所在的包要和映射文件所在的包一致
            2、mapper接口要和映射文件的名字一致
        -->
        <package name="com.atguigu.mybatis.mapper"/>
    </mappers>
</configuration>

4、在 IDEA 中将 MyBatis 核心配置文件和 mapper 映射文件配置成自己的模板

  1. File | Settings | Editor | File and Code Templates 中设置 MyBatis 核心配置文件模板:

在这里插入图片描述
在这里插入图片描述

核心配置文件信息,注释内容可以删掉:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入properties文件,此时就可以${属性名}的方式访问属性值-->
    <properties resource="jdbc.properties" />

    <!--设置类型别名-->
    <typeAliases>
        <!--<typeAlias type="com.atguigu.User"></typeAlias>-->
        <!--以包为单位,将包下所有的类型设置默认的类型别名,即类名且不区分大小写-->
        <package name="com.atguigu.mybatis.pojo"/>
    </typeAliases>

    <!--environments:配置多个连接数据库的环境-->
    <environments default="development">

        <environment id="development">
            <!--transactionManager:设置事务管理方式-->
            <transactionManager type="JDBC"/>
            <!--dataSource:配置数据源,使用使用数据库连接池缓存数据库连接-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

    </environments>

    <!--引入映射文件-->
    <mappers>
        <!--<mapper resource="mappers/UserMapper.xml"/>-->
        <!--以包为单位引入映射文件-->
        <package name="com.atguigu.mybatis.mapper"/>
    </mappers>
</configuration>

设置好之后,在 src/main/resources 文件夹下面新建核心配置文件如下图所示,点击之后可以一键创建:

在这里插入图片描述

  1. File | Settings | Editor | File and Code Templates 中设置映射文件模板:

在这里插入图片描述
在这里插入图片描述

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="">

</mapper>

创建好模板之后可以在对应文件夹下面一键创建对应模板:
在这里插入图片描述

因为上面没有指定创建的文件名称,所以这里点击创建新的映射文件之后还要有一步命名,已经指定了文件格式,所以这里加不加 .xml 后缀都可以:

在这里插入图片描述

5、MyBatis 的增删改查

5.1 增删改

  1. 对于增删改只需要在 mapper 接口中先创建一个方法,然后自己编写 mapper 映射文件中对应的 sql 语句即可;
  2. 还要注意 mapper 接口中的方法和映射文件中的 id 一致;
    在这里插入图片描述

5.2 查询数据库信息

  1. 对于查询数据库中的信息,有两种不同的情况:
    在这里插入图片描述
    解释:
  • 查询的标签 select 必须设置属性 resultTyperesultMap ,用于设置实体类和数据库表的映射关系, mybatis 省了处理结果集的的过程,但是我们还要指定返回的结果集的类型:
    • resultType:自动映射,用于属性名和表中字段名一致的情况
    • resultMap:自定义映射,用于一对多或多对一或字段名和属性名不一致的情况
  • 当我们在核心配置文件中设置了 typeAliases 标签时,即我们设置了以包为单位,将包下所有的类型设置默认的类型别名,这里映射的 id 可以改为 User 即类的类名(不区分大小写)
    在这里插入图片描述
  1. 当查询的数据为多条时,不能使用实体类作为返回值,只能使用集合,否则会抛出异常;

可能的报错信息

  1. 没有设置属性 resultTyperesultMap 的时候,报错信息如下:
Cause: org.apache.ibatis.executor.ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'com.atguigu.mybatis.mapper.UserMapper.getUserById'.  It's likely that neither a Result Type nor a Result Map was specified.

在这里插入图片描述
解释:

  • 从打印出来的日志信息可以看出来 sql 语句执行了,也经过了获取参数步骤;
  • 在数据库返回给服务器的时候,处理数据库结果集的时候出错了。
  1. 如果返回的是几行数据,但是我们使用的是实体类而不是一个 list 集合来接收的话,就会报错,表示结果集太多,用一个实体类接收不到:
TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 8

在这里插入图片描述

6、MyBatis 获取参数值的两种方式(重点)

在这里插入图片描述

6.1 mapper 接口方法的参数为单个的字面量类型

  1. 可以通过 ${}#{} 以任意的名称获取参数值,但是需要注意 ${} 的单引号问题;
  2. ${} 需要手动设置单引号 ;
  3. #{} 在解析的时候会自动添加单引号。
<!--User getUserByUsername(String username);-->
<select id="getUserByUsername" resultType="User">
    <!--  select * from t_user where username = #{username}  -->
    select * from t_user where username = '${username}'
</select>

6.2 mapper 接口方法的参数为多个

  1. 此时 MyBatis 会将这些参数放在一个 map 集合中,以两种方式进行存储:

    • 以 arg0,arg1,… 为键,以参数为值
    • 以 param1,param2,… 为键,以参数为值
  2. 因此只需要通过 #{}${} 以键的方式访问值即可,但是需要注意 ${} 的单引号问题。

<!--User checkLogin(String username, String password);-->
<select id="checkLogin" resultType="User">
    <!--select * from t_user where username = #{arg0} and password = #{arg1}-->
    select * from t_user where username = '${param1}' and password = '${param2}'
</select>

当我们使用其他参数来访问,比如说将其中访问的属性值改为 where username = #{username} 的时候,会报如下的错误:

Cause: org.apache.ibatis.binding.BindingException: Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]

6.3 map 集合的参数

  1. 若 mapper 接口方法的参数有多个时,可以手动将这些参数放在一个 map 中存储,只需要通过 #{}${}以键的方式访问值即可,但是需要注意 ${} 的单引号问题;

mapper 接口中方法的编写:
在这里插入图片描述
映射文件的编写:

<!--User checkLoginByMap(Map<String, Object> map);-->
<select id="checkLoginByMap" resultType="User">
    select * from t_user where username = #{username} and password = #{password}
</select>

测试类的编写:

//当有多个字面量的时候,可以将多个字面量封装进一个 map 集合中
@Test
public void testCheckLoginByMap() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    Map<String, Object> map = new HashMap<>();
    map.put("username", "admin");
    map.put("password", "123");
    User user = mapper.checkLoginByMap(map);
    System.out.println(user);
}

6.4 实体类类型的参数

  1. mapper 接口方法的参数是实体类类型的参数,只需要通过 #{}${} 以属性的方式访问属性值即可,但是需要注意 ${} 的单引号问题;
  2. 有时候没有成员变量,但是有对应的 get/set 方法,Spring 中你点击 properties 中(name,value)中对应的 name 跳到的是 set 方法

在这里插入图片描述

<!--int insertUser(User user);直接通过属性名来访问属性值就可以了-->
<insert id="insertUser">
    insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
//测试参数是实体类参数
@Test
public void testInsertUser() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    int result = mapper.insertUser(new User(null, "李四", "123", 23, "男", "123@qq.com"));
    System.out.println(result);
}

6.5 使用 @Param 标识参数

  1. 此时 MyBatis 会将这些参数放在一个 map 集合中,以两种方式进行存储
    • 以@Param注解的值为键,以参数为值
    • 以param1,param2…为键,以参数为值
  2. 因此只需要通过 #{}${} 以键的方式访问值即可,但是需要注意 ${} 的单引号问题

在这里插入图片描述

<!--User checkLoginByParam(@Param("username") String username, @Param("password") String password);-->
<select id="checkLoginByParam" resultType="User">
    select * from t_user where username = #{username} and password = #{password}
</select>
@Test
public void testCheckLoginByParam() {
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
    User user = mapper.checkLoginByParam("admin", "123");
    System.out.println(user);
}

6.6 总结

  1. 建议有实体类的时候用属性值来访问;
  2. 没有实体类的时候用 @Param 注解命名参数,不管字面量单个还是多个,是不是 map 集合都可以使用自己用注解定义的参数来访问。

6.7 @Param 标识的源码解析

为啥我们能将我们想要的 key 值,以及对应的 value 值设置进去呢?

  1. 首先看这个方法的第三步的内部是如何调用的?

在这里插入图片描述
2. mapper 映射的底层使用了代理模式,通过反射执行当前命令对应的方法
在这里插入图片描述

在这里插入图片描述
3. 当前命令中,name 对应的是要执行的 sql 语句(唯一标识:mapper 映射文件中 namespace + id),方法对应的是 select 方法,所以 switch - case 直接跳到 select 方法去执行对应的方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这边在 else 模块中,第一个方法是将 args 参数转换成 sql 要求的参数,点进这个方法看一下里面怎么写的?

在这里插入图片描述
再进入方法内部,这个方法是一个将注解设定的命名规则的名称设置成 map 容器的 key 值的方法
在这里插入图片描述

第一步:name 是一个排序的 map 容器,其中 0 号位置放了我们通过注解命名的第一个参数名称,1 号位置放置了我们通过注解命名的第二个参数名称:

在这里插入图片描述

第二步:又因为我们有参数注解而且参数注解的个数不为1,所以跳到 else 中执行,新建一个 map 容器用来放置 (键值,参数值);

第三步:遍历 names 这个 map 容器,取出其中第一个键值对;

第四步:将它的 value 值即放置的自定义的 username 注解名称当作键值,将 args[当前键值对的键值] 即 args[0] 当作 value 值放进 params 这个 map 容器中;

在这里插入图片描述
第五步:定义一个字符串 param1,这里的 1 表示的是遍历第一个键值对即 i = 0;

在这里插入图片描述
第六步:如果当前 names 这个 map 容器中没有包含当前的这个 param1 这个值(防止我们自己定义了,重复放置),那么我们就将(param1 ,args[0])这一个键值对放进 param 这个 map 容器中,也就是我们既可以用我们自己设定的 username 来访问对应的参数值,也可以用 param1 来访问对应的参数值。

第七步:i++,遍历 names 容器中的下一个键值对,重复执行 4 - 6;

第八步:最后将生成的 param 这个 map 容器返回,我们可以从中任意选择一个键值来访问对应的参数。

7、MyBatis 的各种查询功能

7.1 若查询出的数据只有一条

  1. 可以通过实体类对象接收
  2. 可以通过list集合接收(建议直接用 list 集合接收)

mapper 接口中方法的定义:
在这里插入图片描述
mapper 映射文件中 sql 语句的编写:

在这里插入图片描述
测试类的编写:

//测试根据id查询用户信息,用 实体类、list集合来接收都可以
@Test
public void testGetUserById(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
    System.out.println(mapper.getUserById(5));
}

结果:
在这里插入图片描述

  1. 可以通过map集合接收

mapper 接口中方法的定义:

在这里插入图片描述

mapper 映射文件中 sql 语句的编写:

在这里插入图片描述

测试类的编写:

//测试单条数据放在 map 集合中
@Test
public void testGetUserByIdToMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
    System.out.println(mapper.getUserByIdToMap(6));
}

结果:
在这里插入图片描述
注意:

  • 通过 map 集合接收到的数据是乱序的,因为 map 集合本身是通过计算 hashcode 散射来放置数据的。

7.2 若查询出的数据有多条

  1. 可以通过实体类类型的 list 集合接收

mapper 接口中方法的定义:

在这里插入图片描述

mapper 映射文件中 sql 语句的编写:

在这里插入图片描述

测试类的编写:

//测试获取多个数据,只能通过 list 来接收
@Test
public void testGetAllUser(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
    System.out.println(mapper.getAllUser());
}
  1. 可以通过 map 类型的 list 集合接收
  2. 可以在 mapper 接口的方法上添加 @MapKey 注解,此时就可以将每条数据转换的 map 集合作为值,以某个字段的值作为键,放在同一个map集合中

mapper 接口中方法的定义:
在这里插入图片描述

mapper 映射文件中 sql 语句的编写:

在这里插入图片描述

测试类的编写:

//测试多条数据用 map 集合来接收
@Test
public void testGetAllUserToMap(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
    System.out.println(mapper.getAllUserToMap());
}

7.3 查询单个数据(聚合函数)

  1. MyBatis 中设置了默认的类型别名:
java.lang.Integer --> int,integer
int --> _int,_integer
Map --> map
String --> string

mapper 接口中方法的定义:
在这里插入图片描述

mapper 映射文件中 sql 语句的编写:

在这里插入图片描述

测试类的编写:

//测试得到的是单个数据,需要用的 java 中的常见数据类型来接收
@Test
public void testGetCount(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    SelectMapper mapper = sqlSession.getMapper(SelectMapper.class);
    System.out.println(mapper.getCount());
}
  • 14
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值