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

news2024/11/25 2:25:54

文章目录

      • 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’

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

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

相关文章

网易云信回声消除量化评估方法

背景 随着现代通信技术的发展&#xff0c;语音通信成为了人们生活中不可或缺的一部分。然而&#xff0c;环境噪声和回声等因素对语音通信质量产生了不良影响&#xff0c;降低了通信效率和用户体验&#xff0c;声学回声消除技术的应用变得越来越重要。如何评估回声消除的效果也变…

详解如何计算字符中的字节数

文章目录 字符概念转义 进制的表示前缀区分后缀区分 什么是ASCII产生表述局限性字节计算 什么是Unicode编码方式UCS-2UCS-4 实现方式UTF的字节序和BOM字节计算 JavaScript中使用字符字符使用缺陷规避字符使用缺陷 MIME 编码Base64编码字节计算QP(Quote-Printable) 总结 字符概念…

进阶-LayUI的基本必知入门教程使用3-layui-laydate选择的值怎么获取?苟日新一刻钟总结反观:

1 效果镇楼&#xff1a; 对于layui框架的刚接触没几天&#xff0c;但是您的年轻同事为啥能搞出来功能啊&#xff01;&#xff1f; 到您就不行了呢&#xff1f; 这就是您对您饭碗的态度了吗&#xff01; 但是&#xff0c;是您尽力了&#xff0c;还能说明啥子问题&#xff1f; 就…

SOLIDWORKS自动标注插件

在设计工作中&#xff0c;三维模型设计好之后&#xff0c;还要创建二维工程图&#xff0c;用来指导加工生产。二维图出图的过程是一个非常枯燥的过程&#xff0c;而且还需要根据公司规范来进行尺寸标注、公差标注等&#xff0c;所以有时候&#xff0c;可能建模只用了几分钟&…

在UOS系统中管理ORACLE数据库

在明确了“数字中国”建设战略后。自主创新与国产化已成为我国实现科技强国、经济强国的发展趋势与行业共识。 即信息技术应用创新产业&#xff0c;简称“信创”。 而现有的国产操作系统&#xff0c;虽然已日趋成熟&#xff0c;但因为很多应用软件由国外垄断&#xff0c;因此…

一键获取数百张免费商用人脸!AI人脸生成器来袭

随着科技的发展&#xff0c;人工智能正在渗透到生活的各个角落&#xff0c;设计行业也不例外。在网页、APP、PPT 等界面设计中&#xff0c;设计师经常需要插入真实的人脸素材&#xff0c;以增强作品的真实感和场景化。但是获取素材既不容易&#xff0c;质量和价格也难免成为设计…

PK Nounique CASCADE DROP INDEX keep index

Explicit Control Over Indexes when Creating, Disabling, or Dropping PK/Unique Constraints (Doc ID 139666.1)​编辑To Bottom PURPOSEIn Oracle 9i, the DBA has an explicit control over how indexes are affectedwhile creating, disabling, or dropping Primary Ke…

【网络基础实战之路】基于BGP协议连接三个AS区域的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 【网络基础实战之路】基于…

网页版的微信客户管理系统是怎样的?

登录账号密码&#xff1a; 微信扫码登录到系统上&#xff1a; 支持多个微信号登录到系统&#xff0c;聚合管理聊天&#xff0c;可以快速查看客服号的聊天记录 群发助手&#xff1a;群发可突破200 朋友圈功能&#xff1a;定时发圈&#xff0c;支持多个微信账号同步发圈、跟圈和一…

恒运资本:投资前瞻:储能产业迎政策密集支持 AIGC有望进入加速状态

昨日&#xff0c;沪指、深成指盘中弱势下探&#xff0c;创业板指冲高回落。到收盘&#xff0c;沪指跌0.49%报3244.49点&#xff0c;深成指跌0.53%报11039.45点&#xff0c;创业板指微跌0.01%报2228.73点&#xff0c;科创50指数跌0.85%&#xff1b;两市合计成交7366亿元&#xf…

STM32 F103C8T6学习笔记4:时钟树、滴答计时器、定时器定时中断

今日理解一下STM32F103 C8T6的时钟与时钟系统、滴答计时器、定时器计时中断的配置&#xff0c;文章提供原理&#xff0c;代码&#xff0c;测试工程下载。 目录 时钟树与时钟系统&#xff1a; 滴答计时器&#xff1a; 定时器计时中断&#xff1a; 测试结果&#xff1a; 测…

echarts3d柱状图

//画立方体三个面 const CubeLeft echarts.graphic.extendShape({shape: {x: 0,y: 0,width: 9.5, //柱状图宽zWidth: 4, //阴影折角宽zHeight: 3, //阴影折角高},buildPath: function (ctx, shape) {const api shape.api;const xAxisPoint api.coord([shape.xValue, 0]);con…

OSCS 闭门研讨第一期实录:软件供应链安全建设价值

2023 年 7 月 18 日晚 19:30&#xff0c;软件供应链安全技术交流群&#xff08;OSCS&#xff09;组织了第一次线上的闭门研讨会&#xff0c;本次研讨会我们收到 71 个来自各个企业关注软件供应链安全的技术专家的报名&#xff0c;根据研讨会参与规则要求&#xff0c;我们对报名…

一文告诉你,Intellij IDEA神器隐藏的11种实用小技巧!

el/2022/10/4 6:58:50 点击上方“程序员大咖”&#xff0c;选择“置顶公众号” 关键时刻&#xff0c;第一时间送达&#xff01; Intellij IDEA真是越用越觉得它强大&#xff0c;它总是在我们写代码的时候&#xff0c;不时给我们来个小惊喜。出于对Intellij IDEA的喜爱&#x…

【uniapp】uniapp打包H5(网页端):

文章目录 一、设置appid&#xff1a;二、设置router&#xff1a;三、打包&#xff1a;【1】[CLI 发行uni-app到H5&#xff1a;https://hx.dcloud.net.cn/cli/publish-h5](https://hx.dcloud.net.cn/cli/publish-h5)【2】HBuilderX 四、最终效果&#xff1a; 一、设置appid&…

W5100S-EVB-PICO 做TCP Server进行回环测试(六)

前言 上一章我们用W5100S-EVB-PICO开发板做TCP 客户端连接服务器进行数据回环测试&#xff0c;那么本章将用开发板做TCP服务器来进行数据回环测试。 TCP是什么&#xff1f;什么是TCP Server&#xff1f;能干什么&#xff1f; TCP (Transmission Control Protocol) 是一种面向连…

芯片常见测试手段:CP测试和FT测试

参考链接&#xff1a; 芯片测试的术语解释&#xff08;FT、CP&#xff09;&#xff0c;持续更新...._ft测试_染不尽的流年的博客-CSDN博客 如何区分芯片cp测试和ft测试 (baidu.com) 芯片常见测试手段&#xff1a;CP测试和FT测试 - 测量仪表 - 电子发烧友网 芯片测试是极其重要…

2023年加湿器市场数据分析(天猫数据分析怎么做)

随着人们生活水平提高、空调广泛使用&#xff0c;导致皮肤紧绷、口舌干燥、咳嗽感冒等空调病的滋生。可以看出&#xff0c;空气湿度与人体健康以及日常生活有着密切的联系。而加湿器作为室内空气湿度控制的重要工具&#xff0c;在近年来受到了越来越多的重视。根据鲸参谋电商数…

pytest 常用命令参数

-x 用例一旦失败或错误时就立即停止执行 共两条用例&#xff0c;运行第一条报错失败或报错&#xff0c;第二条就不会执行 pytest -vs -x test_pytest_study.py::TestCommon1 共2条用例&#xff0c;当执行到第一条失败时候&#xff0c;第二条不执行 --maxfailnum …

快速入门:【c# 之 Winform开发】

C#基础 面向对象(OOP) c语言是面向过程。 c是面向过程面向对象。 c#是纯粹的面向对象: 核心思想是以人的思维习惯来分析和解决问题。万物皆对象。 面向对象开发步骤: 分析对象 特征行为关系(对象关系/类关系) 写代码: 特征–>成员变量 方法–>成员方法 实例化–具体对…