MyBatis从入门到进阶

目录

  • MyBatis入门
    • 1、创建项目、数据准备
    • 2、数据库配置
    • 3、编写持久层代码
    • 单元测试
    • 打印日志
  • 基本操作
    • 查询数据
    • 插入数据
    • 删除数据
    • 更新数据
  • MyBatis - xml
    • 插入数据
    • 更新数据
    • 删除数据
    • 查询数据
    • #{}与${}
    • SQL注入
    • 排序
    • like查询
  • MyBatis进阶
    • if标签
    • trim标签
    • where标签
    • set标签
    • foreach标签
    • sql标签和include标签

MyBatis入门

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作,通过使用简单的 XML 或注解来配置和映射原生信息,使开发者可以专注于编写 SQL 语句。

基本步骤:创建项目和准备数据、数据库配置、编写持久层代码

1、创建项目、数据准备

创建过程和SpringBoot项目一模一样,需要注意的是,下面两个一定选上
在这里插入图片描述

在数据库中创建对应的数据库和表:

-- 创建数据库
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
USE mybatis_test;-- 创建表[用户表]
DROP TABLE IF EXISTS user_info;
CREATE TABLE `user_info` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默认',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常, 1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4; -- 添加用户信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone )
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

对应Java中的实体类

@Data
@RestController
@RequestMapping
public class UserInfo {private Integer id;private String username;private String password;private Integer age;private Integer gender;private String phone;private Integer deleteFlag;private Date createDate;private Date updateDate;}

2、数据库配置

在yml文件中,添加如下的配置:

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: '111111'driver-class-name: com.mysql.cj.jdbc.Driver

如果是properties格式的,配置如下:

#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=false
#连接数据库的⽤⼾名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=111111

3、编写持久层代码

根据规范,一般是Controller层调用Service层接口,Service层调用Dao层接口:
在这里插入图片描述

在MyBatis中持久层又叫Mapper

Controller层:

@RestController
@RequestMapping("/user")
public class UserController {//注入UserService@Autowiredprivate UserService userService;@RequestMapping("/selectUserList")public List<UserInfo> selectUserList(){return userService.selectUserList();}
}

Service层:

@Service
public class UserService {@Autowiredprivate UserInfoMapper userInfoMapper;public List<UserInfo> selectUserList() {return userInfoMapper.selectAll();}
}

Dao层:

MyBatis持久层规范一般叫xxxMapper

@Mapper
public interface UserInfoMapper {@Select("select * from user_info")List<UserInfo> selectAll();
}

@Mapper注解:表示的是MyBatis中的Mapper接口

@Select注解:代表数据库的select操作

单元测试

如果按照:Controller层调用Service层接口,Service层调用Dao层接口这个规范来进行代码测试,未免有些麻烦,因为我们编写完代码之后,往往只是测试单独的某个功能。我们可以使用SpringBoot帮我们创建好的Test测试类来进行测试

在这里插入图片描述

在test目录中创建测试类,需要给类加上类注解@SpringBootTest注解,才能从Spring中获取Bean,给方法加上@Test注解,可以执行对应的方法。例如:

@SpringBootTest
class MyBatisDemoTests {@Testvoid TestFunc() {}}

IDEA自动生成测试类:右键–>Generate–>Test

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

打印日志

yml配置如下:

# 配置日志
mybatis:configuration: # 配置打印 MyBatis⽇志log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

properties配置如下:

mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

配置了上述信息后,会把sql语句以及执行的结果以日志的形式打印出来
在这里插入图片描述

基本操作

查询数据

使用@Select注解

1、通过参数传递

@Mapper
public interface UserInfoMapper {//通过参数传递@Select("select * from user_info where id=#{id}")UserInfo selectAll(Integer id);
}

注意:select操作可能返回多条数据,要使用List接收,如果只返回一条数据,使用对象接收即可

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectAll() {//使用foreach遍历,类似于for循环userInfoMapper.selectAll().forEach(x -> System.out.println(x));List<UserInfo> userInfos = userInfoMapper.selectAll();/*等价于下面代码for (UserInfo user:userInfos) {System.out.println(user);}*/}
}

如果参数只有一个,参数名可以不对应,(多个参数必须对应)例如:

@Mapper
public interface UserInfoMapper {@Select("select * from user_info where id=#{abc}")UserInfo selectById(Integer id);
}
@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectById() {System.out.println(userInfoMapper.selectById(1));}
}

2、多个参数

MyBatis会根据参数名自动匹配

@Mapper
public interface UserInfoMapper {@Select("select * from user_info where id=#{id} and age =#{age}")UserInfo selectFunc(Integer age,Integer id);
}

3、参数重命名

MyBatis会给参数取名字,第一个参数取名为param1,第二个参数取名为param2…以此类推

@Mapper
public interface UserInfoMapper {@Select("select * from user_info where id=#{param1} and age =#{param2}")UserInfo selectFunc(Integer id,Integer age);
}

我们也可以自己重命名:

@Mapper
public interface UserInfoMapper {@Select("select * from user_info where id=#{id1} and age =#{age1}")UserInfo selectFunc(@Param("id1") Integer id,@Param("age1")Integer age);
}

最推荐的写法如下:

参数和注解的名称一致

@Mapper
public interface UserInfoMapper {@Select("select * from user_info where id=#{id} and age =#{age}")UserInfo selectFunc(@Param("id") Integer id,@Param("age")Integer age);
}

4、数据库的字段命名规范是统一小写字母,单词之间使用下划线分割,而java的规范是属性名称统一小驼峰。但是MyBatis是通过名称来映射的,如何让数据库字段和Java属性名映射起来?

方法1:使用@Results注解映射

@Mapper
public interface UserInfoMapper {//下划线命名法转换为驼峰命名法@Results(id = "map", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})//建立映射@Select("select * from user_info")List<UserInfo> selectAll2();@ResultMap("map")//注解复用@Select("select * from user_info")List<UserInfo> selectAll3();
}

方法2:通过配置实现,只需要添加下面的配置信息即可

mybatis:configuration: map-underscore-to-camel-case: true # 配置驼峰自动转换

插入数据

使用@Insert注解,获取参数直接使用对象的属性名

@Mapper
public interface UserInfoMapper {@Insert("insert into user_info(username,`password`,age,gender) values (#{username},#{password},#{age},#{gender})")Integer insertUserInfo(UserInfo userInfo);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUserInfo() {UserInfo userInfo = new UserInfo();userInfo.setId(11);userInfo.setAge(18);userInfo.setGender(1);userInfo.setUsername("z111");userInfo.setPassword("1234");userInfo.setPhone("1234567");userInfoMapper.insertUserInfo(userInfo);}
}

使用@Param注解,可以给对象重命名,重命名之后,需要通过点号获取

@Mapper
public interface UserInfoMapper {//对象重命名@Insert("insert into user_info(username,`password`,age,gender) values (#{Info.username},#{Info.password},#{Info.age},#{Info.gender})")Integer insertUserInfo2(@Param("Info") UserInfo userInfo);//返回值是影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUserInfo2() {UserInfo userInfo = new UserInfo();userInfo.setId(11);userInfo.setAge(18);userInfo.setGender(1);userInfo.setUsername("z222");userInfo.setPassword("1234");userInfo.setPhone("1234567");Integer i = userInfoMapper.insertUserInfo2(userInfo);System.out.println(i);}
}

使用@Options注解,获取主键:

@Mapper
public interface UserInfoMapper {@Options(useGeneratedKeys = true, keyProperty = "id")//@Insert("insert into user_info(username,`password`,age,gender) values (#{Info.username},#{Info.password},#{Info.age},#{Info.gender})")Integer insertUserInfo3(@Param("Info") UserInfo userInfo);//返回值:影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid insertUserInfo3() {UserInfo userInfo = new UserInfo();userInfo.setId(10);userInfo.setAge(18);userInfo.setGender(0);userInfo.setUsername("abcd");userInfo.setPassword("13579");userInfo.setPhone("1234567");Integer i = userInfoMapper.insertUserInfo3(userInfo);System.out.println(i);}
}

删除数据

使用@Delete注解:

@Mapper
public interface UserInfoMapper {@Delete("delete from user_info where id = #{id}")Integer delete(Integer id);//返回值:影响的行数
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid delete() {userInfoMapper.delete(9);}
}

更新数据

使用@Update注解

@Mapper
public interface UserInfoMapper {@Update("update user_info set password = #{password} where id =#{id}")Integer update(Integer id, String password);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid update() {userInfoMapper.update(1, "6666666");}
}

参数为对象:

@Mapper
public interface UserInfoMapper {@Update("update user_info set password = #{password} where id =#{id}")Integer update2(UserInfo userInfo);
}

测试代码:

@SpringBootTest
class UserInfoMapperTest {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid update2() {UserInfo userInfo = new UserInfo();userInfo.setId(8);userInfo.setPassword("00000");userInfoMapper.update2(userInfo);}
}

MyBatis - xml

上述的基本操作都是基于注解的方式进行的,下面我们介绍使用xml的方式进行增删查改等基本操作

数据库配置信息还是一样

# 配置数据库信息
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=falseusername: rootpassword: "111111"driver-class-name: com.mysql.cj.jdbc.Driver

配置MyBatis xml文件路径

mybatis:mapper-locations: classpath:mapper/**Mapper.xml

表示在mapper路径下的,文件名以Mapper结束的xml文件,classpath指的是resources这个目录,例如:
在这里插入图片描述

插件安装:
在这里插入图片描述

安装好插件之后,可以实现接口和xml文件之间跳转,甚至可以帮我们根据接口中的方法自动生成对应xml的语句

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

定义接口:

@Mapper
public interface UserInfoXmlMapper {//查询List<UserInfo> queryAllUser();
}

对应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.wpre.mybatisdemo2.mapper.UserInfoXmlMapper"><select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">select *from user_info</select></mapper>

在这里插入图片描述

resultType只有查询操作需要写,其他操作不需要

插入数据

使用insert标签,标签内写sql语句

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

对应的接口:

Integer insertUser(UserInfo userInfo);

测试类:

@Test
void insertUser() {UserInfo userInfo = new UserInfo();userInfo.setUsername("wpre");userInfo.setPassword("wpre");userInfo.setAge(18);userInfo.setGender(1);userInfoXmlMapper.insertUser(userInfo);
}

参数重命名:

Integer insertUser2(@Param("uf") UserInfo userInfo);
<insert id="insertUser2">insert into user_info(username, `password`, age, gender)values (#{uf.username}, #{uf.password}, #{uf.age}, #{uf.gender})
</insert>

重命名之后,需要通过点号获取

测试类:

@Test
void insertUser2() {UserInfo userInfo = new UserInfo();userInfo.setUsername("wpre");userInfo.setPassword("wpre");userInfo.setAge(18);userInfo.setGender(1);userInfoXmlMapper.insertUser2(userInfo);
}

返回自增id

Integer insertUser(UserInfo userInfo);
<insert id="insertUser3" useGeneratedKeys="true">insert into user_info(username, `password`, age, gender)values (#{uf.username}, #{uf.password}, #{uf.age}, #{uf.gender})
</insert>

测试类:

@Test
void insertUser() {UserInfo userInfo = new UserInfo();userInfo.setUsername("wpre");userInfo.setPassword("wpre");userInfo.setAge(18);userInfo.setGender(1);Integer result = userInfoXmlMapper.insertUser3(userInfo);System.out.println("影响行数"+result+"id:"+userInfo.getId());
}

更新数据

使用update标签

Integer updateUser(Integer id,String password);
<update id="updateUser">update user_infoset password = #{password}where id = #{id}
</update>

测试类:

@Test
void updateUser() {userInfoXmlMapper.updateUser(1, "12321");
}

删除数据

Integer deleteUserById(Integer id);
<delete id="deleteUserById">deletefrom user_infowhere id = #{id}
</delete>

测试类:

@Test
void deleteUserById() {userInfoXmlMapper.deleteUserById(1);
}

查询数据

List<UserInfo> queryAllUser();
<select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">select *from user_info
</select>

测试类:

@Test
void queryAllUser() {userInfoXmlMapper.queryAllUser();
}

xml同样会出现数据库字段名和Java中的属性名不匹配的问题

解决办法:

1、通过sql语句中的as取别名

例如

select delete_flag as deleteFlag,create_time as createTime,
from user_info;

2、建立映射关系

<resultMap id="BaseMap" type="com.wpre.mybatisdemo2.model.UserInfo"><id property="id" column="id"></id><result property="deleteFlag" column="delete_flag"></result><result property="createDate" column="create_date"></result><result property="updateDate" column="update_flag"></result>
</resultMap>

在这里插入图片描述

如果使用这种方式映射,建议把所有的字段都写上

使用映射来进行查询:

<select id="queryAllUser2" resultMap="BaseMap">select id, username, delete_flag, create_time, update_timefrom user_info
</select>

3、配置驼峰自动转换

mybatis.configuration.map-underscore-to-camel-case=true

#{}与${}

MyBatis的参数赋值有两种方式,一种是使用#符号,一种是使用$符号

#{}:

在这里插入图片描述

${}:
在这里插入图片描述

#{}是预编译SQL, 是即时 S Q L , {}是即时SQL, 是即时SQL{}是直接替换参数。一般情况下,能使用#尽量使用#。

SQL注入

SQL注入(SQL Injection)是一种常见的数据库攻击手段,它允许攻击者插入或“注入”一个或多个SQL语句到原本的查询中,欺骗数据库服务器执行非预期的命令。这种攻击利用了应用程序在构建SQL查询时对用户输入数据的不当处理。

例如:

select * from user_info where username = '';drop table user_info;--'
@Select("select * from user_info where username=${username}")
UserInfo selectById(String username);

如果是即时SQL,传递的参数如果是';drop table user_info;-- 这样一条SQL就变成两条SQL了,在不知不觉中你的表就已经被删除了

排序

结论:排序只能使用${}

//排序
@Select("select * from user_info order by id #{order};")
List<UserInfo> selectUsernameByOrder(String order);

测试类

@Test
void selectUsernameByOrder() {userInfoXmlMapper.selectUsernameByOrder("desc");
}

运行结果
在这里插入图片描述

使用的是#{}进行参数赋值,参数是String类型,此时默认加上单引号,所以我们必须使用${}进行参数赋值。

like查询

结论:使用${}

//like查询
@Select("select from user_info where username like '%${name}%' ")
List<UserInfo> selectByLike(String name);

模糊查询+CONCAT可以避免SQL注入问题

//like查询
@Select("select * from user_info where username like CONCAT('%','#{name}','%') ")
List<UserInfo> selectByLike(String name);

MyBatis进阶

if标签

Integer insertUserByCondition(UserInfo userInfo);
<insert id="insertUserByCondition">insert into user_info(username, `password`, age, <if test="gender!=null">gender</if>)values (#{username}, #{password}, #{age}, <if test="gender!=null">#{gender}</if>)
</insert>

测试类:

@Test
void insertUserByCondition() {UserInfo userInfo = new UserInfo();userInfo.setUsername("zhangsan");userInfo.setPassword("123");userInfo.setAge(18);userInfoXmlMapper.insertUserByCondition(userInfo);
}

表示的含义是:检查参数gender是否为null,如果参数gender为null,gender就不会被包含在这条SQL语句中;如果参数gender不为null,gender就会被包含在这条SQL语句中。上述测试类中并没有设置gender,gender为空,所以SQL语句为

insert into user_info(username, `password`, age,)
values (username, `password`, age,)

可以发现,上述的SQL语句是有语法错误的,age的后面多了一个逗号,何解?使用trim标签

trim标签

trim标签有4个属性,分别是:

prefix:增加前缀

suffix:增加后缀

prefixOverrides:去除前缀

suffixOverrides:去除后缀

使用方法:if标签嵌套在trim标签中

<trim ><if test=""></if>
</trim>

例如:

<insert id="insertUserByCondition">insert into user_info<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></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></trim>
</insert>

如果逗号写在前面,则需要使用prefixOverrides

where标签

where标签的作用:

1、能够去除多余的and

2、当有查询条件时,生成where关键字

3、没有查询条件时,不生成where关键字

例如:

<select id="selectByCondition" resultType="com.wpre.mybatisdemo2.model.UserInfo">select *from user_info<where><if test="age!=null">age = #{age} and</if><if test="deleteFlag!=null">delete_flag = #{deleteFlag}</if></where>
</select>

set标签

set标签的作用:

1、添加set关键字

2、去除末尾的逗号

<update id="updateByCondition">update user_info<set><if test="username!=null">username=#{username},</if><if test="password!=null">password=#{password},</if><if test="gender!=null">gender=#{gender},</if></set><where>id = #{id}</where>
</update>

foreach标签

foreach标签处理的是如下SQL语句

delete from user_info where id in (10,11,12)

forecah属性如下:

1、collection:遍历的集合

2、separator:分隔符

3、item:元素的名称

4、open:以xx为开始

5、close:以xx为结束

例如:

Integer foreachDelete(List<Integer> ids);
<update id="foreachDelete">delete from user_info where id in<foreach collection="ids" separator="," item="id" open="(" close=")">#{id}</foreach>
</update>

测试类:

@Test
void foreachDelete() {userInfoXmlMapper.foreachDelete(List.of(10, 11, 12));
}

sql标签和include标签

sql标签可以把重复冗余的代码片段进行抽取,封装成一个SQL片段,通过使用include标签进行引用

例如:

<sql id="queryAllUser">id,username,age,gender,phone,delete_flag,create_time,update_time
</sql><select id="queryAllUser" resultType="com.wpre.mybatisdemo2.model.UserInfo">select<include refid="queryAllUser"></include>from user_info
</select>

本文结束,感谢阅读~

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

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

相关文章

TensorFlow 2.0 环境配置

官方文档&#xff1a;CUDA Installation Guide for Windows 官方文档有坑&#xff0c;windows的安装指南直接复制了linux的指南内容&#xff1a;忽略这些离谱的信息即可。 可以从官方文档知悉&#xff0c;cuda依赖特定版本的C编译器。但是我懒得为了一个编译器就下载整个visua…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 &#xff0c; 现实的漫游效果不是从摄像机的角度来看 &#xff0c; 但其仍然存在很多困难 。基于三维场景的视频融合 &#xff0c; 因其直观等特效在视频监控等相关领域有着…

亚马逊评论爬虫+数据分析

爬取评论 做分析首先得有数据&#xff0c;数据是核心&#xff0c;而且要准确&#xff01; 1、爬虫必要步骤&#xff0c;选好框架 2、开发所需数据 3、最后测试流程 这里我所选框架是seleniumrequest&#xff0c;很多人觉得selenium慢&#xff0c;确实不快&#xff0c;仅针对此…

RK3588 C++ 多线程运行

RK3588 C 多线程 实际运行解决OpenCV问题&#xff1a; 1. OpenCV 安装 sudo apt-get update sudo apt-get install libopencv-dev2. 检查 OpenCV 安装路径 find / -name OpenCVConfig.cmake3. 设置 OpenCV_DIR 环境变量 export OpenCV_DIR/usr/lib/aarch64-linux-gnu/cmake/op…

【已解决】Parameter index out of range (14 > number of parameters, which is 13).

解决思路&#xff1a; 字面意思就是sql传参数量对不上&#xff0c;但我检查几遍代码都感觉没问题&#xff0c;sql单独拿到mysql里运行也没问题。看了其他的报错&#xff1a;Error setting non null for parameter #2 with JdbcType null&#xff0c;看起来也是跟参数有关的&am…

MDBook 使用指南

MDBook 是一个灵感来自 Gitbook 的强大工具&#xff0c;专门用于创建电子书和文档。它能够将 Markdown 编写的内容编译成静态网站&#xff0c;非常适合项目文档、教程和书籍的发布。 个人实践过许多文档方案&#xff0c;如 hexo、hugo、WordPress、docsify 和 mdbook 等&#…

vue计算属性 初步使用案例

<template><div><h1>购物车</h1><div v-for"item in filteredItems" :key"item.id"><p>{{ item.name }} - {{ item.price }} 元</p><input type"number" v-model.number"item.quantity"…

C++编程技巧与规范-类和对象

类和对象 1. 静态对象的探讨与全局对象的构造顺序 静态对象的探讨 类中的静态成员变量(类类型静态成员) 类中静态变量的声明与定义&#xff08;类中声明类外定义&#xff09; #include<iostream> using namespace std;namespace _nmspl {class A{public:A():m_i(5){…

如何在 Ubuntu 上安装 RStudio IDE(R语言集成开发环境) ?

RStudio 是一个功能强大的 R 语言集成开发环境(IDE)&#xff0c;R 是一种主要用于统计计算和数据分析的编程语言。任何从事数据科学项目或任何其他涉及 R 的类似任务的人&#xff0c;RStudio 都可以使您的工作更轻松。 本指南将引导您完成在 Ubuntu 系统上安装 RStudio 的过程…

高中数学:概率-相关运算性质

文章目录 一、概率定义二、运算性质三、事件相互独立四、频率与概率五、练习 一、概率定义 二、运算性质 基本性质 互斥事件的性质 对立事件性质 包含事件的性质 有交集但不包含的事件性质 三、事件相互独立 注意&#xff1a; 四、频率与概率 五、练习

VM安装Ubuntu详细配置

1、第一步修改阿里源&#xff1a;打开软件 与更新&#xff0c;更改下载自为&#xff1a;http://mirrors.aliyun.co/ubuntu 2、安装open-vm-tools: 安装两个文件&#xff1a;sudo api install open-vm-tools open-vm-tools-desktop 3、安装搜狗输入法&#xff1a;点击下载 a、…

乒乓球筐(多组输入模板)

乒乓球筐 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNext()) {int[] hash new i…

AI 写作(五)核心技术之文本摘要:分类与应用(5/10)

一、文本摘要&#xff1a;AI 写作的关键技术 文本摘要在 AI 写作中扮演着至关重要的角色。在当今信息爆炸的时代&#xff0c;人们每天都被大量的文本信息所包围&#xff0c;如何快速有效地获取关键信息成为了一个迫切的需求。文本摘要技术正是为了解决这个问题而诞生的&#x…

TCP 三次握手意义及为什么是三次握手

✨✨✨励志成为超级技术宅 ✨✨✨ TCP的三次握手在笔试和面试中经常考察&#xff0c;非常重要&#xff0c;那么大家有没有思考过为什么是三次握手&#xff0c;俩次握手行不行呢&#xff1f;四次握手行不行呢&#xff1f;如果大家有疑问或者不是很理解&#xff0c;那么这篇博客…

初识算法 · 位运算(2)

目录 前言&#xff1a; 判定字符是否唯一 丢失的数字 比特位计数 只出现一次的数字III 前言&#xff1a; ​本文的主题是位运算&#xff0c;通过四道题目讲解&#xff0c;一道是判断字符是否唯一&#xff0c;一道是只出现一次的数字III&#xff0c;一道是比特位计数&…

Unity Assembly Definition Assembly Definition Reference

文章目录 1.Unity 预定义程序集2.Assembly definition3. Assembly definitions相关实验 1.Unity 预定义程序集 Unity 有4个预定义程序集&#xff1a; 阶段程序集名脚本文件1Assembly-CSharp-firstpassStandard Assets, Pro Standard Assets和Plugins文件夹下面的运行时脚本2A…

【征稿倒计时!华南理工大学主办 | IEEE出版 | EI检索稳定】2024智能机器人与自动控制国际学术会议 (IRAC 2024)

#华南理工大学主办&#xff01;#IEEE出版&#xff01;EI稳定检索&#xff01;#组委阵容强大&#xff01;IEEE Fellow、国家杰青等学术大咖领衔出席&#xff01;#会议设置“优秀论文”“优秀青年学者报告”“优秀海报”等评优奖项 2024智能机器人与自动控制国际学术会议 &#…

[CKS] Create/Read/Mount a Secret in K8S

最近准备花一周的时间准备CKS考试&#xff0c;在准备考试中发现有一个题目关于读取、创建以及挂载secret的题目。 ​ 专栏其他文章: [CKS] Create/Read/Mount a Secret in K8S-CSDN博客[CKS] Audit Log Policy-CSDN博客 -[CKS] 利用falco进行容器日志捕捉和安全监控-CSDN博客[C…

5个非LLM软件趋势

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

社会工程骗局席卷金融机构

2024 年北美金融机构收到的社交工程诈骗报告数量比一年前增加了 10 倍。数据显示&#xff0c;诈骗现在占所有数字银行欺诈的 23%。 深度伪造和 GenAI 诈骗的危险日益增加 BioCatch 在其 2024 年北美数字银行欺诈趋势报告中公布了这些发现&#xff0c;该报告还详细说明了报告的…