Mybatis-Spring-注入映射器

本文介绍如何利用MyBatis-Spring提供的MapperFactoryBean进行数据映射器的注入,简化DAO层代码编写,并通过MapperScannerConfigurer自动扫描注册映射器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注入映射器
为了代替手工使用 SqlSessionDaoSupport 或 SqlSessionTemplate 编写数据访问对象 (DAO)的代码,MyBatis-Spring 提供了一个动态代理的实现:MapperFactoryBean。这个类 可以让你直接注入数据映射器接口到你的 service 层 bean 中。当使用映射器时,你仅仅如调 用你的 DAO 一样调用它们就可以了,但是你不需要编写任何 DAO 实现的代码,因为 MyBatis-Spring 将会为你创建代理。


使用注入的映射器代码,在 MyBatis,Spring 或 MyBatis-Spring 上面不会有直接的依赖。 MapperFactoryBean 创建的代理控制开放和关闭 session,翻译任意的异常到 Spring 的 DataAccessException 异常中。此外,如果需要或参与到一个已经存在活动事务中,代理将 会开启一个新的 Spring 事务。


MapperFactoryBean
数据映射器接口可以按照如下做法加入到 Spring 中:


<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
  <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
MapperFactoryBean 创建的代理类实现了 UserMapper 接口,并且注入到应用程序中。 因为代理创建在运行时环境中(Runtime,译者注) ,那么指定的映射器必须是一个接口,而 不是一个具体的实现类。


如果 UserMapper 有一个对应的 MyBatis 的 XML 映射器文件, 如果 XML 文件在类路径的 位置和映射器类相同时, 它会被 MapperFactoryBean 自动解析。 没有必要在 MyBatis 配置文 件 中 去 指 定 映 射 器 , 除 非 映 射 器 的 XML 文 件 在 不 同 的 类 路 径 下 。 可 以 参 考 SqlSessionFactoryBean 的 configLocation 属性(第三章)来获取更多信息。


注意,当 MapperFactoryBean 需要 SqlSessionFactory 或 SqlSessionTemplate 时。 这些可以通过各自的 SqlSessionFactory 或 SqlSessionTemplate 属性来设置, 或者可以由 Spring 来自动装配。如果两个属性都设置了,那么 SqlSessionFactory 就会被忽略,因为 SqlSessionTemplate 是需要有一个 session 工厂的设置; 那个工厂会由 MapperFactoryBean. 来使用。


你可以直接在 business/service 对象中以和注入任意 Spring bean 的相同方式直接注入映 射器:


<bean id="fooService" class="org.mybatis.spring.sample.mapper.FooServiceImpl">
  <property name="userMapper" ref="userMapper" />
</bean>
这个 bean 可以直接在应用程序逻辑中使用:


public class FooServiceImpl implements FooService {


  private UserMapper userMapper;


  public void setUserMapper(UserMapper userMapper) {
    this.userMapper = userMapper;
  }


  public User doSomeBusinessStuff(String userId) {
    return this.userMapper.getUser(userId);
  }
}
注意在这段代码中没有 SqlSession 或 MyBatis 的引用。也没有任何需要创建,打开或 关闭 session 的代码,MyBatis-Spring 会来关心它的。


MapperScannerConfigurer
没有必要在 Spring 的 XML 配置文件中注册所有的映射器。相反,你可以使用一个 MapperScannerConfigurer , 它 将 会 查 找 类 路 径 下 的 映 射 器 并 自 动 将 它 们 创 建 成 MapperFactoryBean。


要创建 MapperScannerConfigurer,可以在 Spring 的配置中添加如下代码:


<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  <property name="basePackage" value="org.mybatis.spring.sample.mapper" />
</bean>
basePackage 属性是让你为映射器接口文件设置基本的包路径。 你可以使用分号或逗号 作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到。


MapperScannerConfigurer 属性不支持使用了 PropertyPlaceholderConfigurer 的属 性替换,因为会在 Spring 其中之前来它加载。但是,你可以使用 PropertiesFactoryBean 和 SpEL 表达式来作为替代。


注 意 , 没 有 必 要 去 指 定 SqlSessionFactory 或 SqlSessionTemplate , 因 为 MapperScannerConfigurer 将会创建 MapperFactoryBean,之后自动装配。但是,如果你使 用了一个 以上的 DataSource ,那 么自动 装配可 能会失效 。这种 情况下 ,你可 以使用 sqlSessionFactoryBeanName 或 sqlSessionTemplateBeanName 属性来设置正确的 bean 名 称来使用。这就是它如何来配置的,注意 bean 的名称是必须的,而不是 bean 的引用,因 此,value 属性在这里替代通常的 ref:


<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
MapperScannerConfigurer 支 持 过 滤 由 指 定 的 创 建 接 口 或 注 解 创 建 映 射 器 。 annotationClass 属性指定了要寻找的注解名称。 markerInterface 属性指定了要寻找的父 接口。如果两者都被指定了,加入到接口中的映射器会匹配两种标准。默认情况下,这两个 属性都是 null,所以在基包中给定的所有接口可以作为映射器加载。


被发现的映射器将会使用 Spring 对自动侦测组件(参考 Spring 手册的 3.14.4)默认的命 名策略来命名。也就是说,如果没有发现注解,它就会使用映射器的非大写的非完全限定类 名。但是如果发现了@Component 或 JSR-330 的@Named 注解,它会获取名称。注意你可以 配 置 到 org.springframework.stereotype.Component , javax.inject.Named(如果你使用 JSE 6 的话)或你自己的注解(肯定是自我注解)中,这 样注解将会用作生成器和名称提供器。
<think>嗯,用户问的是一次请求的全过程,这应该是想了解从客户端发起请求到服务器响应并返回数据的整个流程。首先,我需要回忆一下网络通信的基本模型,比如OSI七层模型或者TCP/IP四层模型。然后,考虑从用户输入网址开始,DNS解析、建立TCP连接、发送HTTP请求、服务器处理、返回响应、浏览器渲染这些步骤。可能还需要细分每个步骤的具体过程,比如三次握手、TLS握手如果是HTTPS的话。同时要注意用户可能是开发者或者普通用户,但问题比较基础,可能不需要太深入的技术细节,但需要准确。 用户提到使用中文回答,所以要注意用词准确且易懂。系统级指令里要求数学表达式用$...$,不过这个问题可能不涉及数学公式,但需要留意。结构要清晰,分步骤说明,可能用序号列出每个阶段,再详细展开。比如: 1. DNS解析:将域名转换为IP地址,涉及到本地缓存、递归查询等。 2. 建立TCP连接:三次握手的过程,客户端发送SYN,服务器SYN-ACK,客户端ACK。 3. 发送HTTP请求:GET/POST等方法,请求头和正文。 4. 服务器处理:Web服务器(如Nginx)转发到应用服务器,处理逻辑,访问数据库等。 5. 返回HTTP响应:状态码、响应头、数据(HTML/JSON等)。 6. 浏览器渲染:解析HTML、CSS,执行JavaScript,构建DOM树等。 需要检查是否每个步骤都覆盖到了关键点,有没有遗漏,比如可能还有TLS握手在HTTPS的情况下,或者负载均衡、CDN的环节。同时要确保流程正确,比如DNS解析是在TCP连接之前,而TLS握手是在TCP连接之后。可能还要提到缓存机制,比如浏览器缓存、CDN缓存等对请求过程的影响。 另外,用户可能对某些术语不太了解,需要适当解释,比如DNS是什么,三次握手的目的,状态码的意义等。但保持简洁,不过于深入。最后,总结整个流程,让用户有一个整体的认识。需要确保语言流畅,逻辑清晰,步骤正确,没有技术错误。</think>一个完整的网络请求(例如访问网页)通常经历以下阶段,以访问 `https://example.com` 为例: --- ### 一、DNS 解析 1. **浏览器缓存**:检查本地是否缓存过域名对应的 IP 地址。 2. **系统缓存**:若未命中,查询操作系统 hosts 文件。 3. **递归查询**:向本地 DNS 服务器(如 ISP 提供)发起请求,逐级查询根域名服务器、顶级域名服务器(`.com`),最终获得 `example.com` 的 IP 地址。 --- ### 二、建立 TCP 连接 1. **三次握手**: - 客户端发送 `SYN` 包(同步请求)。 - 服务器返回 `SYN-ACK` 包(确认同步)。 - 客户端回复 `ACK` 包(最终确认),连接建立。 --- ### 三、TLS 握手(仅 HTTPS) 1. **协商加密协议**:客户端发送支持的 TLS 版本和密码套件。 2. **证书验证**:服务器返回 SSL 证书,客户端验证其合法性(如颁发机构、有效期)。 3. **生成会话密钥**:通过非对称加密交换密钥,后续通信使用对称加密。 --- ### 四、发送 HTTP 请求 1. **构造请求报文**: ```http GET /index.html HTTP/1.1 Host: example.com User-Agent: Chrome/... ``` 2. **传输数据**:通过已建立的 TCP 连接发送请求头和正文(如 POST 请求)。 --- ### 五、服务器处理请求 1. **反向代理**:Web 服务器(如 Nginx)接收请求,可能转发到应用服务器(如 Tomcat)。 2. **业务逻辑**:应用服务器执行代码(如查询数据库、调用 API)。 3. **生成响应**:服务器返回状态码(如 `200 OK`)和内容(如 HTML、JSON)。 --- ### 六、浏览器解析与渲染 1. **解析 HTML**:构建 DOM 树。 2. **加载资源**:下载 CSS、JavaScript 和图片等。 3. **执行脚本**:运行 JavaScript,修改 DOM/CSSOM。 4. **渲染页面**:合成布局(Layout)、绘制(Paint)到屏幕。 --- ### 七、连接释放 1. **四次挥手**: - 客户端发送 `FIN` 包。 - 服务器回复 `ACK` 包。 - 服务器发送 `FIN` 包。 - 客户端回复 `ACK` 包,连接关闭。 --- ### 流程图总结 $$ \begin{aligned} &\text{客户端} \xrightarrow{\text{DNS查询}} \text{IP地址} \xrightarrow{\text{TCP三次握手}} \text{服务器} \\ &\xrightarrow{\text{HTTPS握手}} \text{加密通道} \xrightarrow{\text{HTTP请求/响应}} \text{数据交互} \\ &\xrightarrow{\text{渲染}} \text{页面展示} \xrightarrow{\text{TCP四次挥手}} \text{连接终止} \end{aligned} $$ 此过程涉及网络协议栈、服务器架构和浏览器工作原理的协同,实际场景可能包含 CDN、负载均衡等优化环节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值