SSM——3.Mybatis的增删改查

2023-10-26

        

目录

1查询所有数据

2根据id进行查询

 3.插入一条数据

 4.获取插入数据的id

5.根据id进行删除

6.修改数据

7.小结


        前面实践篇我们讲了如何从零创建一个Mybatis项目,然后原理篇我们浅讲了一下Mybatis的实现原理及流程,今天,我们来详细讲一下Mybatis的语法规则。

        我们就安照原理篇写的书写顺序,然后根据实例,来讲解一下Mybatis的语法规则。

1查询所有数据

现在,我们要查询User表中的所有数据

我们在UserDao.xml文件中写下如下的sql语句:

<select id="findAll" resultType="com.qcby.entity.User">
        select * from user
   </select>

即如下图所示:

 说明:

第5行 namespace :写的是我们Userdao的地址,与相应的接口类进行连接

第7行 select:是查询关键字,表示语句是用来查询的,其他的比如删除,用delete;修改,用update;添加,用insert

第7行 id:是唯一标识符,可以理解为方法名,要与对应的接口类中的方法名相同(可以与相应的测试方法名不同)

第7行 resultType:指返回值类型,这里我们查询出来的是一条条user数据,所以用user对象来接收

现在,我们在接口类中写下如下内容:

public List<User> findAll();

即如下图所示:

说明:因为查询返回的是一条条user内容,所以我们用List<User>来接收返回值

现在,我们来写测试类:

public class UserTest {

    private InputStream in = null;
    private SqlSession session = null;
    private UserDao mapper = null;

    @Before  //前置通知, 在方法执行之前执行
    public void init() throws IOException {
        //加载主配置文件,目的是为了构建SqlSessionFactory对象
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //通过SqlSessionFactory工厂对象创建SqlSesssion对象
        session = factory.openSession();
        //通过Session创建UserDao接口代理对象
        mapper = session.getMapper(UserDao.class);
    }

    @After  //@After: 后置通知, 在方法执行之后执行 。
    public void destory() throws IOException {
        //释放资源
        session.close();
        in.close();
    }

    /**
     * 测试查询所有的方法
     */
    @Test
    public void findAll() throws IOException {
        List<User> users = mapper.findAll();
        for (User user:users) {
            System.out.println(user.toString());
        }
    }
}

即如下图所示:

 

说明:

第19行:我们创建一个io对象in,并对in赋值null

第20行:创建一个sqlSession对象session,赋值null 

第21行:创建接口代理对象,还是赋值null

第26行:利用io对象in,来加载sqlMapConfig.xml文件,使计算机可以读取mapper下的UserDao.xml文件

第28行:创建sqlSessionFactory对象,就是一个工厂,让工厂通过in来读取sqlMapConfig.xml文件

第30行:我们可以理解为打开工厂,并将其命名为session,也可以理解为第28行的factory是一个工厂模板,第30行是创建了一个实体化工厂对象,然后我们的一些操作是在这里进行的

第32行:通过session对象来创建UserDao接口代理对象。这里才是最关键的一步,因为这里出现了我们的代理对象(回想代理的基本思想)

第47行:创建User类型的列表users,通过代理对象来调用接口里面的findAll()方法

第48行:for循环,打印输出

第45行:@Test 表示这个一个测试方法,点击可以运行此方法

第23行:@Before 注解,表示下面的代码在Test之前运行

第35行:@After 注解,表示下面的代码在Test之后运行

第38行:关闭sqlSession工厂,释放资源

第39行:关闭io对象,释放资源

下面,我去配置一下sqlMapConfig.xml文件,如下图所示:

说明: 

第20行:是对mapper下的xml文件的引用。

好了,现在让我们回到测试方法来点击测试一下:

 当然,有点同学会出现这样的情况:

 上面是几行红色的警告,不用担心,我的其他文章会教大家解决。

现在,我们的第一条sql语句就执行成功了。

2根据id进行查询

下面我们来书写根据id进行查询的sql语句

首先,在我们的UserDao.xml中写下如下语句:

<select id="findById" parameterType="java.lang.Integer" resultType="com.qcby.entity.User">
        select * from user where id = #{id}
    </select>

即如下图所示:

 说明:

第11行 parameterType:指的是输入值的类型,可以理解为入参类型

第12行 id=#{id}:这里用的是#{},是用占位赋值的方式来拼接sql的,这是Mybatis参数注入的一种方式,后面会详细讲,暂时先记着这样用就行

下面,我们来写接口,如下图所示:

然后,我们来写测试方法:

 @Test
    public void findById(){
        User user=mapper.findById(3);
        System.out.println(user.toString());
    }

 即如下图所示:

 然后,点击测试运行:

 3.插入一条数据

老规矩,先写UserDao.xml文件中的方法,代码如下:

<insert id="insertUser" parameterType="com.qcby.entity.User">
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

截图如下:

 说明:

我们在写sql语句时,考虑的出参入参,是针对sql语句的,而不是针对接口中方法的。什么意思?以插入为例:插入数据,我们需要对数据赋值,这就是入参,但是插入的sql语句会返回什么?是一张表吗?不是;是一条数据吗?不是;是一个数子吗?不是;也就是说,当我们插入一条数据时,它是没有返回值的。所以,这里我们没有写出参,也就是resultType。但是换个角度想,我们执行这条插入语句时,会返回什么?Navicat会返回你插入的条数,也就是1。所以我们接口的返回参数类型就要定义为int型。

这里我们要区别:“我们查询 / 插入 / 删除 / 修改 一条语句时,需要什么?会返回什么?”根据这个,确定我们写sql语句时要定义的出参与入参。还有“当我们执行 查询 / 插入 / 删除 / 修改 语句时,会返回什么?”根据这个,可以在一些时候来确定我们写接口时定义返回参数的类型。这是比较绕的。我也是执行插入操作时才思考的。

下面,我们来看一下接口的书写(不给你们代码了,直接上图):

 注意那个int,结合上面写的,思考一下。

下面看测试方法的书写:

@Test
    public void insert(){
        User user = new User();
        user.setUsername("哈哈1");
        int code = mapper.insertUser(user);
        session.commit();
        System.out.println(code);

    }

截图如下:

 说明:

第65行:这里的session.commit()是做session提交的。我们在执行修改操作时(增,删,改,三种)需要进行数据的提交。记住就行,原理我也不太清楚。

最后,看一下结果:

 为了弄清那个出参与入参的东西,让我们直接在Navicat上运行一下插入操作,看下结果:

 关于这个出入参,和接口方法返回值的定义,我们需要好好思考一下

 4.获取插入数据的id

一样,先写UserDao.xml文件里面的方法,代码如下:

<insert id="insertGetId" parameterType="com.qcby.entity.User">
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

写完后的截图如下:

 说明:

第19行:和前面插入方法一样,不多讲

第20行:注意这里的关键字是“selectKey”,什么意思?查询关键字,表示这条语句就是查询关键字的;  “keyProperty”表示你的关键字是什么,我们当初在设计表的时候,是将id设为关键字的,所以后面写“id”;  “resultType”指的是返回值类型,前面讲过,不多说;  “order”指的是顺序,即这条语句执行的顺序是什么,我们这里是在插入数据之后获取它的id的,所以这条语句的顺序是在插入语句之后执行。

第21行:算是一种固定写法吧,记住就行

第23行,插入语句,没啥好说的

然后,我们来写接口(不给代码,直接给图):

 然后,我们来看一下测试方法(代码如下):

 @Test
    public void insertGetId(){
        User user = new User();
        user.setUsername("哈哈3");
        int code = mapper.insertGetId(user);
        //数据的修改,需要做session数据的提交
        session.commit();
        System.out.println(code); //code = 1
        //获取id
        System.out.println(user.getId());
    }

截图如下:

 然后,我们来看一下运行结果:

这里我们可以看到2个值,一个是code的值,为1,也是方法的返回值;第二个是插入数据的id,为32,是通过get方法得到的。

5.根据id进行删除

一样,我们先写UserDao.xml文件,代码如下:

<delete id="deleteById" parameterType="java.lang.Integer">
        delete from user where id = #{id}
    </delete>

截图如下:

 其实出入参和上面的插入操作基本一致

下面来写接口,如图:

 最后写测试文档,代码如下:

 @Test
    public void deleteById(){
        int code = mapper.deleteById(32);
        session.commit();
        System.out.println(code);
    }

截图如下:

 然后,我们执行一下,看下运行结果:

 这就没什么好说的了

6.修改数据

首先,我们来写UserDao.xml文件,代码如下:

<update id="update" parameterType="com.qcby.entity.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        where id= #{id}
    </update>

截图如下:

 然后,我们来写接口,截图如下:

然后,我们来写测试方法:

 最后,我们来看一下结果:

 一些理解:

我们能够发现,我们的插入与修改操作都是new了一个新对象,然后用新对象覆盖旧对象。插入就不多说什么了,这里说一下修改操作。我们在Navicat上执行修改操作时,感觉只是赋值就行,没什么特别的,而到这里,却要new新对象,我个人觉得这应该与实体类的包装有关。

7.小结

这里小结一下我们在增删改查中所用到的关键字

namespace:连接我们的对应的接口

id:唯一标识符,可以理解为方法名,要与接口中的方法名相同

resultType:返回值类型,确定时要根据sql语句考虑,而不是接口中的方法考虑

parameterType:可以理解为入参类型,即传给sql在值,也是根据sql来进行确定

selectKey:查询关键字,结合上面的例子进行分析

keyProperty:后面接关键字,与表有关

order:执行顺序,即在后面语句之前执行还是之后执行

#{}:这是用占位赋值的方式来拼接sql的,是Mybatis参数注入的一种方式。另外一种我们后面会讲并且会比较二者的不同。

        到这里,我们的增删改查操作全部完成,当然,肯定不全,但是大体不差多少,后面的具体问题就具体分析了。

        文中所写的一些个人理解如果有失偏颇,还请各位大佬指出!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SSM——3.Mybatis的增删改查 的相关文章

  • Java:扩展类并实现具有相同方法的接口

    可能无法完成以下操作 我收到编译错误 继承的方法 A doSomthing int 无法隐藏 B 中的公共抽象方法 public class A int doSomthing int x return x public interface
  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • 如何在java中将数组值排序为循环格式?

    我的数组值如下 String value 1 2 3 4 5 6 7 8 9 10 假设如果我将值 5 传递给 tat 数组 它应该按如下顺序排序 5 6 7 8 9 10 1 2 3 4 怎么办 有人帮忙吗 感谢你 你需要的就是所谓的轮换
  • Android中如何使用JNI获取设备ID?

    我想从 c 获取 IMEIJNI 我使用下面的代码 但是遇到了未能获取的错误cls 它总是返回NULL 我检查了环境和上下文 它们都没有问题 为什么我不能得到Context班级 我在网上搜索了一下 有人说我们应该使用java lang Ob
  • java inputstream 打印控制台内容

    sock new Socket www google com 80 out new BufferedOutputStream sock getOutputStream in new BufferedInputStream sock getI
  • 如何在单个查询中搜索 RealmObject 的 RealmList 字段

    假设我有一堂课 public class Company extends RealmObject private String companyId private RealmList
  • 断言 Kafka 发送有效

    我正在使用 Spring Boot 编写一个应用程序 因此要写信给 Kafka 我这样做 Autowired private KafkaTemplate
  • 将人类日期(当地时间 GMT)转​​换为日期

    我正在服务器上工作 服务器正在向我发送 GMT 本地日期的日期 例如Fri Jun 22 09 29 29 NPT 2018在字符串格式上 我将其转换为日期 如下所示 SimpleDateFormat simpleDateFormat ne
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 在Java中运行bat文件并等待

    您可能会认为从 Java 启动 bat 文件是一项简单的任务 但事实并非如此 我有一个 bat 文件 它对从文本文件读取的值循环执行一些 sql 命令 它或多或少是这样的 FOR F x in CD listOfThings txt do
  • Java继承,扩展类如何影响实际类

    我正在查看 Sun 认证学习指南 其中有一段描述了最终修饰符 它说 如果程序员可以自由地扩展我们所知的 String 类文明 它可能会崩溃 他什么意思 如果可以扩展 String 类 我是否不会有一个名为 MyString 的类继承所有 S
  • 蓝牙发送和接收文本数据

    我是 Android 开发新手 我想制作一个使用蓝牙发送和接收文本的应用程序 我得到了有关发送文本的所有内容逻辑工作 但是当我尝试在手机中测试它时 我看不到界面 这是Main Activity Code import android sup
  • Jetty、websocket、java.lang.RuntimeException:无法加载平台配置器

    我尝试在 Endpoint 中获取 http 会话 我遵循了这个建议https stackoverflow com a 17994303 https stackoverflow com a 17994303 这就是我这样做的原因 publi
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 使用 Elastic Beanstalk 进行 Logback

    我在使用 Elastic Beanstalk 记录应用程序日志时遇到问题 我正在 AWS Elastic Beanstalk 上的 Tomcat 8 5 with Corretto 11 running on 64bit Amazon Li
  • Spring @Cacheable 和 @Async 注解

    我需要缓存一些异步计算的结果 具体来说 为了克服这个问题 我尝试使用 Spring 4 3 缓存和异步计算功能 作为示例 我们采用以下代码 Service class AsyncService Async Cacheable users C
  • Hibernate 本机查询 - char(3) 列

    我在 Oracle 中有一个表 其中列 SC CUR CODE 是 CHAR 3 当我做 Query q2 em createNativeQuery select sc cur code sc amount from sector cost
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 由 Servlet 容器提供服务的 WebSocket

    上周我研究了 WebSockets 并对如何使用 Java Servlet API 实现服务器端进行了一些思考 我没有花费太多时间 但在使用 Tomcat 进行一些测试时遇到了以下问题 如果不修补容器或至少对 HttpServletResp

随机推荐

  • Docker搭建漏洞靶场(Vulhub、Vulnapp、Vulfocus)

    文章目录 vulhub 靶场搭建 简介 环境搭建过程 vulnapp靶场搭建 vulfocus靶场搭建 简介 环境搭建 vulhub 靶场搭建 简介 Vulhub是一个面向大众的开源漏洞靶场 无需docker知识 简单执行一条命令即可编译
  • 数据中心联盟第五批大数据产品评测结果出炉,腾讯云大数据斩获多个奖项

    欢迎大家前往腾讯云社区 获取更多腾讯海量技术实践干货哦 近日 在数据中心联盟组织的第五批大数据产品评测中 腾讯云大数据平台取得了两项第一名 特别在Hbase性能上有非常亮眼的表现 其他各项成绩也名列前茅 本月7日 中国通信标准化协会常务副秘
  • 以太坊学习-笔记1

    加密 以太坊有两种不同类型的账户 外部拥有账户 EOA 和合约 EOA 的以太坊地址是从密钥对的公钥部分生成的 以太坊使用的系统是基于公钥加密的系统 密钥是成对出现的 由一个私有 秘密 密钥和一个公共密钥组成 私钥提供对账户的控制权 公钥将
  • Java加密之IV

    AES是一种 分组密码 密码学中 分组 block 密码的工作模式 mode of operation 允许使用同一个分组密码密钥对多于一块的数据进行加密 并保证其安全性 分组密码自身只能加密长度等于密码分组长度的单块数据 若要加密变长数据
  • LeetCode 127. 单词接龙(C++)*

    思路 1 如果采用回溯法来的话会超时 2 这里采用构造图和广度优先遍历结合来实现 首先要构造图 需要将每个字符串对应一个数字id 然后边的构造使用矩阵来实现 这里采用将每一个字符串的id连接每个将该字符串的其中一个字符改为未知字符的字符串的
  • Python ffmpeg视频处理

    2 源码 coding utf 8 import ffmpeg import getpass import subprocess import matplotlib pyplot as plt import cv2 import numpy
  • android studio(自带SDK)安装教程

    下载网址 http www android studio org index php download hisversion 当下载为 exe程序时 直接双击 exe程序 之后点击Next 第一地址是安装路径 自己选择即可 第二个是SDK路
  • 手把手教你搭建Windows环境微信小程序的本地测试服务器

    Mac环境下 手把手教你搭建Mac环境微信小程序的本地测试服务器 问题的提出 Windows环境 方便快捷地搭建小程序的测试服务器 小程序对于网络请求的URL的特殊要求 不能出现端口号 不能用localhost 必须用https 主要步骤
  • elementUI侧边栏实现响应式,响应式侧边栏

    实现思路 准备两份aside侧边栏 借助display和媒体查询实现响应式 以下是完整代码
  • 初次使用vite新建项目报错

    第一次使用vite新建项目时报错 C Users AppData Roaming npm cache npx 13100 node modules create vite index js 4 import fs from node fs
  • 测试报告(进阶)

    功能测试可以手写一份测试报告 一 如何自动生成测试报告 unittest生成测试报告 测试用例 账号正确 密码错误 自己依照测试用例输入一组账号 点登录 会出现信息 密码错误 代码 import unittest import time f
  • vue 监听div宽高变化

    npm install element resize detector save import elementResizeDetectorMaker from element resize detector mounted const th
  • 如何使用chatglm-6b实现多卡训练

    首先先说ChatGLM 6b是支持多卡训练的 步骤如下 1 安装 NVIDIA CUDA Toolkit 要使用多卡训练 需要安装 CUDA Toolkit 可以在 NVIDIA 官网下载适用于操作系统的 CUDA 版本 2 确认所有的显卡
  • 实验四 MGRE与OSPF综合实验

    1 R6为ISP只能配置IP地址 R1 R5的环回为私有网段 2 R1 4 5为全连的MGRE结构 R1 2 3的星型的拓扑结构 R1为中心站点 3 所有私有网段可以互相通讯 私有网段使用OSPF完成 新建拓扑图 配置合理的IP R1 R2
  • 解决IDEA、PyCharm、PhpStorm及Android Studio中输入法卡住、光标不跟随的问题

    2017新版JetBrains全家桶下的各个软件都存在使用中文输入法时出现类似卡住 即光标不跟随的现象 解决办法 删除软件所在根目录下的jre或jre64文件夹 删除后软件会自动使用本机的jre 并可能提示jie已不是最新版 但不影响使用
  • 详解Vector

    目录 一 Vector介绍 二 源码解析 1 Vector实现的接口 2 Vector的构造方法 1 无参构造方法 2 带初始容量的构造方法 3 带初始容量和增量的构造方法 4 集合型构造方法 3 Vector中的变量 4 Vector主要
  • HttpRunner v4 一条用例是怎么被执行的

    HttpRunner 4 0版本 支持多种用例的编写格式 YAML JSON go test pytest 其中后面两种格式我们都知道通过调用测试函数执行 那YAML JSON这两种用例格式到底是怎样被运行的呢 下面我们一起分析一下 注意
  • zotero翻译、界面、笔记字体大小设置

    zotero翻译 界面 笔记字体大小设置 方式一 编辑器出设置 图中分别对应翻译 界面 笔记字体大小设置 方式二 图形界面设置
  • PC端本地存储方案,Windows和Mac双端通用方案

    功能要求 缓存数据 没有频繁的读写 存储服务端下发的数据 当数据有更新的时候 本地存储会进行更新 同时刷新内存 本地存储作为持久化储存方案 程序每次启动时会读取数据加载到内存 当数据有更新的时候 也会进行内存刷新 从需求解析 存储的特点是持
  • SSM——3.Mybatis的增删改查

    目录 1查询所有数据 2根据id进行查询 3 插入一条数据 4 获取插入数据的id 5 根据id进行删除 6 修改数据 7 小结 前面实践篇我们讲了如何从零创建一个Mybatis项目 然后原理篇我们浅讲了一下Mybatis的实现原理及流程