mybatis中动态代理存在的意义

  • 图示

  • 图示分析

    • 分层说明:界面层为第一层,业务逻辑层(接口层 + 实现层)为第二层,数据访问层(接口层 + 实现层)为第三层

    • 业务逻辑层和数据访问层:分别分两层来开发,是开发中的规范

      • 接口层:为了面向接口编程,使开发更加灵活
      • 实现层:落实具体功能,完成具体的实现
    • 调用规范:在每一层的实现层,用下一层的接口指向下一层的实现,通过调用该实现类的方法来完成功能

      • 例如,界面层的下一层为业务逻辑层,则在界面层的调用代码应为:业务逻辑层的接口指向业务逻辑层的实现,然后调用该实现类的方法

        UsersService uService = new UsersServiceImpl();
        uService.insert(XXXX);
  • mybatis框架中动态代理存在的意义

    • 但是,在mybatis框架中sql语句的执行是通过定位mapper.xml文件中的sql标签来实现的,而业务逻辑层的实现类无法使用上述"调用规范"

      • 原因:我们无法new出mapper.xml文件对象,这是一个".xml"文件,不是一个简单的实现类,也就无法使用该mapper.xml文件中的sql标签
    • 问题的本质:我们需要在业务逻辑实现层使用mapper.xml文件中的sql标签,调用其功能,但是又无法直接访问该mapper.xml文件
    • 使用动态代理解决需要访问mapper.xml文件,却又无法直接访问该mapper.xml文件的问题,这就是mybatis框架中动态代理存在的意义

mybatis中动态代理的实现规范

  • UsersMapper.xml文件与UsersMapper.java的接口必须位于同一目录下
  • UsersMapper.xml文件与UsersMapper.java的接口文件名必须一样,后缀随意
  • UsersMapper.xml文件中标签的id值与UsersMapper.java的接口中方法的名称完全一致
  • UsersMapper.xml文件中标签的parameterType属性值与UsersMapper.java的接口中方法的参数类型完全一致
  • UsersMapper.xml文件中标签的resultType属性值与UsersMapper.java的接口中方法的返回值类型完全一致
  • UsersMapper.xml文件中的namespace属性必须是接口的完全限定名称,例如:com.example.mapper.UsersMapper
  • 在SqlMapConfig.xml文件中注册mapper文件时,使用class="接口的完全限定名称",例如:class=com.example.mapper.UsersMapper

mybatis中动态代理访问的步骤

参考:mybatis 02: 添加并配置mybatis

  • 新建users表,插入测试数据
  • 新建maven工程
    • 修改目录结构
    • 修改pom.xml文件,添加依赖
    • 添加资源文件指定
  • 添加jdbc.properties文件到resources目录下
  • 添加SqlMapConfig.xml文件到resources目录下
<?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> <!-- 读取属性文件(jdbc.properties)-->
<properties resource="jdbc.properties"/> <!-- 设置日志输出-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings> <!-- 为实体类注册别名-->
<typeAliases>
<package name="com.example.pojo"/>
</typeAliases> <!-- 配置环境变量 -->
<environments default="develop">
<environment id="develop">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments> <!--注册mapper.xml文件-->
<mappers>
<mapper class="com.example.mapper.UsersMapper"/>
</mappers>
</configuration>
  • 添加实体类

  • 添加mapper文件夹,新建UsersMapper接口

    package com.example.mapper;
    
    import com.example.pojo.Users;
    
    import java.util.List;
    
    /**
    * 数据访问层的接口,定义对数据库完成的CRUD的操作
    */
    public interface UsersMapper {
    //获取全部用户信息
    List<Users> getAll();
    }
    • 在该文件夹下,新建UsersMapper.xml文件,完成对users表的CRUD操作
    <?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.UsersMapper">
    <!--
    //获取全部用户信息
    List<Users> getAll();
    -->
    <select id="getAll" resultType="users">
    select
    id, username, birthday, sex, address
    from
    users
    </select>
    </mapper>
  • 添加测试类,测试功能

mybatis借助动态代理实现对users表的CRUD操作

查询全部用户信息

  • 测试代码
package com.example.mapper;

import com.example.pojo.Users;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import java.io.IOException;
import java.io.InputStream;
import java.util.List; public class TestUsersMapper {
//SqlSession对象
SqlSession sqlSession; //获取SqlSession
@Before
public void getSqlSession() throws IOException {
//读取核心配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//获取SqlSession
sqlSession = factory.openSession();
} //归还SqlSession
@After
public void closeSession(){
sqlSession.close();
} @Test
public void testGetAll(){
//获取mybatis动态代理对象
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
//调用代理的功能
List<Users> users = usersMapper.getAll();
//输出查询结果
users.forEach(System.out::println);
}
}
  • 输出结果的部分内容
Checking to see if class com.example.pojo.Users matches criteria [is assignable to Object]
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections.
PooledDataSource forcefully closed/removed all connections. Opening JDBC Connection Created connection 1548946718. Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c530d1e] ==> Preparing: select id, username, birthday, sex, address from users
==> Parameters:
<== Columns: id, username, birthday, sex, address
<== Row: 1, 小涵, 2000-09-10, 2, 黑河市
<== Row: 2, 小王, 2001-07-12, 1, 芜湖市
<== Row: 3, 小张, 1999-02-22, 1, 长沙
<== Row: 4, 小吴, 2002-11-19, 1, 成都
<== Row: 5, 段, 2001-03-10, 1, 太原
<== Row: 6, 范成群, 2002-01-19, 1, 鲅鱼圈
<== Row: 7, 学委, 2001-05-13, 2, 平顶山市
<== Total: 7
Users{id=1, userName='小涵', birthday=Sun Sep 10 00:00:00 CST 2000, sex='2', address='黑河市'}
Users{id=2, userName='小王', birthday=Thu Jul 12 00:00:00 CST 2001, sex='1', address='芜湖市'}
Users{id=3, userName='小张', birthday=Mon Feb 22 00:00:00 CST 1999, sex='1', address='长沙'}
Users{id=4, userName='小吴', birthday=Tue Nov 19 00:00:00 CST 2002, sex='1', address='成都'}
Users{id=5, userName='段', birthday=Sat Mar 10 00:00:00 CST 2001, sex='1', address='太原'}
Users{id=6, userName='范成群', birthday=Sat Jan 19 00:00:00 CST 2002, sex='1', address='鲅鱼圈'}
Users{id=7, userName='学委', birthday=Sun May 13 00:00:00 CST 2001, sex='2', address='平顶山市'} Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c530d1e] Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c530d1e] Returned connection 1548946718 to pool. Process finished with exit code 0

mybatis 05: mybatis中的动态代理的更多相关文章

  1. mybatis源码学习: 动态代理的应用(慢慢改)

    动态代理概述 在学spring的时候知道使用动态代理实现aop,入门的列子:需要计算所有方法的调用时间.可以每个方法开始和结束都获取当前时间咋办呢.类似这样: long current=system. ...

  2. 从Mybatis源码理解jdk动态代理默认调用invoke方法

    一.背景最近在工作之余,把开mybatis的源码看了下,决定自己手写个简单版的.实现核心的功能即可.写完之后,执行了一下,正巧在mybatis对Mapper接口的动态代理这个核心代码这边发现一个问题. ...

  3. 使用Java中的动态代理实现数据库连接池

    2002 年 12 月 05 日 作者通过使用JAVA中的动态代理实现数据库连接池,使使用者可以以普通的jdbc连接的使用习惯来使用连接池. 数据库连接池在编写应用服务是经常需要用到的模块,太过频繁的 ...

  4. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  5. Spring AOP中的动态代理

    0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  Spring AOP中的动态代理机制 2.1  ...

  6. 转:Spring AOP中的动态代理

    原文链接:Spring AOP中的动态代理 0  前言 1  动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2  S ...

  7. java反射中的动态代理机制(有实例)

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  8. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  9. 动态代理(一)——JDK中的动态代理

    在开始动态代理的描述之前,让我们认识下代理.代理:即代替担任执行职务.在面向对象世界中,即寻找另一个对象代理目标对象与调用者交互.Java中分为静态代理和动态代理.这里对于静态代理不做详述.它们之间的 ...

  10. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

随机推荐

  1. JAVA数组案例!

    数组的用例 一.案例需求: 有这样的一个数组,元素是{68,27,95,88,171,996,51,210}.求出该数组中满足要求的元素和, 要求是:求和的元素个位和十位都不能是7,并且只能是偶数如何 ...

  2. CenterNet和CenterNet2笔记

    CenterNet和CenterNet2笔记 CenterNet是基于anchor-free的一阶段检测算法 CenterNet2是CenterNet作者基于两阶段的改进 CenterNet(Obje ...

  3. MySql笔记Ⅰ

    MySql part 1: 数据库概念 数据库:(DataBase, 简称DB):数据库中的数据按一定的数据模型组织.描述和储存,具有较小的冗余度.较高的数据独立性和易扩展性,并可为各种 用户共享 数 ...

  4. 当运行npm install 命令的时候带上ignore-scripts,会发生什么?

    摘要:运行npm install 命令的时候带上ignore-scripts, 可以避免一个恶意包里的病毒. 本文分享自华为云社区<运行npm install 命令的时候带上--ignore-s ...

  5. 名校AI课推荐 | UC Berkeley《人工智能导论》

    深度学习具备强感知能力但缺乏一定的决策能力,强化学习具备决策能力但对感知问题束手无策,因此将两者结合起来可以达到优势互补的效果,为复杂系统的感知决策问题提供了解决思路. 今天我们推荐这样一门课程--U ...

  6. python logging模块使用方法

    # -*- coding: utf-8 -*- # @ModuleName: logger # @Time: 2022/6/10 11:48 # @Author : Free-A # @Descrip ...

  7. SAP 查看在线用户

    SM04 可查看服务器全部客户端(Client)的用户的在线状态,并可以结束指定用户的会话状态,也就是强制踢出用户.

  8. ShardingSphere-proxy-5.0.0建立mysql读写分离的连接(六)

    一.修改配置文件config-sharding.yaml,并重启服务 # # Licensed to the Apache Software Foundation (ASF) under one or ...

  9. NC16564 [NOIP2012]借教室

    NC16564 [NOIP2012]借教室 题目 题目描述 ​ 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借 ...

  10. 《Domain Agnostic Learning with Disentangled Representations》ICML 2019

    这篇文章是ICML 2019上一篇做域适应的文章,无监督域适应研究的问题是如何把源域上训练的模型结合无lable的目标域数据使得该模型在目标域上有良好的表现.之前的研究都有个假设,就是数据来自哪个域是 ...