MyBatis 用法详解

news2024/11/26 1:46:56

文章目录

  • 一、普通 SQL
    • 1.1 注解实现:
      • 1.1.1 参数传递:
      • 1.1.2 增(@Insert):
      • 1.1.3 删(@Delete):
      • 1.1.4 改(@Update):
      • 1.1.5 查(@Select):
        • 1.1.5.1 起别名:
        • 1.1.5.2 结果映射:
        • 1.1.5.3 开启驼峰命名(推荐):
    • 1.2 MyBatis XML 配置文件实现:
      • 1.2.1 添加 Mapper.xml
      • 1.2.2 增:
      • 1.2.3 删:
      • 1.2.4 改:
      • 1.2.5 查:
  • 二、#{} 和 ${} 的区别:
  • 三、动态 SQL:
    • 3.1 `<if> `标签:
    • 3.2 `<trim>`标签:
    • 3.3 `<where>`标签:
    • 3.4 `<set>`标签:
    • 3.5 `<foreach>`标签:
    • 3.6 `<include>`标签:

使用 MyBatis 需要导入依赖(MyBatis 和 MySQL(数据库都行)),和配置 yml 文件。导入对应的依赖比较简单,所以下面只给出 yml 文件的配置。

yml 文件配置如下。

下面用中文填写(除了注释)的都是要根据自己的情况来填写的。

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/对应数据库名称?characterEncoding=utf8&useSSL=false
    username: root
    password: 对应数据库的密码(如果是纯数字记得加上单引号)
    driver-class-name: com.mysql.cj.jdbc.Driver
  mvc:
    favicon:
      enable: false
  profiles:  #多平台配置
    active: dev
# 设置 Mybatis 的 xml 保存路径
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml
  configuration: # 配置打印 MyBatis 执行的 SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true  #自动驼峰转换

MyBatis 有两种实现方式。(1)注解(2)xml 文件实现。

一、普通 SQL

1.1 注解实现:

注解实现,其实就是在对应的注解里面写上 SQL 语句即可。

1.1.1 参数传递:

需求:查找 id=4 的用户,对应的 SQL 就是:select * from userinfo where id=4。

@Select("select username, `password`, age, gender, phone from userinfo where id = 4")
UserInfo queryById();

但是这样的话,只能查找 id=4 的数据,所以 SQL 语句中的 id 值不能写成固定数值,需要变为动态的数值。

解决方法:在 queryById 方法中添加一个参数(id),将方法中的参数,传给 SQL 语句。

使用#{}的方式获取方法中的参数。注意:#{}里面的名称需要和方法参数名称一致(如果方法参数是一个对象,那么#{}里面的值,要和对象的属性名称一样。)

@Select("select username, `password`, age, gender, phone from userinfo where id= #{id} ")
UserInfo queryById(Integer id);

如果 mapper 接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如:#{id}、# {value}。建议和参数名保持一致。

添加测试用例:

@Test
void queryById() {
 UserInfo userInfo = userInfoMapper.queryById(4);
 System.out.println(userInfo);
}

运行结果:

image-20241007150941216

也可以通过 @Param ,设置参数的别名,如果使用 @Param 设置别名,#{…}里面的属性名必须和 @Param 设置的一样。

@Select("select username, `password`, age, gender, phone from userinfo where id = #{userid} ")
UserInfo queryById(@Param("userid") Integer id);

如果参数是对象,设置了 @Param 属性,#{…} 需要使用 别名.属性 来获取。

//插入数据
@Insert("insert into userinfo(username,`password`,age,gender,phone) " +
        "values(#{gobeyye.username},#{gobeyye.password}" +
        ",#{gobeyye.age},#{gobeyye.gender},#{gobeyye.phone})")
Integer insertUserInfo1(@Param("gobeyye") UserInfo userInfo);

1.1.2 增(@Insert):

SQL 语句:

insert into userinfo (username, `password`, age, gender, phone) values 
("zhaoliu","zhaoliu",19,1,"18700001234")

把 SQL 中的常量替换为动态的参数:

Mapper 接口的方法:

@Insert("insert into userinfo (username, `password`, age, gender, phone) values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);

直接使用 UserInfo 对象的属性名来获取参数。

测试代码:

 @Test
    void insertUesrInfo1() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("zhaoliu");
        userInfo.setPassword("zhaoliu");
        userInfo.setAge(19);
        userInfo.setGender(1);
        userInfo.setPhone("18700001234");
        userInfoMapper.insertUesrInfo1(userInfo);
    }

运行结果:下面这个运行结果,需要导入日志配置。

image-20241007153531754

返回主键:

如果想要拿到自增 id(主键一般默认是 id),需要在 Mapper 接口的方法上添加一个 Options 的注解。

@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into userinfo (username, age, gender, phone) values (#{userinfo.username},#{userinfo.age},#{userinfo.gender},#{userinfo.phone})")
Integer insert(@Param("userinfo") UserInfo userInfo);
  • useGeneratedKeys:这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。

  • keyProperty:指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素,设置它的值,默认值:未设置(unset)。

注意:设置 useGeneratedKeys = true 之后,方法返回值依然是受影响的行数,自增 id 会设置在上述 keyProperty 指定的属性中。

1.1.3 删(@Delete):

SQL 语句:

问号是占位符的意思,方便下面写代码,不是 SQL 语法支持的。

delete from userinfo where id = ?

Mapper 接口的方法:

@Delete("delete from userinfo where id = #{id}")
void delete(Integer id);

1.1.4 改(@Update):

SQL 语句:

update userinfo set username="zhaoliu" where id=5

Mapper 接口的方法:

@Update("update userinfo set username=#{username} where id=#{id}")
void update(UserInfo userInfo);

1.1.5 查(@Select):

SQL 语句:

@Select("select id, username, `password`, age, gender, phone, delete_flag, 
create_time, update_time from userinfo")

Mapper 接口的方法:

@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
List<UserInfo> queryAllUser();

查询结果:

image-20241007160052250

从运行结果上可以看到,我们 SQL 语句中,查询了 delete_flag,create_time,update_time 但是这几个属性却没有赋值。

原因分析:

当自动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。这意味着如果发现了 ID 列和 id 属性,MyBatis 会将列 ID 的值赋给 id 属性。

观察下图:

image-20241007160512525

我们可以发现,这是因为字段名和属性名称不一致导致的(命名规则不同导致的)。

解决方法:

  1. 起别名

  2. 结果映射

  3. 开启驼峰命名

1.1.5.1 起别名:

在 SQL 语句中,给列名起别名,保持别名和实体类属性名一样。

@Select("select id, username, `password`, age, gender, phone," +
        " delete_flag as deleteFlag, create_time as createTime, update_time as updateTime from userinfo")
public List<UserInfo> queryAllUser();
1.1.5.2 结果映射:
@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
@Results({
        @Result(column = "delete_flag", property = "deleteFlag"),
        @Result(column = "create_time", property = "createTime"),
        @Result(column = "update_time", property = "updateTime")
})
List<UserInfo> queryAllUser2();

如果其他 SQL,也希望可以复用这个映射关系,可以给这个 Results 定义一个名称。

@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time from userinfo")
@Results(id="resultMap",value = {
    @Result(column = "delete_flag", property = "deleteFlag"),
    @Result(column = "create_time", property = "createTime"),
    @Result(column = "update_time", property = "updateTime")
})
List<UserInfo> queryAllUser2();

@Select("select id, username, `password`, age, gender, phone, delete_flag, create_time, update_time " +
        "from userinfo where id= #{userid} ")
@ResultMap(value = "resultMap")
UserInfo queryById(@Param("userid") Integer id);

使用 id 属性给该 Results 定义别名,使用 @ResultMap 注解来复用 Results。

1.1.5.3 开启驼峰命名(推荐):

通常数据库列使用蛇形命名法进行命名(下划线分割各个单词),而 Java 属性一般遵循驼峰命名法约定。为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase 设置为 true(设置 application.properties 或者 application.yml 文件)。

mybatis:
  configuration:
#    日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#    自动驼峰转换
    map-underscore-to-camel-case: true

这时 Java 代码不做任何处理。字段就能全部正确赋值。

1.2 MyBatis XML 配置文件实现:

1.2.1 添加 Mapper.xml

首先根据 yml 文件中配置的 mapper 路径创建对应的 xml 文件。

image-20241007165055159

创建完成后,向里面填入 MyBatis 的固定 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.UserInfoXMlMapper">
 <select id="queryAllUser" resultType="com.example.demo.model.UserInfo">
 select username,`password`, age, gender, phone from userinfo
 </select>
</mapper>

以下是对以上标签的说明:

  • <mapper>标签:需要指定 namespace 属性,标识命名空间,值为 mapper 接口的全限定名,包括全包名.类名。
  • <select>查询标签:是用来执行数据库的查询操作的。select 中的属性解释如下:
  1. id :是和 Interface(接口)中定义的方法名称一样的,表示对接口的具体实现方法。
  2. resultType:返回的数据类型。
image-20241007170155891

其实 xml 增删改查和注解实现增删改查,其实差不多,无非就是一个使用注解,另一个使用标签。

1.2.2 增:

UserInfoMapper 接口:

Integer deleteUser(Integer id);

UserInfoMapper.xml 实现:

<insert id="insertUser">
 insert into userinfo (username, `password`, age, gender, phone) values (#{username}, #{password}, #{age},#{gender},#{phone})
</insert>

测试代码:

@Test
void insertUser() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("gobeyye");
    userInfo.setPassword("123456");
    userInfo.setAge(18);
    userInfo.setGender(1);
    userInfo.setPhone("12345678");
    userInfoXMLMapper.insertUser(userInfo);
}

效果如下:

image-20241008094127079

  • 返回自增 id:

接口定义不变,Mapper.xml 实现设置 useGeneratedKeys 和 keyProperty 属性。代码如下:

<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into userinfo (username, `password`, age, gender, phone)
    values (#{username}, #{password}, #{age},#{gender},#{phone})
</insert>

1.2.3 删:

UserInfoMapper 接口:

Integer deleteUser(Integer id);

UserInfoMapper.xml 实现:

<delete id="deleteUser">
    delete from userinfo where id = #{id}
</delete>

1.2.4 改:

UserInfoMapper 接口:

Integer updateUser(UserInfo userInfo);

UserInfoMapper.xml 实现:

<update id="updateUser">
 update userinfo set username=#{username} where id=#{id}
</update>

1.2.5 查:

UserInfoMapper 接口:

List<UserInfo> queryAllUser();

UserInfoMapper.xml 实现:

<select id="queryAllUser" resultType="com.example.demo.model.UserInfo">
 select id, username,`password`, age, gender, phone, delete_flag, create_time, update_time from userinfo
</select>

运行结果:

image-20241008095014817

结果显示:deleteFlag,createTime,updateTime 也没有进行赋值。

解决办法和注解类似:

  1. 起别名

  2. 结果映射

  3. 开启驼峰命名

其中 1 和 3 方法和注解一样,下面重点讲如何使用 xml 写结果映射。

Mapper.xml:

<resultMap id="BaseMap" type="com.gobeyye.mybatis.moder.UserInfo">
    <id column="id" property="id"></id>
    <result column="delete_flag" property="deleteFlag"></result>
    <result column="create_time" property="createTime"></result>
    <result column="update_time" property="updateTime"></result>
</resultMap>

<select id="queryAllUser" resultMap="BaseMap">
    select id, username,`password`, age, gender, phone, delete_flag, create_time, update_time from userinfo
</select>
image-20241008100239710

多表查询和单表查询类似,只是 SQL 不同而已,不再多说。

二、#{} 和 ${} 的区别:

MyBatis 参数赋值有两种方式,文章前面使用了 #{} 进行赋值,接下来我们看下二者的区别。

#{} 和 ${} 的区别就是预编译SQL即时SQL的区别。

了解 SQL 语句的执行流程,有助于理解下面的区别。

SQL 语句的执行流程:

  1. SQL 语法校验和解析

  2. SQL 优化

  3. SQL 执行

  4. #{} 性能更高:

绝大多数情况下,某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的语法解析,SQL 优化、SQL 编译等,则效率就明显不行了。

image-20241008101914520

预编译 SQL,编译一次之后会将编译后的 SQL 语句缓存起来,后面再次执行这条语句时,不会再次编译 (只是输入的参数不同),省去了解析优化等过程,以此来提高效率。

  1. #{} 更安全(防止 SQL 注入,最重要的一点):

SQL 注入:是通过操作输入的数据来修改事先定义好的 SQL 语句,以达到执行代码对服务器进行攻击的方法。

#{} 内部的值,只会被识别成参数,而 ${} 内部的值,既可以识别成参数也可以被识别成 SQL 语句。

  1. 特殊场景只能使用 ${}:

在排序功能中,我们可以选择升序或者降序。

Mapper 实现:

@Select("select id, username, age, gender, phone, delete_flag, create_time, update_time " +
        "from userinfo order by id ${sort} ")
List<UserInfo> queryAllUserBySort(String sort);

部分结果如下:

image-20241008103313736

如果将 ${} 换成 #{},就会出现如下结果,并报错:

image-20241008103424177

这是因为 #{} 会根据参数类型判断,是否拼接引号''。如果参数类型为 String,就会加上引号。

当使用 #{sort} 查询时,asc 前后自动给加了引号,导致 sql 错误。

除此之外,还有表名作为参数时,也只能使用 ${},但是一定要注意 SQL 注入问题。

综上,能使用 #{} 的场景就使用 #{},实在不行再使用 ${},但是一定要注意 SQL 注入问题。

三、动态 SQL:

动态 SQL 是 Mybatis 的强大特性之一,能够完成不同条件下不同的 sql 拼接。

可以参考官方文档:https://mybatis.net.cn/dynamic-sql.html

由于动态 SQL 会复杂一点,所以一般将动态 SQL 写在 xml 文件中(使用注解也行)。下面就都使用 xml 文件的形式,注解就不再演示。

3.1 <if> 标签:

接口定义:

Integer insertUserByCondition(UserInfo userInfo);

Mapper.xml 实现:

<insert id="insertUserByCondition">
    INSERT INTO userinfo (
    username, `password`, age,
    <if test="gender != null">
        gender,
    </if>
    phone)
    VALUES (#{username},#{password}, #{age},
    <if test="gender != null">
        #{gender},
    </if>
    #{phone})
</insert>

测试代码如下:

@Test
void insertUserByCondition() {
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("gobeyye");
    userInfo.setPassword("123123");
    userInfo.setAge(18);
    userInfo.setPhone("999999");
    userInfoXMLMapper.insertUserByCondition(userInfo);
}

效果如下:可以看到 gender 由于属性没有值,所以该字段被去除了。

image-20241008105642300

这里有的友友可能会有疑问:把全部字段都加上,不进行赋值的字段,参数传为 null 不就行了?

答:不行,因为 MySQL 中,有的字段如果没有赋值,会有默认值(可以自己设定),如果传值为 null,就会把默认值覆盖掉,这是我们不希望看到的,所以只能使用 if 标签。

3.2 <trim>标签:

之前的插入用户功能,只是有一个 gender 字段可能是选填项,如果有多个字段,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。

<trim>标签中有如下属性:

  • prefix:表示整个语句块,以 prefix 的值作为前缀。

  • suffix:表示整个语句块,以 suffix 的值作为后缀。

  • prefixOverrides:表示整个语句块要去除掉的前缀。

  • suffixOverrides:表示整个语句块要去除掉的后缀。

调整 Mapper.xml 的插入语句为:

<insert id="insertUserByCondition">
    insert into userinfo
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username !=null">
            username,
        </if>
        <if test="password !=null">
            `password`,
        </if>
        <if test="age != null">
            age,
        </if>
        <if test="gender != null">
            gender,
        </if>
        <if test="phone != null">
            phone,
        </if>
    </trim>
    values
    <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username !=null">
            #{username},
        </if>
        <if test="password !=null">
            #{password},
        </if>
        <if test="age != null">
            #{age},
        </if>
        <if test="gender != null">
            #{gender},
        </if>
        <if test="phone != null">
            #{phone}
        </if>
    </trim>
</insert>

在上面的这段代码中,就可以使用 <trim>标签起到解决,多余后缀,的问题。

3.3 <where>标签:

where 标签解决的是,如果所有条件都加上了 if 标签,且都没有进行传值,这时 where 就会多出来,这时 SQL 语法就出错了,使用 where 标签就可以很好的解决上面的问题。

<where>只会在子元素有内容的情况下才插入 where 字句,而且会自动去除字句开头的 AND 或 OR。

<select id="queryByCondition" resultType="com.example.demo.model.UserInfo">
    select id, username, age, gender, phone, delete_flag, create_time,
    update_time
    from userinfo
    <where>
        <if test="age != null">
            and age = #{age}
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="deleteFlag != null">
            and delete_flag = #{deleteFlag}
        </if>
    </where>
</select>

3.4 <set>标签:

<set> :动态的在 SQL 语句中插入 set 关键字,并会删掉额外的逗号。(用于 update 语句中)。

Mapper.xml:

<update id="updateUserByCondition">
    update userinfo
    <set>
        <if test="username != null">
            username = #{username},
        </if>
        <if test="age != null">
            age = #{age},
        </if>
        <if test="deleteFlag != null">
            delete_flag = #{deleteFlag},
        </if>
    </set>
    where id = #{id}
</update>

3.5 <foreach>标签:

对集合进行遍历时可以使用该标签。标签有如下属性:

  • collection:绑定方法参数中的集合,如 List,Set,Map 或数组对象。

  • item:遍历时的每一个对象。

  • open:语句块开头的字符串。

  • close:语句块结束的字符串。

  • separator:每次遍历之间间隔的字符串。

使用演示:

接口方法:

void deleteByIds(List<Integer> ids);

Mapper.xml:

<delete id="deleteByIds">
    delete from userinfo
    where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>

3.6 <include>标签:

在 xml 映射文件中配置的 SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码。

image-20241008121124855

我们可以对重复的代码片段进行抽取,将其通过标签封装到一个 SQL 片段,然后再通过标签进行引用。

  • <sql>:定义可重用的 SQL 片段。
  • <include>:通过属性 refid,指定包含的 SQL 片段。

例如 SQL片段:

<sql id="allColumn">
 id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

通过 include 标签进行引用。操作如下:

<select id="queryById" resultType="com.example.demo.model.UserInfo">
    select
    <include refid="allColumn"></include>
    from userinfo where id= #{id}
</select>

结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话,还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。

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

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

相关文章

大疆M2006+C610 pid参数调优

官方给的示例代码里给的是1.5, 0.1, 0 但试了下空转时显然不太行. 自己摸索出0.8, 0.03, 0 表现如图中的蓝色线 期望速度先两秒的1000,然后一秒的2000,一秒的3000, 0 2000 表现还不错,可以看到0.5秒后与期望值的差距控制在大概10%之内,但还是感觉有些过调 对了先说一下基础知识…

UnityComputeShader Challenge2

UnityComputeShader Challenge2 大部分内容与Challenge1中的一致&#xff0c;重复的地方不做说明 using UnityEngine; using System.Collections;public class Challenge2 : MonoBehaviour {public ComputeShader shader;//纹理的分辨率&#xff0c;正方形public int texReso…

PHP拼团接龙商城系统小程序源码

拼团接龙商城系统&#xff0c;解锁购物新乐趣&#xff01; &#x1f389; 拼团接龙&#xff0c;购物也能玩出新花样 你是否厌倦了单调的购物方式&#xff1f;想要尝试一种既有趣又实惠的购物新体验&#xff1f;那么&#xff0c;“拼团接龙商城系统”绝对是你的不二之选&#…

fluke双绞线测试-外部串扰AxTALK-测试DEMO样本

外部串扰是电缆束或跳线中相邻电缆之间传输的噪音或串扰。外部串扰是 10GBASE-T 通信应用中主要的噪音源。 电缆线对&#xff08;NEXT 和 FEXT&#xff09;之间的串扰信号与传输信号有关&#xff0c;所以网络设备可以利用数字信号处理 (DSP) 技术除去数据信号中的串扰信号。但…

力扣题11~20

题11&#xff08;中等&#xff09;&#xff1a; 思路&#xff1a; 这种题目第一眼就是双循环&#xff0c;但是肯定不行滴&#xff0c;o(n^2)这种肯定超时&#xff0c;很难接受。 所以要另辟蹊径&#xff0c;我们先用俩指针&#xff08;标志位&#xff09;在最左端和最右端&am…

Android iOS 使用 ARMS 用户体验监控(RUM)的最佳实践

作者&#xff1a;元泊 引言 背景信息 随着移动互联网技术的持续演进与全民互联网时代的深入&#xff0c;用户在 Android、iOS 应用程序、小程序、H5 游戏及网页等多元化平台上的交互时长显著增长。这一趋势加剧了用户体验&#xff08;UX&#xff09;场景的复杂性&#xff0c…

谈到数据集成和数据分析,这三个概念你得分清楚!

谈及数据集成和数据分析相关的概念&#xff0c;总是会提到异构数据源、异构数据库和分布式数据库&#xff0c;他们所涉及到的方面略有不同&#xff0c;今天来详细说下它们之间的区别&#xff01; 一、异构数据源 异构数据源是指不同类型、不同结构、不同格式的数据源。 在数据…

PyQt基本功能

简单的窗口 #!/usr/bin/python3 # -*- coding: utf-8 -*- import sys # 这⾥引⼊了PyQt5.QtWidgets模块&#xff0c;这个模块包含了基本的组件 from PyQt5.QtWidgets import QApplication, QWidgetif __name__ __main__:# 每个PyQt5应⽤都必须创建⼀个应⽤对象# sys.argv是⼀…

雷达图怎么绘制?!超简单,一次性告诉你Python和R绘制方法~~

今天给大家介绍的的图表为雷达图(Radar/Spider chart),这种类型图表在生活中较常使用&#xff0c;是一种以从同一点开始的轴上表示的三个或更多个定量变量的二维图表的形式显示多变量数据的图形方法。较常用的场景多为分析企业经营状况(收益性、生产性、流动性、安全性和成长性…

Vatee万腾平台:企业数字化转型的加速器

在当今这个信息化、数字化高速发展的时代&#xff0c;企业要想在激烈的市场竞争中立于不败之地&#xff0c;就必须紧跟时代步伐&#xff0c;实现数字化转型。而Vatee万腾平台&#xff0c;正是这样一款能够助力企业快速、高效完成数字化转型的利器&#xff0c;它如同一位经验丰富…

【MySQL】基本查询(下):更新、删除

3.Update 语法&#xff1a; UPDATE table_name SET column expr [, column expr ...] [WHERE ...] [ORDER BY ...] [LIMIT ...]举几个例子&#xff1a; 将孙悟空同学的数学成绩变更为 80 分&#xff1a; 将曹孟德同学的数学成绩变更为 60 分&#xff0c;语文成绩变更为 …

【GUI】使用 PySide6 创建一个简单的计算器

使用 PySide6 创建一个简单的计算器 在这篇博客中&#xff0c;我们将探索如何使用 PySide6 创建一个简单的计算器应用程序。PySide6 是 Python 的 Qt 绑定&#xff0c;提供了一套强大的工具来开发图形用户界面&#xff08;GUI&#xff09;应用程序。通过这个项目&#xff0c;我…

PPT技巧:保护PPT文件的方法有哪些?

PPT文件制作好之后保证文件不出错应该是很重要的&#xff0c;毕竟是要拿出去展示的&#xff0c;今天分享PPT加密方法给大家。希望能够帮助大家保护好自己的PPT文件。 打开密码 如果想要其他人需要输入正确的密码才能够打开文件查看并编辑&#xff0c;我们可以给PPT文件设置打…

除了电商,API在其他行业中的应用有哪些?

API&#xff08;应用程序编程接口&#xff09;在不同行业中扮演着至关重要的角色&#xff0c;它们促进了数据共享、服务集成和业务创新。以下是API在各个行业中的一些关键应用案例和作用&#xff1a; 金融服务行业 在金融服务行业&#xff0c;API的应用正在改变游戏规则。通过…

【安装教程】飞牛私有云fnOS安装部署

原文链接&#xff1a;【安装教程】飞牛私有云fnOS安装部署 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于飞牛私有云fnOS的安装和使用指南。飞牛私有云&#xff08;fnOS&#xff09;是一款专为企业和个人用户设计的私有云操作系统&#xff0c;提供了安全、便捷…

睡眠监测免费软件

睡眠监测免费软件&#xff0c;在现代社会中&#xff0c;随着生活节奏的加快和压力的增加&#xff0c;许多人都面临着睡眠问题。失眠、浅睡、早醒等问题不仅影响着我们的身体健康&#xff0c;也对日常生活造成诸多不便。然而&#xff0c;科技的进步为我们提供了许多解决方案&…

力扣 二叉树 104. 二叉树的最大深度

104. 二叉树的最大深度 一、题目描述 二、理解 对照二叉树的递归定义&#xff1a; 如果树为空&#xff0c;则它是一个空树。如果树不为空&#xff0c;它由一个根节点和两个子树组成&#xff0c;分别是左子树和右子树&#xff0c;且左子树和右子树本身也是二叉树。 采用递归形…

潜水打捞系统助力,破解汽车打捞难题

随着人类活动的不断扩展&#xff0c;汽车落水事故频发&#xff0c;成为救援工作中的一大难题。汽车因其重量和结构特性&#xff0c;一旦沉入水体&#xff0c;打捞工作将面临巨大挑战。传统的打捞方法往往效率低下&#xff0c;且在操作过程中可能会对汽车造成进一步的损害&#…

Leetcode 50. Pow ( x , n ) 快速幂、取模 C++实现

问题&#xff1a;Leetcode 50. Pow ( x , n ) 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数。 算法&#xff1a; 具体实现流程如下&#xff1a; 代码&#xff1a; class Solution { public:double myPow(double x, int N) {double ans 1;long long n N;if (n <…