MyBatis操作数据库常用用法总结1

文章目录

      • 1.单表查询
        • 1.1返回所有的表记录
        • 1.2根据id查找结果
        • 1.3根据名字查找结果
      • 2.单表修改
        • 2.1修改密码
      • 3.单表删除
        • 3.1根据id删除信息
      • 4.单表增加(根据业务情况返回)
        • 4.1添加返回影响的行数
        • 4.2添加返回影响行数和id
      • 5.多表查询(多)
        • 一对一
        • 多对多
      • 参数占位符#{}和${}区别:
        • like查询
      • sql注入

说明:
1.这里写完interface和xml中的内容,使用数据库和单元测试进行了检验
2. Mybatis拿参数的方式和SpringBoot一样,最通用的就是在加个@Param注解在这里插入图片描述
对应的sql中的xml就需要用${ord}或者#{ord}的方式获取
3.如果传对象,一般不用再要@Param注解,如UserEntity user,这个时候xml写法:
直接写对象的名字,直接写属性名(框架帮助我们自动完成了映射)

4.多表删除和多表增加都可以在Serive层进行任务编排,一个一个属性的注入,对应的完成任务,所以mapper这一层只需要考虑单表的增删改查和多表的联合查询问题
5.数据库如果使用拼接,java这边使用大小驼峰的话,spring框架可以自动映射

1.单表查询

1.1返回所有的表记录

1)在UserMapper中建立对应的接口

package com.example.demo.mapper;
import com.example.demo.entity.UserEntity;
//名字是历史原因(以前的类可能还是ibatis这个名)
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
//mapper层就是数据持久层,叫做repostories也行
@Mapper//表明是组件之一
public interface UserMapper {
    //单表查询
    List<UserEntity> getAll();
}

2)在UserMapper.xml中实现完成的方法:

<?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.demo.mapper.UserMapper">
    <!--    1.namespace:要实现的类包名+接口名-->
    <!--    2.id:实现的对应接口里的方法名-->
    <!--实现什么方法,返回值-->
    <select id="getAll" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo
<!--        不用写分号-->
    </select>
</mapper>

3)返回UserMapper中,点中方法,右键生成测试方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IVMI4zqU-1691473708859)(F:\typora插图\image-20230515171810665.png)]

4)补充测试方法

  • 为类加上@SpringBootTest注解
  • 采用DI的方式注入UserMapper对象
package com.example.demo.mapper;

import com.example.demo.entity.UserEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest//表示当前单元测试是运行在Spring Boot环境下的
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void getAll() {
        List<UserEntity> list=userMapper.getAll();
        System.out.println(list);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mRPXJbyq-1691473708860)(F:\typora插图\image-20230515173216919.png)]

在配置完对应的配置项,我们可以看到下边的测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wlAzd0Uz-1691473708860)(F:\typora插图\image-20230515173432418.png)]

下边是数据库中的验证结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LhFGdpac-1691473708861)(F:\typora插图\image-20230515173727230.png)]

1.2根据id查找结果

1)mapper中添加方法声明

UserEntity getUserById(@Param("id") Integer id);

2)xml文件中添加方法实现:

<select id="getUserById" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where id=#{id}
</select>

3)生成、补充、运行测试代码,去数据库进行验证

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mzvLJ6U3-1691473708861)(F:\typora插图\image-20230515172100379.png)]

在配置完对应的配置项,我们可以看到下边的测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MjodaacV-1691473708861)(F:\typora插图\image-20230515172909652.png)]

下边是数据库中对应的验证结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uip5Vf0f-1691473708862)(F:\typora插图\image-20230515173001207.png)]

1.3根据名字查找结果

1)mapper中添加方法声明

UserEntity getUserByUsername(@Param("username") String username);

2)xml文件中添加方法实现:

    <select id="getUserByUsername" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where username=#{username}
    </select>

3)生成、补充、运行测试代码,去数据库进行验证

    @Test
    void getUserByUsername() {
//        直接替换没有单引号
        UserEntity user=userMapper.getUserByUsername("zhangsan");
        System.out.println(user);
    }

在配置完对应的配置项,我们可以看到下边的测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KVgmX8q4-1691473708862)(F:\typora插图\image-20230515175628146.png)]

下边是数据库中对应的验证结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EVK6Y5o0-1691473708863)(F:\typora插图\image-20230515175709082.png)]

2.单表修改

这里使用的标签是update,这里只有一个id属性名,没有namespace其他的,至于resultType,因为方法那里默认就是返回int类型,所以可以省略不写。

一般来说修改用户名和密码是比较高频的操作,所以我们这里以修改密码为例。

2.1修改密码

代码实现步骤:
mapper中写接口方法–》xml中写对应sq语句—>添加对应的测试方法,进行校验–》数据库校验(略)

//修改密码
int updatePassword(@Param("id")Integer id,
                   @Param("password")String password,
                    @Param("newPassword")String newPassword);
    <update id="updatePassword">
<!--        默认返回值就是int-->
<!--        select和update标签的区别-->
        update userinfo set password=#{newPassword}
            where id=#{id} and password=#{password}
    </update>
//默认污染,但是可以设置成不污染的
@Transactional//不会污染了==》会进行事务回滚
@Test
void updatePassword() {
    int result=userMapper.updatePassword(1,"admin","abcdef");
    System.out.println("修改"+result);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ttkM2UWH-1691473708863)(F:\typora插图\image-20230515180219234.png)]

记得加@Transactional注解,不污染数据库,他可以加载方法上,也可以加载类上。

3.单表删除

这里使用的delete标签,只需要设置一个参数id,和update一样,默认返回受影响的行数。

3.1根据id删除信息

//删除用户
int delById(@Param("id")Integer id);
<delete id="delById">
    delete from userinfo where id=#{id}
</delete>
@Transactional
@Test
void delById() {
    int result=userMapper.delById(1);
    System.out.println("删除"+result);
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JKzpkfKD-1691473708864)(F:\typora插图\image-20230515180440846.png)]

4.单表增加(根据业务情况返回)

这里使用的是insert标签,和前边两个标签一样,默认返回受影响的行数。

4.1添加返回影响的行数

以登录场景为例,推荐传递对象而不是传递两个参数,方便后续维护,否则会影响整个调用链。

//添加用户
int addUser(UserEntity user);
<insert id="addUser">
	insert into userinfo(username,password) values(#{username0},#{password})
<insert>
@Transactional
@Test
void addUser() {
        UserEntity user = new UserEntity();
        user.setUsername("zhangsan");
//        user.setPassword("123456");
        int result = userMapper.addUser(user);
        System.out.println("添加:" + result);
    }

如果一批用户需要插入,看后边的动态sql,使用list

4.2添加返回影响行数和id

需要使用insert标签中userGeneratedKeys和keyProperty属性,第一个是是否生成自增主键,设置成true,第二个是将返回的主键id放到我们想要的变量中。

//添加用户,并返回id
int addUserGetId(UserEntity user);
<insert id="addUserGetId" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo(username,password) values(#{username},#{password})
</insert>
@Test
void addUserGetId() {
        UserEntity user = new UserEntity();
        user.setUsername("lisi");
//        user.set("123456");
        int result = userMapper.addUserGetId(user);
        System.out.println("添加结果:" + result);
        System.out.println("ID:" + user.getId());
    }

5.多表查询(多)

一对一

使用最多的就是left join或者right join,将查询后的结果重命名
一般实体类和数据库表是一致的,如果还要其他的,需要创建扩展类,然后继承上一层类。

@Data
public class ArticleInfoVO extends ArticleInfo {
    private String username;

    @Override
    public String toString() {
        return "ArticleInfoVO{" +
                "username='" + username + '\'' +
                "} " + super.toString();
    }
    //通过看字节码知道
}

以查询用户指定文章详情为例

// 查询文章详情
    ArticleInfoVO getDetail(@Param("id") Integer id);
<select id="getDetail" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.*,u.username from articleinfo a
        left join userinfo u on u.id=a.uid
        where a.id=#{id}
    </select>
 @Test
    void getDetail() {
        ArticleInfoVO articleInfoVO = articleMapper.getDetail(1);
        System.out.println(articleInfoVO);
        System.out.println("title:" + articleInfoVO.getTitle());
    }

多对多

上边一个文章 我们规定只能一个作者,但是一个作者可以有多个文章,需要进行多对多的表查询
主表应该是文章,返回的结果应该是一个文章的列表。

 List<ArticleInfoVO> getListByUid(@Param("uid") Integer uid);
<select id="getListByUid" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.*,u.username from articleinfo a
        left join userinfo u on u.id=a.uid
        where a.uid=#{uid}
    </select>
 @Test
    void getListByUid() {
        Integer uid = 1;
        List<ArticleInfoVO> list = articleMapper.getListByUid(uid);
//stream(语法糖)使用并行方式打印,顺序不确定(不需要自己开线程池),可以通过字节码看
        list.stream().parallel().forEach(System.out::println);
//      使用串行方式  
		list.stream().forEach(System.out::println);
    }

参数占位符#{}和${}区别:

#{}:原理是预编译处理。MyBatis处理#{}会将sql中的#{}替换成?号,使用Preparement的set方法赋值。
: 原 理 是 字 符 串 直 接 替 换 。 M y B a t i s 处 理 {}:原理是字符串直接替换。MyBatis处理 MyBatis{}会将它替换成变量的值。
在这里插入图片描述

共同点:都可以正确处理数值型参数。

#{}优缺点:优点可以有效防止SQL注入,提高系统安全性;缺点就是当java代码中参数名和数据库关键字相同时,会报错,那个时候考虑sql内置的concat方法。

例如:select * from userinfo order by id desc(比如tb或者pdd需要按照什么样的规则进行有限展示商品asc还是desc),此时就需要使用$

${}:优点可以解决关键字与sql语句关键字相同的问题,缺点解决非数据类型数据比较麻烦,有安全问题,通常是登录场景,有sql注入问题。

但是即使是上边的场景也是需要参数可以被枚举的,是可控的,不过不建议用这种方法,最好在Controller层Service层就能进行确定,做好了服务编排,提高安全性

结论:用于查询的字段,尽量使用#{}预编译处理的方式,尤其是的时候非数据类型的,否则不仅可能会有sql注入的问题,还有sql语句中缺少对应的引号。

like查询

当参数为非数据类型时,like使用#{}会报错,因为#{}实现原理是预编译,
最终这部分就是’%‘username’’%’
而我们又不想要sql注入,这里的解决方案就是使用concat方法:

<select id="getListByName" resultType="com.example.demo.entity.UserEntity">
        select * from userinfo where username like concat('%',#{username},'%')
    </select>
    @Test
    void getListByName() {
        String username = "zhang";
        List<UserEntity> list = userMapper.getListByName(username);
        list.stream().forEach(System.out::println);
    }

sql注入

使用了不符合要求的代码查到了本不该查到的代码。最典型的便是’or 1= 1’

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【容器化】Oceanbase镜像构建及使用

通过该篇文章可以在国产X86-64或ARM架构上构建商业版oceanbase&#xff0c;只需要替换pkg安装包即可。下面截图主要以国产X86-64安装为例&#xff0c;作为操作截图&#xff1a; 镜像构建目录说明 pkg:用来存放安装包及脚本&#xff0c;抛出rpm其他是脚步&#xff0c;这些rpm包…

伪原创神码ai怎么样【php源码】

这篇文章主要介绍了python汉化补丁包下载&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 火车头采集ai伪原创插件截图&#xff1a; ** Spyder汉化&#xff08;python汉化&…

解锁滴滴ES的性能潜力:JDK 17和ZGC的升级之路

前文介绍了滴滴自研的ES强一致性多活是如何实现的&#xff0c;其中也提到为了提升查询性能和解决查询毛刺问题&#xff0c;滴滴ES原地升级JDK17和ZGC&#xff0c;在这个过程中我们遇到了哪些问题&#xff0c;怎样解决的&#xff0c;以及最终上线效果如何&#xff0c;这篇文章就…

软考高级之系统架构师之数据通信与计算机网络

概念 OSPF 在划分区域之后&#xff0c;OSPF网络中的非主干区域中的路由器对于到外部网络的路由&#xff0c;一定要通过ABR(区域边界路由器)来转发&#xff0c;既然如此&#xff0c;对于区域内的路由器来说&#xff0c;就没有必要知道通往外部网络的详细路由&#xff0c;只要由…

[系统安全] 五十二.DataCon竞赛 (1)2020年Coremail钓鱼邮件识别及分类详解

您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列。因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全、逆向分析和恶意代码检测,“系统安全”系列文章会更加聚焦,更加系…

MyCat配置rule.xml、server.xml讲解

1. rule.xml分片规则配置文件 rule.xml中配置的主要就是拆分表的规则&#xff0c;rule.xml中主要包含两类标签 tableRule 和Function。 tableRule标签里面主要配置我们的分片规则&#xff0c;Function里面涉及的是分片规则里面所涉及的java类&#xff0c;都是在function中配置…

学习笔记-JAVAJVM-JVM的基本结构及概念

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 原资料地址&#xff1a;课程资料 什么是JVM 原文连接&#xff1a; 原文连接 JVM是J…

Unity游戏源码分享-精品即时战略游戏_官网60美刀素材

Unity游戏源码分享-精品即时战略游戏_官网60美刀素材 下载地址&#xff1a;https://download.csdn.net/download/Highning0007/88204017

2023年10款常用的Mac工具合集

Typora Typora 是一款由 Abner Lee 开发的轻量级 Markdown 编辑器&#xff0c;与其他 Markdown 编辑器不同的是&#xff0c;Typora 没有采用源代码和预览双栏显示的方式&#xff0c;而是采用所见即所得的编辑方式&#xff0c;实现了即时预览的功能&#xff0c;但也可切换至源代…

关于Postman如何配置随请求携带token

文章目录 一些吐槽实际应用 一些吐槽 首先吐槽一下 postman官网的文档说明&#xff0c;真是乱七八糟&#xff0c;一点都不清晰&#xff0c;能不能好好写用户手册啊&#xff08;比如把用户都当作初始小白&#xff09; 然后吐槽一下网上铺天盖地让我写js脚本应用全局access toke…

uniapp开发小程序-分包(微信错误码:800051)

在使用uniapp开发小程序时&#xff0c;上传的时候因为文件过大&#xff0c;显示上传失败。 以下是开发过程中遇到的问题及解决方法&#xff1a; 1. 问题一&#xff1a;因为文件过大&#xff0c;显示上传失败 ①尝试过把本地使用的图片压缩到最小&#xff1b; ②把图片转换为网…

火山引擎联合Forrester发布《中国云原生安全市场现状及趋势白皮书》,赋能企业构建云原生安全体系

国际权威研究咨询公司Forrester 预测&#xff0c;2023年全球超过40%的企业将会采用云原生优先战略。然而&#xff0c;云原生在改变企业上云及构建新一代基础设施的同时&#xff0c;也带来了一系列的新问题&#xff0c;针对涵盖云原生应用、容器、镜像、编排系统平台以及基础设施…

ThinkPHP6企业OA办公系统

有需要请加文章底部Q哦 可远程调试 ThinkPHP6企业OA办公系统 一 介绍 勾股OA基于ThinkPHP6开发&#xff0c;前端Layui&#xff0c;数据库mysql&#xff0c;是一款实用的企业办公系统。可多角色登录&#xff0c;集成了系统设置、人事管理、消息管理、审批管理、日常办公、客户…

机器学习深度学习——常见循环神经网络结构(RNN、LSTM、GRU)

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——RNN的从零开始实现与简洁实现 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章…

4用opencv玩转图像2

opencv绘制文字和几何图形 黑色底图 显示是一张黑色图片 使用opencv画圆形 #画一个圆 cv2.circle(imgblack_img,center(400,400),radius100,color(0,0,255),thickness10) 画实心圆 只需要把thickness-1。 cv2.circle(imgblack_img,center(500,600),radius50,color(0,0,255),t…

JS逆向系列之猿人学爬虫第11题 - app抓取 - so文件协议破解

题目地址 http://match.yuanrenxue.com/match/11这是个app题目,先下载下来安装到测试手机上 安装完成后的app界面长这样 打开之后是这样的: 要求已经简单明了了。 二话不说先反编译app 不出意外的是没出意外,源代码里面没啥混淆,所有东西都展示的明明白白的。 "…

Apache Maven:从构建到部署,一站式解决方案

目录 一、Maven介绍 1. Maven是什么&#xff1f; 2.Maven的作用&#xff1f; 二、Maven仓库介绍 2.1 库的分类 三、Maven安装与配置 3.1 Maven安装 3.2 Maven环境配置 3.3 仓库配置 四、Eclipse与Maven配置 五、Maven项目测试 5.1 新建Maven项目步骤及注意事项 5.…

【LeetCode】236. 二叉树的最近公共祖先、 JZ36 二叉搜索树与双向链表

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 236. 二叉树的最近公共祖先 236. 二叉树的最近公共祖先 题目描述&#xff1a; 给定一个二叉树…

为MySQL新增一张performance_schema表 | StoneDB 技术分享会 #4

StoneDB开源地址 https://github.com/stoneatom/stonedb 设计&#xff1a;小艾 审核&#xff1a;丁奇、李浩 编辑&#xff1a;宇亭 作者&#xff1a;王若添 中国科学技术大学-软件工程-在读硕士、StoneDB 内核研发实习生 performance_schema 简介 MySQL 启动后会自动创建四…

中睿天下入选河南省网信系统2023年度网络安全技术支撑单位

近日&#xff0c;河南省委网信办发布了“河南省网信系统2023年度网络安全技术支撑单位名单”&#xff0c;中睿天下凭借出色的网络安全技术能力和优势成功入选。 本次遴选由河南省委网信办会同国家计算机网络与信息安全管理中心河南分中心&#xff08;以下简称安全中心河南分中心…