通过myBatis将sql语句返回的值自动包装成一个java对象(2)

1.之前我们是如何执行一个sql语句自动包装成一个java对象呢?

1.创建一个mapper.xml,定义执行的语句名字包装成什么类

2.在总的配置文件里申明这个mapper

3.在java里通过sqlSession执行mapper里定义好的内容

我们还可以使用另一种方法实现第三步。现在我们我们实际上是通过读取xml配置文件中的映射关系来确定selectUser执行的是哪条sql语句,返回什么值。

我们还可以再创建一个接口,在接口中写抽象方法,将接口中的抽象方法和xml文件里的映射关系一一对应。这样我们通过调用接口里的抽象方法,就可以找到xml中的映射关系,进而确定 selectUser执行的是哪条sql语句。

2.现在我们如何执行一个sql语句自动包装成一个java对象

1.基本逻辑

mapper.xml中存放了很多映射关系:

sql语句名称-》真正的sql语句,ie:selectUser-》select * from accounting_ledger.user

现在我们编写一个接口,对这些映射关系命名:

a(映射关系名)= 【sql语句名称-》真正的sql语句】

有了接口之后,我们再调用某个sql语句,就只需要知道映射关系名即可。

2.编写接口和xml

接口:

java 复制代码
package Mybatis.Mapper;

import Mybatis.User;

import java.util.List;

public interface UserMapper {
    List<User> selectStudent();
}

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">
<!--
    MyBatis 映射器(Mapper)XML 文件,用于定义 SQL 映射配置。
    映射器文件通常用于将数据库操作与 Java 方法关联起来。
-->

    <!-- 定义映射器命名空间,通常与对应的 Java 接口或类的全限定名一致 -->
<mapper namespace="Mybatis.Mapper.UserMapper">

    <!--
        namespace是这个mapper配置文件的名字,这里我们通过namespace属性把这个mapper和UserMapper接口对应
        这样当我们调用接口中的抽象方法时,myBatis就知道通过这个mapper里的配置文件,来实现那个抽象方法

        id指的是"select * from user"这条语句的名字,起了这个名字后,我们就可以在后面的java代码里用这个名字指代这条sql语句
        这里我们已经将这个mapper和接口对应,接口里会有一个名叫selectUser的抽象方法
        当调用selectUser方法时,myBatis会通过namespace找到这个mapper
        再通过id来找到调用的这个selectUser方法具体对应这个mapper里的哪一部分语句

        resultType是需要映射成的类型的位置(不是电脑里的路径,是在java里的位置,哪个包(也可能不在包里,看你自己),哪个类)
        在这个例子里User是类名,Mybatis是User类所在的包名,这个地方每个人不一样,根据你的类的位置来决定。
    -->

    <select id="selectUser" resultType="Mybatis.User">
        select * from accounting_ledger.user
    </select>
    <!--
        在实际项目中,查询语句通常更为复杂,可以包含条件、关联查询等。
        这里的示例是一个简单的查询所有user的语句。
    -->

</mapper>

3.接口和mapper.xml是如何对应的

(1)一个项目里可能有多个mapper,而每一个mapper对应一个接口,所以我们需要将mapper和接口对应。

mapper的namespace属性应该等于接口的全限定名

(<mapper namespace="Mybatis.Mapper.UserMapper">

全限定名:

java 复制代码
package com.example.myproject.interfaces;

public interface TestMapper {
    // 接口方法定义
}

那么,TestMapper 接口的全限定名就是 com.example.myproject.interfaces.TestMapper。这个全限定名唯一标识了这个接口在Java代码中(不是计算机的路径)的位置。

(2)一个mapper里有多个sql语句,所以接口里也要有多个抽象方法,我们需要将接口里的抽象方法和mapper中的sql语句对应

xml中,每条sql的id应该和接口中的抽象方法名相同

(select id="selectUser "-》List<User> selectUser();)

(3)抽象方法的返回值应该和sql语句的返回值相同

这里抽象方法返回List<User>,而这个sql语句返回的就是一些列user对象的属性。

4.工程文件的格式

我们建议将mapper.xml和接口写在同一目录下:

5.更改最初的mybatis全局配置文件

因为此时我们的mapper被移动到了src文件夹内(接口肯定写在src里,mapper和接口在一起-》mapper在src里),所以此时我们要将全局配置文件中的mapper部分由:

复制代码
<mapper url="file:UserMapper.xml"/>

改为

复制代码
<mapper resource="Mybatis/Mapper/UserMapperWithInterface.xml"/>
复制代码
当配置文件在src文件夹下的时候,用resource,用/表示层级关系。在src文件夹外的时候,用url,用.表示层级关系。resource指类目录,url指电脑的文件目录

6.调用

java 复制代码
package Mybatis.Mapper;

import Mybatis.MyBatisUtil;
import Mybatis.User;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class Main3 {
    public static void main(String args[]){
        //用MyBatisUtil来包装之前Main1的工厂类,更简单地得到连接
        try(SqlSession sqlSession = MyBatisUtil.getSession(true)){
            //获取接口的实现类
            UserMapper testMapper = sqlSession.getMapper(UserMapper.class);
            //通过接口来实现sql语句
            List<User> user = testMapper.selectUser();

            //这行代码使用了 Java 8 引入的新特性之一,称为方法引用(Method Reference)。
            // 具体来说,System.out::println 是一个静态方法引用,用于将 println 方法关联到 System.out 对象上。
            //在这里,System.out::println 等效于 lambda 表达式 (s) -> System.out.println(s)。
            // 它表示将遍历 student 集合的每个元素,并将每个元素传递给 System.out.println 方法,实现在控制台上打印每个元素的效果。
            user.forEach(System.out::println);
        }
    }
}

1.当上述代码调用testMapper.selectUser();时,java发现这是一个接口的抽象方法,没有发现真正的实现方法,先暂停

2.与此同时,java读取到了mybatis的大配置文件,发现了

复制代码
<mapper resource="Mybatis/Mapper/UserMapperWithInterface.xml"/>

3.mybatis开始工作,找到了这个mapper,和刚刚的那个接口,发现了mapper.xml和接口的各种对应关系

4.mybatis通过这个mapper里的sql语句开始为接口里的抽象方法同态生成实现的方法。

相关推荐
计算机学姐2 分钟前
基于SSM的宠物领养平台
java·vue.js·spring·maven·intellij-idea·mybatis·宠物
泰山小张只吃荷园12 分钟前
期末Python复习-输入输出
java·前端·spring boot·python·spring cloud·docker·容器
Mr_Xuhhh15 分钟前
程序地址空间
android·java·开发语言·数据库
YSRM21 分钟前
异或-java-leetcode
java·算法·leetcode
大明湖的狗凯.24 分钟前
MySQL 中的乐观锁与悲观锁
java·数据库·mysql
真上帝的左手24 分钟前
数据库-MySQL-MybatisPlus整合多数据源
数据库·mysql·mybatis
真上帝的左手25 分钟前
数据库-MySQL-Mybatis源码解析-设计模式角度
数据库·mysql·mybatis
z2023050829 分钟前
linux之调度管理(13)- wake affine 唤醒特性
java·开发语言
AI人H哥会Java30 分钟前
【JAVA】Java高级:Java网络编程——TCP/IP与UDP协议基础
java·开发语言
robin_suli1 小时前
Java多线程八股(三)一>多线程环境使用哈希表和ArrayList
java·开发语言·多线程·哈希表