【Java闭关修炼】MyBatis-接口代理的方式实现Dao层
【Java闭关修炼】MyBatis-接口代理的方式实现Dao层
- 实现规则
- 代码实现
- 代理对象分析
- 接口代理方式小结
实现规则

- 映射配置文件中的名称空间必须和Dao层接口的全类名相同
- 映射配置文件的增删改查标签的id属性必须和Dao层接口方法的参数相同
- 映射配置文件中的增删改查标签的parameterType属性必须和Dao层接口方法的参数相同
- 映射配置文件中的增删改查标签中的resultType属性必须和Dao层接口方法的返回值相同
代码实现
-
删除mapper层接口的实现类
-
修改映射配置文件
-
修改service层接口的实现类 采用接口代理方式实现功能
-
mapper层接口
package com.itheima.mapper;import com.itheima.bean.Student;import java.util.List;/*持久层接口*/// 接口的名称要和namespace一样
public interface StudentMapper {//查询全部public abstract List<Student> selectAll();//根据id查询public abstract Student selectById(Integer id);//新增数据public abstract Integer insert(Student stu);//修改数据public abstract Integer update(Student stu);//删除数据public abstract Integer delete(Integer id);//多条件查询public abstract List<Student> selectCondition(Student stu);//根据多个id查询public abstract List<Student> selectByIds(List<Integer> ids);
}
- 映射配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--mapper:核心根标签namespace属性:名称空间
--><!--名称空间要和接口的路径保持一致-->
<mapper namespace="com.itheima.mapper.StudentMapper"><sql id="select" >SELECT * FROM student</sql><!--select:查询功能的标签id属性:唯一标识resultType属性:指定结果映射对象类型 返回值类型parameterType属性:指定参数映射对象类型--><!-- id必须和方法名保持一致--><select id="selectAll" resultType="student"><include refid="select"/></select><select id="selectById" resultType="student" parameterType="int"><include refid="select"/> WHERE id = #{id}</select><insert id="insert" parameterType="student">INSERT INTO student VALUES (#{id},#{name},#{age})</insert><update id="update" parameterType="student">UPDATE student SET name = #{name},age = #{age} WHERE id = #{id}</update><delete id="delete" parameterType="int">DELETE FROM student WHERE id = #{id}</delete><select id="selectCondition" resultType="student" parameterType="student"><include refid="select"/><where><if test="id != null">id = #{id}</if><if test="name != null">AND name = #{name}</if><if test="age != null">AND age = #{age}</if></where></select><select id="selectByIds" resultType="student" parameterType="list"><include refid="select"/><where><foreach collection="list" open="id IN (" close=")" item="id" separator=",">#{id}</foreach></where></select>
</mapper>
- StudentServiceImpl
package com.itheima.service.impl;import com.itheima.bean.Student;
import com.itheima.mapper.StudentMapper;
import com.itheima.service.StudentService;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;
/*业务层实现类*/
public class StudentServiceImpl implements StudentService {@Overridepublic List<Student> selectAll() throws IOException {List<Student> students = null;SqlSession sqlSession = null;InputStream is = null;// 没有了持久层实现对象 只有持久层的接口try{// 加载核心配置文件is = Resources.getResourceAsStream("MyBatisConfig.xml");// 返回一个字节输入流对象// 获取sqlSession工厂对象SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);// 通过工厂对象获取SqlSession对象sqlSession = build.openSession(true);// 代表自动提交事务// 获取StudentMapper接口的实现类对象// 父类的接口指向实现类对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 通过实现类对象调用方法 接受结果students = mapper.selectAll();// 释放资源// 返回结果}catch(Exception e){e.printStackTrace();}finally {// 释放资源if(sqlSession != null){sqlSession.close();}if(is != null){is.close();}}// 返回结果return students;}@Overridepublic Student selectById(Integer id) throws IOException {// 根据id来查询对象Student stu = null;SqlSession sqlSession = null;InputStream is = null;try{// 加载核心配置文件is = Resources.getResourceAsStream("MyBatisConfig.xml");//获取工厂对象SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);// 通过工厂对象获取SqlSessionsqlSession = build.openSession(true);// 代表自动提交事务// 获取StudentMapper接口的实现类对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 通过实现类对象调用方法 接受结果stu = mapper.selectById(id);// 获取学生对象}catch (Exception e){e.printStackTrace();}finally {if(sqlSession != null){sqlSession.close();}if(is != null){is.close();}}// 获取学生对象return stu;}// 新增学生对象@Overridepublic Integer insert(Student stu) throws IOException {// 根据id来查询对象Integer result = null;SqlSession sqlSession = null;InputStream is = null;try{// 加载核心配置文件is = Resources.getResourceAsStream("MyBatisConfig.xml");//获取工厂对象SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);// 通过工厂对象获取SqlSessionsqlSession = build.openSession(true);// 代表自动提交事务// 获取StudentMapper接口的实现类对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 通过实现类对象调用方法 接受结果result = mapper.insert(stu);// 返回影响的行数}catch (Exception e){e.printStackTrace();}finally {if(sqlSession != null){sqlSession.close();}if(is != null){is.close();}}// 获取学生对象return result;}@Overridepublic Integer update(Student stu) throws IOException {// 根据id来查询对象Integer result = null;SqlSession sqlSession = null;InputStream is = null;try{// 加载核心配置文件is = Resources.getResourceAsStream("MyBatisConfig.xml");//获取工厂对象SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);// 通过工厂对象获取SqlSessionsqlSession = build.openSession(true);// 代表自动提交事务// 获取StudentMapper接口的实现类对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 通过实现类对象调用方法 接受结果result = mapper.update(stu);// 返回影响的行数}catch (Exception e){e.printStackTrace();}finally {if(sqlSession != null){sqlSession.close();}if(is != null){is.close();}}// 获取学生对象return result;}@Overridepublic Integer delete(Integer id) throws IOException {// 根据id来查询对象Integer result = null;SqlSession sqlSession = null;InputStream is = null;try{// 加载核心配置文件is = Resources.getResourceAsStream("MyBatisConfig.xml");//获取工厂对象SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);// 通过工厂对象获取SqlSessionsqlSession = build.openSession(true);// 代表自动提交事务// 获取StudentMapper接口的实现类对象StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 通过实现类对象调用方法 接受结果result = mapper.delete(id);// 返回影响的行数}catch (Exception e){e.printStackTrace();}finally {if(sqlSession != null){sqlSession.close();}if(is != null){is.close();}}// 获取学生对象return result;}
}
代理对象分析

接口代理方式小结
-
接口代理方式可以让我们之编写接口即可,而实现类对象由MyBatis生成
-
实现规则
- 映射配置文件中的名称空间必须和Dao层接口的全类名相同
- 映射配置文件中的增删改查标签的id属性必须和Dao层接口的方法名相同
- 映射配置文件中的增删改查标签的parameterType属性必须和Dao层接口方法的参数相同
- 映射配置文件中的增删改查标签的resultType属性必须和Dao层接口方法的返回值相同
-
获取动态代理对象
- SqlSession功能类中的getMapper()方法
相关文章:
【Java闭关修炼】MyBatis-接口代理的方式实现Dao层
【Java闭关修炼】MyBatis-接口代理的方式实现Dao层实现规则代码实现代理对象分析接口代理方式小结实现规则 映射配置文件中的名称空间必须和Dao层接口的全类名相同映射配置文件的增删改查标签的id属性必须和Dao层接口方法的参数相同映射配置文件中的增删改查标签的parameterTyp…...
2022年网络安全政策态势分析与2023年立法趋势
近日,公安部第三研究所网络安全法律研究中心与 360 集团法务中心联合共同发布了《全球网络安全政策法律发展年度报告(2022)》。《报告》概览2022年全球网络安全形势与政策法律态势,并对2023年及后续短期内网络安全政策、立法趋势进…...
使用vmware制作云平台redhat7.9镜像模板
一、概述 1.1 redhat7.9 定制镜像上传到云平台。 这个制作镜像得方式适用于多种iso 镜像。 将iso 镜像通过vmware 创建出一台虚机,对虚机做一些基础配置。在虚机上安装kvm 虚拟化得工具, 将iso 镜像在导入虚机种通过kvm创建一下虚机, 虚机创…...
OpenCV基础(28)使用OpenCV进行摄像机标定Python和C++
摄像头是机器人、监控、太空探索、社交媒体、工业自动化甚至娱乐业等多个领域不可或缺的一部分。 对于许多应用,必须了解相机的参数才能有效地将其用作视觉传感器。 在这篇文章中,您将了解相机校准所涉及的步骤及其意义。 我们还共享 C 和 Python 代码以…...
APB总线详解及手撕代码
本文的参考资料为官方文档AMBA™3 APB Protocol specification文档下载地址: https://pan.baidu.com/s/1Vsj4RdyCLan6jE-quAsEuw?pwdw5bi 提取码:w5bi APB端口介绍介绍总线具体握手规则之前,需要先熟悉一下APB总线端口,APB的端口…...
【Linux/Windows】源文件乱码问题解决方法总结
🐚作者简介:花神庙码农(专注于Linux、WLAN、TCP/IP、Python等技术方向)🐳博客主页:花神庙码农 ,地址:https://blog.csdn.net/qxhgd🌐系列专栏:Linux技术&…...
Python 四大主流 Web 编程框架
目前Python的网络编程框架已经多达几十个,逐个学习它们显然不现实。但这些框架在系统架构和运行环境中有很多共通之处,本文带领读者学习基于Python网络框架开发的常用知识,及目前的4种主流Python网络框架:Django、Tornado、Flask、Twisted。 …...
学UI设计,可以向哪些方向发展?该怎么学?
1、什么是UI设计?UI设计,全称 User Interface,翻译成中文意思叫做用户界面设计。2、UI设计的类型UI设计按用户和界面来分可分成四种UI设计。分别是移动端UI设计,PC端UI设计,游戏UI设计,以及其它UI设计。第一…...
【C++】初识CC++内存管理
前言 我们都知道C&C是非常注重性能的语言,因此对于C&C的内存管理是每一个C/C学习者必须重点掌握的内容,本章我们并不是深入讲解C&C内存管理,而是介绍C&C内存管理的基础知识,为我们以后深入理解C&C内存管理做铺…...
Nacos快速使用指南
简单例子:springboot快速集成nacos官方github文档命名空间是绝对隔离的。group之间可以通过配置实现跨 group访问配置中心Nacos config官方文档应用级别的默认配置文件名(dataId)dataId 的完整格式如下:${prefix}-${spring.profil…...
复旦发布国内首个类ChatGPT模型MOSS,和《流浪地球》有关?
昨晚,复旦大学自然语言处理实验室邱锡鹏教授团队发布国内首个类ChatGPT模型MOSS,现已发布至公开平台https://moss.fastnlp.top/ ,邀公众参与内测。 MOSS和ChatGPT一样,开发的过程也包括自然语言模型的基座训练、理解人类意图的对…...
国家级高新区企业主要经济指标(2012-2021年)
数据来源:国家统计局 时间跨度:2012-2021 区域范围:全国(及各分类统计指标) 指标说明:手工提取最新的中国统计年鉴数据中各个excel指标表,形成各个指标文件的多年度数据,便于多年…...
SpringBoot2核心技术-核心功能【05、Web开发】
目录 1、SpringMVC自动配置概览 2、简单功能分析 2.1、静态资源访问 1、静态资源目录 2、静态资源访问前缀 2.2、欢迎页支持 2.3、自定义 Favicon 2.4、静态资源配置原理 3、请求参数处理 0、请求映射 1、rest使用与原理 2、请求映射原理 1、普通参数与基本注解 …...
2021-03 青少年软件编程(C语言)等级考试试卷(六级)解析
2021-03 青少年软件编程(C语言)等级考试试卷(六级)解析T1. 生日相同 2.0 在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的名字,出生月日。试找出所有生日相同的学生。 时间限制:1000 内存限制:65536 输入 第一行为整数n,表示有n个学生,n …...
数据库的多租户隔离
数据库的多租户隔离有三种方案 1、独立数据库 一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,成本也最高 优点:为不同的租户提供独立的数据库,有助于简化数据模型的扩展设计,满足不同租…...
网络输入分辨率是否越大越好
目标检测比如 yolov5,训练输入图像大小默认是 640*640,这个是不是越大训练的效果越好 ? 这个肯定不是的。而且,如果仅调整输入图像的分辨率,不改变网络结构的话,检测准确率反而会下降的。首先,…...
离线采集普遍解决方案
简介 使用Datax每日全量相关全量表,使用Maxwell增量采集到Kafka然后到Flume然后到Hdfs。 DataX全量 生成模板Json gen_import_config.py # codingutf-8 import json import getopt import os import sys import MySQLdb#MySQL相关配置,需根据实际情…...
SAP ABAP 数据类型P类型详解
ABAP中比较难以理解的是P类型的使用,P类型是一种压缩类型,主要用于存储小数,定义时要指定字节数和小数点位数,定义语法如下: DATA: name(n) TYPE P decimals m,n代表字节数,最大为16,m是小…...
应用沙盒seccomp的使用
应用沙盒原理参考https://zhuanlan.zhihu.com/p/513688516 1、什么是Seccomp? seccomp 是 secure computing 的缩写,其是 Linux kernel 从2.6.23版本引入的一种简洁的 sandboxing 机制。 系统调用: 在Linux中,将程序的运行空间分为内核与用户空间(内核态和用户态),在逻辑…...
C++项目——高并发内存池(2)——thread_cache的基础功能实现
1.并发内存池concurrent memory pool 组成部分 thread cache、central cache、page cache thread cache:线程缓存是每个线程独有的,用于小于64k的内存的分配,线程从这里申请内存不需要加锁,每个线程独享一个cache,这…...
DevOps工具链集成:GitLab CI、Jenkins与Argo CD如何选?
DevOps工具链集成:GitLab CI、Jenkins与Argo CD如何选? 在DevOps实践中,工具链的选型直接影响交付效率与系统稳定性。GitLab CI、Jenkins和Argo CD作为主流工具,分别覆盖持续集成(CI)、持续交付࿰…...
运算放大器与比较器的本质区别及应用指南
1. 运算放大器与比较器的本质区别在电子电路设计中,运算放大器(Op-Amp)和电压比较器(Comparator)是两种极为常见却又经常被混淆的器件。它们在外观符号上几乎一模一样:都有五个引脚——正负电源端、同相与反…...
4个维度解析Steam Achievement Manager:开源工具如何重塑游戏成就管理体验
4个维度解析Steam Achievement Manager:开源工具如何重塑游戏成就管理体验 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 一、困境诊断&#…...
理视康新零售系统开发要点
业务模式设计新零售模式需整合线上线下渠道,构建会员体系、分销机制与数据中台。通过小程序、APP或H5实现线上商城,线下门店采用智能硬件(如AR试戴、智能货架)提升体验。结合LBS技术实现附近门店导流,支持到店自提或同…...
最后的GIL堡垒正在崩塌:现在不掌握这6种无锁Python并发安全范式,你的微服务将在Q3大规模core dump
第一章:GIL消亡史与无锁Python并发的必然性Python 的全局解释器锁(GIL)自1991年诞生起,便成为 CPython 解释器中一道不可逾越的并发屏障。它确保同一时刻仅有一个线程执行 Python 字节码,虽简化了内存管理与引用计数实…...
VideoSrt:零基础视频字幕自动化解决方案
VideoSrt:零基础视频字幕自动化解决方案 【免费下载链接】video-srt-windows 这是一个可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具。 项目地址: https://gitcode.com/gh_mirrors/vi/video-srt-windows 视频创作者的效率痛点:…...
AVR机器人固件基座:负熵架构与确定性调度
1. 项目概述“Negentropic Base”是一个面向AVR微控制器平台的嵌入式固件基础框架,专为移动机器人(尤其是轮式探测车、自主巡线小车、轻量级自主导航平台)设计。其名称中的“Negentropic”(负熵)并非玄学术语ÿ…...
SerialLCD库深度解析:SerLCD v2.5串口LCD驱动实践
1. SerialLCD 库技术解析:面向嵌入式系统的 SparkFun SerLCD v2.5 串口 LCD 驱动深度实践 1.1 背景与工程定位 SerialLCD 是一个专为 SparkFun SerLCD v2.5 硬件模块设计的轻量级串口 LCD 控制库,其原始实现源自 Arduino.cc Playground 社区维护的 Ser…...
WebDAV网盘横向评测:从个人备份到多端同步的实战指南
1. WebDAV网盘入门:为什么你需要它? 刚接触WebDAV时,我和大多数人一样疑惑:明明有那么多现成的网盘,为什么还要折腾这个?直到有次出差,急需修改存放在某商业网盘里的设计方案,却发现…...
PCIe设备树深度解析:从RK3588实例看Linux内核地址与中断映射(九)
1. PCIe设备树基础概念与RK3588实战背景 第一次接触PCIe设备树配置时,我被那些密密麻麻的十六进制数字和嵌套属性搞得头晕眼花。直到在RK3588平台上实际调试PCIe设备时,才真正理解设备树如何成为连接硬件与操作系统的桥梁。PCIe设备树不同于普通外设的简…...
