【java web篇】MyBatis实现增删改查

news2024/9/29 11:23:05

📋 个人简介

  • 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
  • 📝 个人主页:馆主阿牛🔥
  • 🎉 支持我:点赞👍+收藏⭐️+留言📝
  • 📣 系列专栏:java 小白到高手的蜕变🍁
  • 💬格言:要成为光,因为有怕黑的人!🔥
    请添加图片描述

目录

    • 📋 个人简介
  • 前言
    • 查询
      • 查看详情
      • 条件查询
      • 动态条件查询
        • 多条件动态查询
        • 单条件动态查询
    • 添加和修改
      • 添加
      • 修改
    • 删除
    • 使用注解方实增删改查
  • 结语

前言

上一节主要写了MyBatis入门案例以及Mapper代理,这节主要结合前面的知识实现MyBatis的增删改查,涉及动态sql的使用!

查询

查询所有在入门案例里已经举例过了,这里不再写案例!

查看详情

首先补充mybatis-config.xml核心配置文件:
在这里插入图片描述
可以添加类型别名,然后对应的sql映射文件里resultType就可以直接简写返回值类型了,而且不区分大小写!
在这里插入图片描述
下面进入案例:

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws IOException {
        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 执行sql (只有这块需要手写,其他步骤直接复制)
        MemberMapper memberMapper = sqlSession.getMapper(MemberMapper.class);

        int id = 2;
        Member member = memberMapper.selectById(id);
        System.out.println(member);

        //4. 释放资源
        sqlSession.close();
    }

在这里插入图片描述
这里要对参数占位符作出说明:

mybatis提供了两种参数占位符:

  • #{} :执行SQL时,会将 #{} 占位符替换为?,将来自动设置参数值。从上述例子可以看出使用#{} 底层使用的是PreparedStatement
  • ${} :拼接SQL。底层使用的是 Statement ,会存在SQL注入问题。

接下来来看另为的问题:

在这里插入图片描述
这里sql语句>是没有问题的,但小于号<是xml标签的开始符号,会报错!
在这里插入图片描述
有两种解决方式:

方式一:使用<的转义字符:

<select id="selectById" resultType="member">
     select * from member where id &lt; #{id}
</select>

方式二:使用CDATA区:

<select id="selectById" resultType="member">
   select * from member where id 
    <![CDATA[
        <  
    ]]> 
    #{id}
</select>

CDATA区里的字符会当做纯文本处理!

条件查询

sql映射文件:MemberMapper.xml
在这里插入图片描述
而该功能有2个参数,我们就需要考虑定义接口时,参数应该如何定义。Mybatis针对多参数有多种实现:

1.使用 @Param(“参数名称”) 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位!

在这里插入图片描述

int age = 28;
 String name = "张";
 // 模糊匹配,参数处理
 name = '%' + name + '%';

 List<Member> members = memberMapper.selectByCondition(age,name);
 System.out.println(members);

在这里插入图片描述

2.将多个参数封装成一个 实体对象 ,将该实体对象作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容} 时,里面的内容必须和实体类属性名保持一致。

在这里插入图片描述

int age = 28;
String name = "张";
// 模糊匹配,参数处理
name = '%' + name + '%';
// 封装对象
Member member = new Member();
member.setAge(age);
member.setName(name);

List<Member> members = memberMapper.selectByCondition(member);
System.out.println(members);

3.将多个参数封装到map集合中,将map集合作为接口的方法参数。该方式要求在映射配置文件的SQL中使用 #{内容}时,里面的内容必须和map集合中键的名称一致。

int age = 28;
String name = "张";
// 模糊匹配,参数处理
name = '%' + name + '%';
// 封装map对象
HashMap map = new HashMap();
map.put("age",age);
map.put("name",name);
List<Member> members = memberMapper.selectByCondition(map);
System.out.println(members);

动态条件查询

多条件动态查询

上述功能实现存在很大的问题,假如我们在做开发遇到用户在输入条件时,这个需求肯定不会所有的条件都填写,一种是对于不同填写情况判断,用不同的sql,但这样比较麻烦,写的sql也多,所以MyBatis提供了动态sql,可以帮助我们一条语句就搞定这种搜索查询情况!

<!--    条件查询-->
 <select id="selectByCondition" resultType="member">
     select *
     from member
     where age = #{age}
     and name like #{name};
 </select>

上面的意思就是说,这样的sql查询必须是两个或者多个参数都有才能查出来,而我们的需求是两个甚至多个条件任选都满足查询,这就是动态sql,只需一条sql就搞定,那下面就来看看怎么搞!

<!--    动态条件查询-->
<select id="selectByCondition" resultType="member">
    select *
    from member
    where
    <if test="age != null">
        age = #{age}
    </if>
    <if test="name != null and name != ''">
        and name like #{name}
    </if>
</select>

用动态sql的if标签即可满足!if标签可以判断参数是否有值,使用test属性判断!
在这里插入图片描述
可以看到此时只有一个条件,依然满足!
但是如果是第一个条件没有,此时就会出问题:

在这里插入图片描述
报错也很明显,多了一个and,对于这种情况有两种解决方式!

方式一:不常用

```xml
<!--    动态条件查询-->
<select id="selectByCondition" resultType="member">
    select *
    from member
    where 1=1
    <if test="age != null">
        and age = #{age}
    </if>
    <if test="name != null and name != ''">
        and name like #{name}
    </if>
</select>

加一个1=1恒等式不就行了,但我们sql可不这么写,所以用第二个方法!

方法二:使用where 标签

  • 作用:
    • 替换where关键字
    • 会动态的去掉第一个条件前的 and
    • 如果所有的参数没有值则不加where关键字
<select id="selectByCondition" resultType="member">
     select *
     from member
     <where>
         <if test="age != null">
             age = #{age}
         </if>
         <if test="name != null and name != ''">
             and name like #{name}
         </if>
     </where>
</select>

在这里插入图片描述

单条件动态查询

还有一个情况就是我们的条件只有一个,但我们不知道是哪一个条件!

这就需要使用到 choose(when,otherwise)标签 实现, 而 choose 标签类似于Java 中的switch语句。

<!--    单条件动态条件查询-->
<select id="selectByCondition" resultType="member">
    select *
    from member
    where 
    <choose> <!--相当于switch -->
        <when test="age != null">  <!--相当于case -->
            age = #{age}
        </when>
        <when test="name != null and name != ''">
            and name like #{name}
        </when>
    </choose>
</select>

但这样有个问题是当单个条件都没有时会多出一个where,此时跟上面一样,有两种解决方案!

方案一:借助otherwise多写一个恒等式

<!--    单条件动态条件查询-->
 <select id="selectByCondition" resultType="member">
     select *
     from member
     where
     <choose> <!--相当于switch -->
         <when test="age != null">  <!--相当于case -->
             age = #{age}
         </when>
         <when test="name != null and name != ''">
             and name like #{name}
         </when>
         <otherwise>  <!--相当于default -->
             1 = 1
         </otherwise>  
     </choose>
 </select>

方案二 :用where标签

<!--    单条件动态条件查询-->
<select id="selectByCondition" resultType="member">
    select *
    from member
    <where>
        <choose> <!--相当于switch -->
            <when test="age != null">  <!--相当于case -->
                age = #{age}
            </when>
            <when test="name != null and name != ''">
                and name like #{name}
            </when>
        </choose>
    </where>
</select>

在这里插入图片描述

添加和修改

添加

sql映射文件:

<insert id="add">
   insert into member (name,gender,age)
    values (#{name},#{gender},#{age});
</insert>

mapper接口

void add(Member member);

主要代码:

package com.aniu;

import com.aniu.mapper.MemberMapper;
import com.aniu.pojo.Member;
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;

/**
 * @Author:Aniu
 * @Date:2023/4/13 22:07
 * @description 增加
 */
public class MyBatisDemo4 {
    public static void main(String[] args) throws IOException {
        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // SqlSession sqlSession = sqlSessionFactory.openSession(true);  // 开启自动提交
        //3. 执行sql (只有这块需要手写,其他步骤直接复制)
        MemberMapper memberMapper = sqlSession.getMapper(MemberMapper.class);
        String name = "阿牛";
        String gender = "男";
        int age = 21;
        Member member = new Member();
        member.setGender(gender);
        member.setName(name);
        member.setAge(age);

        memberMapper.add(member);
        //手动提交事务
        sqlSession.commit();
        //4. 释放资源
        sqlSession.close();
    }
}

在这里插入图片描述

在数据添加成功后,有时候需要获取插入数据库数据的主键(主键是自增长)。

此时直接从pojo类中获取不到,sql映射文件里的insert语句要添加两个属性:

<insert id="add" useGeneratedKeys="true" keyProperty="id">
   insert into member (name,gender,age)
    values (#{name},#{gender},#{age});
</insert>

修改

有修改部分字段,有全部修改,这里依旧使用动态sql来实现全部需求

sql映射文件:

<update id="update">
  update member
   <set>
       <if test="name != null and name != ''">
           name = #{name},
       </if>
       <if test="gender != null and gender != ''">
           gender = #{gender},
       </if>
       <if test="age != null">
           age = #{age}
       </if>
   </set>
   where id = #{id};
</update>

依然有逗号问题,所以用set标签处理

mapper接口:

int update(Member member);

主要实现:

public class MyBatisDemo4 {
    public static void main(String[] args) throws IOException {
        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // SqlSession sqlSession = sqlSessionFactory.openSession(true);  // 开启自动提交
        //3. 执行sql (只有这块需要手写,其他步骤直接复制)
        MemberMapper memberMapper = sqlSession.getMapper(MemberMapper.class);
        String name = "aniu";
        int id = 5;
        Member member = new Member();
        member.setName(name);
        member.setId(id);
        int count = memberMapper.update(member);
        System.out.println(count);
        //手动提交事务
        sqlSession.commit();
        //4. 释放资源
        sqlSession.close();
    }
}

在这里插入图片描述

删除

根据id删除:

void deleteById(int id);
<delete id="deleteById">
	delete from member where id = #{id};
</delete>

批量删除:

/**
* 批量删除
*/
void deleteByIds(int[] ids);

编写SQL语句:
在 MemberMapper.xml 映射配置文件中编写删除多条数据的 statement 。

编写SQL时需要遍历数组来拼接SQL语句。Mybatis 提供了 foreach 标签供我们使用:

  • foreach 标签:用来迭代任何可迭代的对象(如数组,集合)。
    • collection 属性:mybatis会将数组参数,封装为一个Map集合。
      默认:array = 数组
      使用@Param注解改变map集合的默认key的名称。
    • item 属性:本次迭代获取到的元素。
    • separator 属性:集合项迭代之间的分隔符。 foreach 标签不会错误地添加多余的分隔符。也就是最 后一次迭代不会加分隔符。
    • open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
    • close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次
<delete id="deleteByIds">
    delete from member where id
    in
    <foreach collection="array" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
    ;
</delete>

使用@Param注解改变map集合的默认key的名称后:

void deleteByIds(@Param("ids") int[] ids);

在这里插入图片描述

主要测试代码:

package com.aniu;

import com.aniu.mapper.MemberMapper;
import com.aniu.pojo.Member;
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;

/**
 * @Author:Aniu
 * @Date:2023/4/14 19:36
 * @description 批量删除
 */
public class MyBatisDemo5 {
    public static void main(String[] args) throws IOException {
        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // SqlSession sqlSession = sqlSessionFactory.openSession(true);  // 开启自动提交
        //3. 执行sql (只有这块需要手写,其他步骤直接复制)
        MemberMapper memberMapper = sqlSession.getMapper(MemberMapper.class);
        int[] ids = {1,2,3};
        memberMapper.deleteByIds(ids);
        //手动提交事务
        sqlSession.commit();
        //4. 释放资源
        sqlSession.close();
    }
}

在这里插入图片描述

使用注解方实增删改查

使用注解开发会比配置文件开发更加方便。如下就是使用注解进行开发:

@Select(value = "select * from member where id = #{id}")
public Member select(int id);

注意:

  • 注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的 statement。

Mybatis 针对 CURD 操作都提供了对应的注解,已经做到见名知意。如下:

  • 查询 :@Select
  • 添加 :@Insert
  • 修改 :@Update
  • 删除 :@Delete

注意:在官方文档中 入门 中有这样的一段话:

在这里插入图片描述
所以,注解完成简单功能,配置文件完成复杂功能。这里对注解的使用不再举例!

结语

如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。

🏰系列专栏
👉flask框架入门到实战
👉软磨 css
👉硬泡 javascript

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

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

相关文章

Git使用教程:从入门到精通(以Gitee为例)

一、前言 Git是一款分布式版本控制系统&#xff0c;可以帮助开发者更好地管理代码。在众多的Git平台中&#xff0c;Gitee是国内最受欢迎的Git平台之一。本篇文章将介绍如何使用Git进行代码管理&#xff0c;并以Gitee为例&#xff0c;详细讲解Git的基本操作和常用命令。 二、深入…

JS学习笔记(一)

从编程模式看&#xff1a;JS是结构化、事件驱动的动态语言&#xff0c;支持声明式和指令式两种模式&#xff0c;所以JS是一个多模式的语言。面向对象和函数式是常用的两种模式。 函数式编程 基本概念&#xff1a;函数是什么&#xff1f;函数是数据集到目标的一种关系。在函数式…

Windows逆向安全(一)之基础知识(十)

汇编一维数组 之前的文章学习过了四种基本类型&#xff1a;char short int long的汇编表示形式 因为它们的数据宽度都小于等于32位&#xff0c;所以都可以只用一个通用寄存器来存储 接下来的数组显然就无法只用一个通用寄存器就可以存储了 在学习数组之前&#xff0c;再学习…

云可见性和端口欺骗:已知的未知

与所有技术一样&#xff0c;新工具是建立在以前的基础上的迭代&#xff0c;经典的网络日志记录和指标也不例外。 网络流量的工具、检测和监控在私有云和内部部署中几乎没有变化。今天使用的许多日志和指标已有将近二十年的历史&#xff0c;最初是为了解决计费等问题而设计的。…

Node 08-express框架

express 介绍 express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架&#xff0c;官方网址&#xff1a; https://www.expressjs.com.cn/ 简单来说&#xff0c;express 是一个封装好的工具包&#xff0c;封装了很多功能&#xff0c;便于我们开发 WEB 应用(HTTP 服务)…

强训之【查找组成一个偶数最接近的两个素数和二进制插入】

目录 1.查找组成一个偶数最接近的两个素数1.1题目1.2思路1.2.1 暴力解法1.2.2 取中判断 1.3代码1.3.1暴力求解代码1.3.2 取中判断代码 2.二进制插入2.1题目2.2思路2.3代码 3.选择题 1.查找组成一个偶数最接近的两个素数 1.1题目 链接: link 描述 任意一个偶数&#xff08;大于…

Android学习Day1

Android学习笔记 了解Android 的结构ActivityAndroid中的布局了解安卓的结构ActivityAndroid中的布局代码展示(登录界面的实现)&#xff1a;实现效果&#xff1a;代码展示&#xff08;注册界面的实现&#xff09;实现效果一些之前学习的笔记end 了解Android 的结构 Activity …

服务(第八篇)location和rewrite

常用的Nginx正则表达式: 从功能看&#xff0c;rewrite和location似乎有点像&#xff0c;都能实现跳转&#xff0c;主要区别在于rewrite是在同一域名内更改获取资源的路径&#xff0c;而location是对一类路径做控制访问或反向代理&#xff0c;还可以proxy_pass到其他机器。 rew…

企业如何挑选设备管理系统?

在当今高度竞争的市场环境中&#xff0c;企业需要不断提高生产效率、确保设备的可靠性和安全性以降低运营成本。设备管理系统&#xff08;Equipment Management System&#xff0c;简称EMS&#xff09;是一种帮助企业实现这些目标的有力工具。本文将为您解析企业如何挑选合适的…

提高亚马逊等其他跨境平台的曝光率方法有哪些?

很多卖家都会想尽办法提高自己店铺的曝光率&#xff0c;但有些新手卖家可能不知道曝光率意味着什么 简单来说&#xff0c;曝光率是指你自己的店铺和产品被呈现给顾客的次数&#xff0c;一般来说&#xff0c;曝光率通常决定了你店铺的总流量&#xff0c;交易总量&#xff0c;订…

PM866 3BSE050200R1高压变频器的四种控制方法

PM866 3BSE050200R1高压变频器的四种控制方法 高压变频器装置指驱动输入电源为6&#xff0c;000V或10KV的电机装置&#xff0c;高压变频器一般主要有下列几种方案选择&#xff1a; 一、直接高压控制&#xff08;高成本&#xff09; 目前以采用美国罗宾康类似的无谐波变频技术&a…

凌恩生物美文分享|3月客户文章盘点——累计IF=105,平均IF=8.08

凌恩生物以打造国内一流生物公司为目标&#xff0c;在科研测序领域深耕不辍&#xff0c;吸纳多名在生物信息高级技术人员的加盟&#xff0c;参与并完成多个高科技项目。现已在宏组学、基因组、表观遗传以及蛋白代谢等多组学及联合分析领域积累了深厚经验&#xff0c;打造出成熟…

ASP.NET Core MVC 从入门到精通之布局

随着技术的发展&#xff0c;ASP.NET Core MVC也推出了好长时间&#xff0c;经过不断的版本更新迭代&#xff0c;已经越来越完善&#xff0c;本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容&#xff0c;适用于初学者&#xff0c;在校毕业生&#xff0c…

核心业务4:标的管理

核心业务4:标的管理 1.标的管理流程图 2.数据库表设计 3.前端逻辑设计 4.后端逻辑设计 5.标的放款TODO 核心业务4:标的管理 1.标的管理流程图 ①上一个核心业务通过审核借款申请结束

mybatis-plus的代码生成器的应用

目录 1.工程引入mybatis-plus3-generator代码生成器2.只需要关注mybatis-plus-config.properties然后生成代码3.分别添加依赖解决报错4.加入其它配置然后测试效果 3.4版本 1.工程引入mybatis-plus3-generator代码生成器 mybatis-plus3-generator放入项目工程中&#xff0c;父工…

JeecgBoot 3.5.1 版本发布,开源的企业级低代码平台

项目介绍 JeecgBoot是一款企业级的低代码平台&#xff01;前后端分离架构 SpringBoot2.x&#xff0c;SpringCloud&#xff0c;Ant Design&Vue3&#xff0c;Mybatis-plus&#xff0c;Shiro&#xff0c;JWT 支持微服务。强大的代码生成器让前后端代码一键生成! JeecgBoot引领…

kafka manager服务部署

1.配置一台centos7主机或者直接在kafka服务主机上部署也可以&#xff0c;关闭firewalld和selinux服务 2.安装java环境(需要jdk11以上) 参考&#xff1a;jdk1.8环境配置_Apex Predator的博客-CSDN博客 3.从github上下载编译好的cmak压缩包(下载最新版本的3.0.0.6) 下载地址&a…

Gradio 部署工具保姆级教程来了,以图生图,画你所想

2023 年以来国内各家大厂竞相发布大模型&#xff0c;AIGC 的热度来到了前所未有的高度&#xff0c;AI 绘画在国际艺术博览会上频频夺冠&#xff0c;数字艺术的新纪元正在逐渐展开。你是否也想与顶尖技术人员一起&#xff0c;参与到 AIGC 的浪潮中呢&#xff1f; 2023 PaddlePa…

source insight4.0使用技巧总结

一、技巧1&#xff1a;查看函数调用关系 步骤 1&#xff1a;在主菜单中点击下图中的按钮 图 1 打开relation界面 步骤 2&#xff1a;在弹出的relation界面点击“设置”按钮&#xff0c; 图2 点击“设置”按钮 步骤3&#xff1a; 在“设置”界面中&#xff0c;“Levels”选择…

一文详解一致性协议

目录 一致性协议 2PC二阶段提交 二阶段提交存在的问题&#xff1a; 3PC 三阶段提交 优点 Paxos算法 流程演变 Paxos优缺点 活锁问题 ZAB协议(Fast Paxos) 一致性协议 事务需要跨多个分布式节点时&#xff0c;为了保证事务的ACID特性&#xff0c;需要选举出一个协调者…