【Java闭关修炼】MyBatis-接口代理的方式实现Dao层

news2025/2/26 0:33:46

【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 mapper
        PUBLIC "-//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 {

    @Override
    public 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;
    }

    @Override
    public 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);

            // 通过工厂对象获取SqlSession
            sqlSession = 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;
    }


    // 新增学生对象
    @Override
    public 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);

            // 通过工厂对象获取SqlSession
            sqlSession = 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;
    }


    @Override
    public 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);

            // 通过工厂对象获取SqlSession
            sqlSession = 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;
    }

    @Override
    public 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);

            // 通过工厂对象获取SqlSession
            sqlSession = 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()方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C进阶】数据的存储

文章目录:star:1. 数据类型:star:2. 整形在内存中的存储2.1 存储规则2.2 存储模式2.3 验证大小端模式:star:3. 数据范围3.1 整形溢出3.2 数据范围的求解3.3 练习:star:4. 浮点型在内存中的存储4.1 浮点数的存储规则4.2 练习5. :star::star:总结(思维导图)⭐️1. 数据类型 在了…

独立产品灵感周刊 DecoHack #048 - 优秀独立开发产品推荐

如果有关注我的 Twitter 的朋友应该看到了&#xff0c;我上周末研究了两天 AI 画图&#xff0c;现在用 Ai 做图太强了&#xff0c;上周又升级 Stable Diffusion 玩了一下&#xff0c;和我去年试的时候相比强大了好多&#xff0c;而且插件LoRA模型玩法都还在快速迭代&#xff0c…

超详细解读!数据库表分区技术全攻略

更多内容可以关注微信公众号&#xff1a;老程序员刘飞 分区的定义 分区是一种数据库优化技术&#xff0c;它可以将大表按照一定的规则分成多个小表&#xff0c;从而提高查询和维护的效率。在分区的过程中&#xff0c;数据库会将数据按照分区规则分配到不同的分区中&#xff0…

【Linux】调试工具gdb的使用

环境&#xff1a;centos7.6&#xff0c;腾讯云服务器Linux文章都放在了专栏&#xff1a;【Linux】欢迎支持订阅&#x1f339;前言在前文&#xff0c;我们已经讲解了vim工具以及gcc/g的使用&#xff0c;我们可以进行编写代码以及编译代码了&#xff0c;但是还没有学习如何在Linu…

贪心--跳跃问题/拼接问题

跳跃问题 判断能否从数轴的最左端跳跃到最右边 变形&#xff1a;最少跳跃次数 45.跳跃游戏 题目链接 给定一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。 示…

博客界的至高神:属于自己的WordPress网站,你值得拥有!

【如果暂时没时间安装&#xff0c;可以直接跳转到最后先看展示效果】 很多朋友都想有一个对外展示的窗口&#xff0c;在那里放一些个人的作品或者其他想对外分享的东西。大部分人选择了在微博、公众号等平台&#xff0c;毕竟这些平台流量大&#xff0c;我们可以很轻易地把自己…

Jectpack -- Navigation了解与简单使用

简介 Navigation是一个可简化的Android导航的库和插件&#xff0c;换句话说&#xff0c;Navigation是用来规范管理Fragment的切换的&#xff0c;并且是通过可视化的方式来进行管理的。 ![[Pasted image 20230210083913.png]] 正常的跳转方法(其实有kotlin以后&#xff0c;代…

【性能测试基础】,从0到实战(手把手教,非常实用)

一、性能基础什么是性能测试--->本质?基于协议来模拟用户发送的请求&#xff08;业务模拟&#xff09;&#xff0c;对服务器形成一定负载。关注点&#xff1a;时间性能、空间性能与界面无关性能测试分类性能测试&#xff08;狭义&#xff09;性能测试方法是通过模拟生产环境…

【C++】多线程

多任务处理有两种形式&#xff0c;即&#xff1a;多进程和多线程。 基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行 文章目录1. 多线程介绍2. Windows多线程1. 多线程介绍 每一个进程&#xff08;可执行程序&#xff09;都有一个主线…

AcWing1027. 方格取数

AcWing1027. 方格取数设有 NN 的方格图&#xff0c;我们在其中的某些方格中填入正整数&#xff0c;而其它的方格中则放入数字0。如下图所示&#xff1a;某人从图中的左上角 A 出发&#xff0c;可以向下行走&#xff0c;也可以向右行走&#xff0c;直到到达右下角的 B 点。在走过…

SpringBoot+Vue前后端分离管理系统02:前端

前端环境搭建 1、node环境 C:\Windows\system32>node -v v12.13.0C:\Windows\system32>npm -v 6.12.0 2、下载vue-admin-template 官网&#xff1a;介绍 | vue-element-admin 项目初始化 1、安装依赖 在刚才下载的vue-admin-template-4.4.0目录下以管理员方式运行c…

Robot Framework + Selenium2Library环境下,结合Selenium Grid实施分布式自动化测试

最近一段时间&#xff0c;公司在推行自动化测试流程&#xff0c;本人有幸参与了自定义通用控件的关键字封装和脚本辅助编写、数据驱动管理、测试用例执行管理等一系列工具软件的研发工作&#xff0c;积累了一些经验&#xff0c;在此与大家做一下分享&#xff0c;也算是做一个总…

SQL零基础入门学习(四)

SQL零基础入门学习&#xff08;三&#xff09; SQL INSERT INTO 语句 INSERT INTO 语句用于向表中插入新记录。 SQL INSERT INTO 语法 INSERT INTO 语句可以有两种编写形式。 第一种形式无需指定要插入数据的列名&#xff0c;只需提供被插入的值即可&#xff1a; INSERT …

ImageCombiner设计源码详解

前言在前面的博客中介绍了一款Java的海报生成器ImageCombiner,原文地址&#xff1a;拿来就用的Java海报生成器ImageCombiner&#xff08;一&#xff09;&#xff0c;在博文中简单介绍了一下代码以及一个真实的生成案例。但是对源码的介绍不多&#xff0c;本文就针对源码进行深入…

vs2022 x64 C/C++和汇编混编

vs2022环境x64 C/C和汇编混编vs64位程序不支持__asm内嵌汇编&#xff0c;需要单独编写汇编源文件示例如下1、新建空的win32项目&#xff0c;新建main.cpp&#xff0c;示例代码如下2、新建asm64.asm汇编源文件&#xff0c;示例代码如下3、编译器配置&#xff0c;选择x64&#xf…

【编程入门】应用市场(uni-app版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 《N种编程语言做个记事本》 目标 为编程初学者打造入门学习项目&#xff0c;使…

华为OD机试 - 最短木板长度(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

PowerJob容器的前世,容器是如何产生,如何上传到Server上去的

这不仅仅是一篇PowerJob源码分析的文章&#xff0c;还有很多的java基础知识&#xff0c;在实践中学习效果更好&#xff0c;感兴趣就留下来交流一下吧。 power容器虽然说是容器&#xff0c;但并不是docker容器&#xff0c;仅仅就是java的jar包 &#xff0c;可以通过框架下载一套…

手工测试混了5年,年底接到了被裁员的消息....

大家都比较看好软件测试行业&#xff0c;只是因为表面上看起来&#xff1a;钱多事少加班少。其实这个都是针对个人运气好的童人才会有此待遇。在不同的阶段做好不同阶段的事情&#xff0c;才有可能离这个目标更近&#xff0c;作为一枚软件测试人员&#xff0c;也许下面才是我们…

阿里5年,一个女工对软件测试的理解

成为一个优秀的测试工程师需要具备哪些知识和经验&#xff1f; 针对这个问题&#xff0c;可以直接拆分以下三个小问题来详细说明&#xff1a; 1、优秀软件测试工程师的标准是什么&#xff1f; 2、一个合格的测试工程师需要具备哪些专业知识&#xff1f; 3、一个合格的测试工程…