当前位置: 首页 > news >正文

初始MYSQL数据库(8)—— JDBC编程

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏: MYSQL

目录

JDBC的概念 

JDBC的使用

加载驱动包

建立连接

创建 statement 对象

定义并执行SQL语句 

处理结果集

关闭资源 

SQL注入

优化后的JDBC

JDBC编程的两种方式对比


前面,我们学习了MySQL数据库中SQL语句的基础语法并且在命令行上面也进行了一些实际的操作。现在我们就来学习使用IDEA去编写SQL语句来操作数据库。

JDBC的概念 

JDBC(Java DataBase Connectivity,Java数据库连接)是Java程序和数据库之间的桥梁,包含
了一套Java定义的用于执行SQL语句的接口,使开发者能够编写数据库的程序。JDBC的主要作用是:与数据库建立连接、发送SQL语句和处理数据库执行结果。关系示意图:

从上面我们知道了,JDBC其实就是一套Java源生的。而其的实现也与我们无关,是由数据库厂商自己提供的。我们只需要去使用即可。

接下来我们就来使用JDBC去操作数据库。

JDBC的使用

JDBC的使用可以大致概括为以下几个方面:

1、加载数据库厂商提供的驱动包。即实现了JDBC的接口

2、建立数据库连接

3、创建statement对象

4、编写SQL语句,并通过statement对象去执行SQL语句

5、接收结果集或者返回值

6、关闭资源

加载驱动包

加载驱动包的过程可以简单理解为在手机上安装一个软件的过程。 而安装软件的过程如下所示:

1、打开应用商店;

2、去应用商店里面找到该软件;

3、下载该软件。

4、安装该软件,在运行即可。

同理加载驱动包也是三个步骤:

1、打开Maven官网(驱动包全部在里面);

Maven官网,点我

2、找到与自己电脑中数据库版本相对应数据库;

那问题来了,怎么判断自己是哪个版本呢?

按 win + R 打开命令行,然后输入 mysql -uroot -p,接着摁下回车键,再输入密码,成功打开MySQL之后,就输入 select version(); 去查询此时正在运行的MySQL的版本是多少。

如果你和我一样是MySQL8.0.39的话,那么就是去第一个结果中找到MySQL8.3即可。

3、在该目录下,来到Maven所在目录,点击框内英文即可。 

 4、将复制的内容粘贴到Maven工程中。

这里首先得创建一个Maven工程。

然后只需要套个框架,在框架内粘贴我们复制的内容即可。 

 接下来就是正式的加载驱动包了,正如运行程序。

现在就已经将驱动包加载完成啦!下面就是要建立连接了。

建立连接

// 2. 获取数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8" +"&allowPublicKeyRetrieval=true&useSSL=false", "root", "123456");;

这里是固定写法:

即修改 3306/ 后面的值,即对应的数据库。root 就是用户名,123456 就是mysql的密码。 

创建 statement 对象

// 3. 创建Statement对象
Statement statement = connection.createStatement();

定义并执行SQL语句 

// 4. 定义SQL并执行SQL语句
System.out.print("请输入学生姓名:");
Scanner scanner = new Scanner(System.in);
// 接收用户的输入
String name = scanner.next();
// 把查询的列详细写出来
String sql = "select id, name, age, gender from student where name = '" + name + "'";
// 5. 执行SQL,获取查询结果
resultSet = statement.executeQuery(sql);

处理结果集

// 6. 对结果集进行遍历,获取数据
// 如果一下条有记录,返回true,没有则返回false
while (resultSet.next()) {// 获取学生的信息long stuId = resultSet.getLong(1); // 这里的1是指第一列String stuName = resultSet.getString(2);int stuAge = resultSet.getInt(3);byte stuGender = resultSet.getByte(4);System.out.println(MessageFormat.format("学生编号={0}, 学生姓名={1}, 学生年龄={2}, 学生性别={3}",stuId, stuName, stuAge, stuGender));
}

关闭资源 

// 依次释放资源,关闭连接
if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}
if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}
}
if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}
}

下面是综合的代码(包括捕获异常):

import java.sql.*;
import java.text.MessageFormat;
import java.util.Scanner;public class JDBC_Demo1 {public static void main(String[] args) {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {// 1. 加载数据库厂商提供的驱动Class.forName("com.mysql.cj.jdbc.Driver");// 2. 获取数据库连接connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8" +"&allowPublicKeyRetrieval=true&useSSL=false", "root", "123456");// 3. 创建Statement对象statement = connection.createStatement();// 4. 定义SQL并执行SQL语句System.out.print("请输入学生姓名:");Scanner scanner = new Scanner(System.in);// 接收用户的输入String name = scanner.next();String sql = "select id, name, age, gender from student where name = '" + name + "'";// 5. 执行SQL,获取查询结果resultSet = statement.executeQuery(sql);// 6. 对结果集进行遍历,获取数据// 如果一下条有记录,返回true,没有则返回falsewhile (resultSet.next()) {// 获取学生的信息long stuId = resultSet.getLong(1);String stuName = resultSet.getString(2);int stuAge = resultSet.getInt(3);byte stuGender = resultSet.getByte(4);System.out.println(MessageFormat.format("学生编号={0}, 学生姓名={1}, 学生年龄={2}, 学生性别={3}",stuId, stuName, stuAge, stuGender));}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();} finally {// 依次释放资源,关闭连接if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}

注意:try块 中定义的变量,其作用域只是在try块中,只有在全局的变量,才能在try-catch 中使用,并且在finally块中也是可以使用。(全局只是相对try-catch和finally而言的)

效果演示:

JDBC:

命令行:

上面这种方法虽然的确可以操作数据库,但是从性能来讲,还是比较差的。因为DriverManager每次调用getConnection方法都会初始化一个新的连接,使用完成后会关闭真实连接,导致资源浪费。因此 DataSource就闪亮登场了。DataSource使用了连接池的技术,会在初始化时创建一定数量的数据库连接,这些连接可以重复使用,关闭时并不是真正关闭连接,而是将连接归还给连接池,以供后续使用,有效地提高资源利用率和和性能。

SQL注入

Statement 用于执行静态SQL语句并返回执行结果,由于只能执行静态语句,所以这里会有一个问题,假设一个语句中需要动态的参数,比如where子句中的条件,那么只能通过字符串拼接的方式组装完成的SQL语句。就和我们上面写的一样,但如果此时有人写了一个必然成立的代码呢?

JDBC进行的检查就是将输入的SQL语句中的所有空格给去掉,从而进行语法检查。 

 上面这种情况叫做 SQL注入。

字符串拼接形式构造SQL语句时,如果不处理参数中的特殊字符就会造成SQL注入,这是一个非常
严重的安全性问题。别人可以通过这种手段把数据内容全部盗取,从而对公司、个人造成损失。

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应
用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

既然出现了这么严重的问题,肯定是需要解决的,因此便有了和编译代码的过程一样,进行预编译。在预编译阶段处理SQL注入的问题。

预编译SQL语句对象,SQL语句被预编译并存储在PreparedStatement对象中,可以使用该对象多次执行SQL语句,同时可以解决SQL注入问题。

优化后的JDBC

现在我们来写优化后的代码:

import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.Scanner;public class JDBC_Demo2 {public static void main(String[] args) {// 定义mysql数据源对象MysqlDataSource mysqlDataSource = new MysqlDataSource();// 设置数据连接串// urlmysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8" +"&allowPublicKeyRetrieval=true&useSSL=false");// 用户名mysqlDataSource.setUser("root");// 密码mysqlDataSource.setPassword("123456");Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;// 上面是厂商给我们提供的实现类,我们要使用Java层面的数据源接口DataSource dataSource = mysqlDataSource; // 向上转型try {// 从数据源中获取连接connection = dataSource.getConnection();// 定义执行的SQLString sql = "select id, name, age, gender from student where name = ?"; // 使用占位符// 对SQL语句进行预编译preparedStatement = connection.prepareStatement(sql);// 接收输入数据System.out.print("请输入学生姓名:");Scanner scanner = new Scanner(System.in);String name = scanner.next();// 用真实数据代替占位符preparedStatement.setString(1,name);// 执行SQL语句并接收结果集resultSet = preparedStatement.executeQuery(); // 这里不要传入SQL了while (resultSet.next()) {long stuId = resultSet.getLong(1);String stuName = resultSet.getString(2);int stuAge = resultSet.getInt(3);byte stuGender = resultSet.getByte(4);System.out.println(MessageFormat.format("学生编号{0},学生姓名{1}, 学生年龄{2}, 学生性别{3}",stuId, stuName, stuAge, stuGender));}} catch (SQLException e) {e.printStackTrace();} finally {// 关闭资源if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement != null) {try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}

上面的代码主要有两个优化的地方:

1、获取数据库连接不再是单独申请,而是在数据源中进行索取。

由于JDBC只是一组接口,因此我们没有办法直接创建数据源对象,只能通过mysql厂商提供的数据源对象来进行向上转型。而前面的获取数据连接时,是每一次都需要写入URL等数据,而数据源只需要获取一次即可,因此我们就是直接通过mysql提供的数据源对象进行设置URL等数据。

2、在优化数据源的基础上,我们还需要对SQL语句进行预编译。因此得先写一个SQL语句,并且不能再是拼接字符串的方式了,所以这里就用到了占位符。然后再让我们自己输入数据去填充占位符,接着就可以直接进行查询了。 

上面我们写的代码都是查询操作,现在我们来写一个简单的新增操作。

大体操作是一致的。

import com.mysql.cj.jdbc.CallableStatement;
import com.mysql.cj.jdbc.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class JDBC_Demo3 {public static void main(String[] args) {// 定义mysql数据源对象MysqlDataSource mysqlDataSource = new MysqlDataSource();// 设置数据连接串// URLmysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8" +"&allowPublicKeyRetrieval=true&useSSL=false");// 用户名mysqlDataSource.setUser("root");// 密码mysqlDataSource.setPassword("123456");// 上面是厂商给我们提供的实现类,我们要使用Java层面的数据源接口DataSource dataSource = mysqlDataSource;Connection connection = null;PreparedStatement preparedStatement = null;try {// 建立连接connection = dataSource.getConnection();// 定义SQL并进行预编译String sql = "insert into student values (?,?,?,?)";preparedStatement = connection.prepareStatement(sql);// 接收输入Scanner scanner = new Scanner(System.in);System.out.print("请输入新增学生编号:");long id = Long.parseLong(scanner.next()); // 不会出现问题System.out.print("请输入新增学生姓名:");String name = scanner.next();System.out.print("请输入新增学生年龄:");int age = Integer.parseInt(scanner.next());System.out.print("请输入新增学生性别:");byte gender = Byte.parseByte(scanner.next());// 替换占位符preparedStatement.setLong(1,id); // 默认从1开始的preparedStatement.setString(2, name);preparedStatement.setInt(3,age);preparedStatement.setByte(4,gender);// 执行SQL语句,并接收结果集int line = preparedStatement.executeUpdate(); // 这里返回的是受影响的行数if (line == 1) {System.out.println("新增成功!");} else {System.out.println("新增失败!");}} catch (SQLException e) {e.printStackTrace();} finally {// 依次关闭资源if (preparedStatement != null) {try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}

效果演示:

注意:

1、这里之所以全部改用next 方法,是因为其他的方法可能会出现一些预料不到的问题。

2、占位符可以有多个,是从1按照顺序开始的。

JDBC编程的两种方式对比

现在我们就来总结一下JDBC的简单使用过程。

第一种方式(不推荐使用):

1、加载数据库厂商提供的驱动包。注意:一个项目中只需加载一次,就类似于一个手机上面只能安装一个同样的应用程序(虚拟机除外)。

2、建立连接。

3、创建Statement对象

4、通过Statement对象执行SQL语句

5、处理结果集

6、关闭资源。

第二种方式(推荐使用):

1、 创建数据源对象。

        (a):使用数据库厂商提供的数据源,创建对象,设置连接串。

        (b):用Java提供的接口去接收,进行向上转型。

2、建立连接。

3、定义SQL语句,进行预编译。

4、接收真实数据,代替占位符。

5、执行SQL语语,并接收返回值。

6、关闭资源。

第二种方式的优点:

1、主要是针对SQL注入的情况,进行了预编译优化。

2、对于第一种方式频繁的建立连接,关闭资源做了优化:定义一个数据源,每次建立连接都是通其中的某一个建立连接,并且当使用完成之后,也不会真的把资源关闭,而是还给了数据源。

好啦!本期 初始MYSQL数据库(8)—— JDBC编程 的学习之旅就到此结束啦!我们下一期再一起学习吧!

相关文章:

初始MYSQL数据库(8)—— JDBC编程

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: MYSQL 目录 JDBC的概念 JDBC的使用 加载驱动包 建立连接 创建 statement 对象 定义并执行SQL语句 处理结果集 关闭资源 SQL注入 …...

Vue $router.push打开新窗口

Vue $router.push打开新窗口 最近有粉丝小伙伴问我:$router.push方法用于在当前窗口中跳转路由,但有时候我们需要在新的窗口或标签页中打开一个路由改怎么实现呢? 那么这里就介绍下实现逻辑和代码案例! 文章目录 Vue $router.pus…...

SQL进阶技巧:如何利用if语句简化where或join中的条件 | if条件语句的优雅使用方法

目录 0 问题场景 1 数据准备 2 问题分析 2.1 需求一 2.2需求二 3 小结 0 问题场景 有两张表,一张用户下单表user_purchase(用户ID粒度)包含用户ID、订单ID和下单消耗金额和一张用户维表user_info包含用户ID、用户年龄和用户是否实名认证。 user_purchase user_info 需…...

SpringCloud-Alibaba第二代微服务快速入门

1.简介 Spring Cloud Alibaba其实是阿里的微服务解决方案,是阿里巴巴结合自身微服务实践,开源的微服务全家桶,在Spring Cloud项目中孵化成为Spring Cloud的子项目。第一代的Spring Cloud标准中很多组件已经停更,如:Eureak,zuul等。所以Sprin…...

JSON字符串转换成对象

在Java中,将JSON字符串转换成对象是一个常见的操作,特别是在处理Web服务或API时。这通常通过使用第三方库来实现,因为Java标准库(Java SE)本身并不直接支持JSON的序列化和反序列化。最常用的库之一是Jackson和Gson。下…...

第三十五章 结合加密和签名

文章目录 第三十五章 结合加密和签名使用非对称密钥签名并加密使用非对称密钥加密并签名 第三十五章 结合加密和签名 可以在同一条消息中加密和签名。在大多数情况下,只需组合前面主题中给出的方法即可。本主题讨论了多种场景。 使用非对称密钥签名并加密 要签名…...

FastAPI 第八课 -- 路径操作依赖项

目录 一. 前言 二. 依赖项(Dependencies) 2.1. 依赖注入 2.2. 依赖项的使用 三. 路径操作依赖项的基本使用 3.1. 预处理(Before) 3.2. 后处理(After) 四. 多个依赖项的组合 五. 异步依赖项 一. 前…...

大厂面试真题-说一下Mybatis的缓存

首先看一下原理图 Mybatis提供了两种缓存机制:一级缓存(L1 Cache)和二级缓存(L2 Cache),旨在提高数据库查询的性能,减少数据库的访问次数。注意查询的顺序是先二级缓存,再一级缓存。…...

jQuery UI 工作原理

jQuery UI 工作原理 引言 jQuery UI 是建立在 jQuery 库之上的一个开源 JavaScript 库,它提供了一系列用户界面交互、特效、小部件和主题。它旨在简化 HTML 用户界面的开发,使开发者能够轻松地创建具有丰富交互性和视觉吸引力的网页。本文将深入探讨 jQuery UI 的工作原理,…...

CS 工作笔记:SmartEdit 里创建的是 CMS Component

下图是在 SmartEdit 里创建的 cms Component,在 Back-Office 里的截图: SAP Commerce Cloud 的 CMS Component 是其内容管理系统 (CMS) 的核心组成部分,它提供了对在线商店或平台内容的灵活管理。通过这些组件,用户能够在不涉及复…...

Java面试经验总结之SSM框架+springboot

一、spring 1.Spring 是什么? 答:spring 是一个轻量级的容器框架, ioc 和 aop 是他的核心。spring 将传统的代码以来形式,变为从容器中获取,提高了开发效率,非常的方便。spring 衍生出了很多生态&#x…...

Unity 热更新(HybridCLR+Addressable)-设置打包路径和加载路径、打开Hosting服务、打包

四、设置打包和加载路径 五、打开Hosting服务 六、打包 打包完成后路径在Assets同级目录下的ServerData 但是目前没有资源文件对比 修改上面设置后再次打包 里面多了哈希和JSON文件,这俩个就是用于资源对比...

享元(轻量级)模式

简介 享元模式(Flyweight Pattern)又叫作轻量级模式,是对象池的一种实现。类似线程池,线程池可以避免不停地创建和销毁多个对象,消耗性能。享元模式提供了减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享…...

基于php的幸运舞蹈课程工作室管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

NLP任务的详细原理与步骤的详细讲解

1. 文本分类 原理: 特征提取:文本分类首先将文本转化为数值特征,常用方法包括词袋模型、TF-IDF、Word Embeddings(如Word2Vec、GloVe)和BERT等预训练模型。模型训练:模型(如SVM、神经网络&…...

Kotlin 处理字符串和正则表达式(二十一)

导读大纲 1.1 处理字符串和正则表达式1.1.1 分割字符串1.1.2 正则表达式和三引号字符串1.1.3 多行三引号字符串IntelliJ IDEA 和 Android Studio 中三重引号字符串内部的语法高亮显示 1.1 处理字符串和正则表达式 Kotlin 字符串与 Java 字符串完全相同 可以将 Kotlin 代码中创建…...

一站式大语言模型API调用:快速上手教程

智匠MindCraft是一个强大的AI工具及开发平台,支持多种大语言模型和多模态AI模型。本文将详细介绍如何通过API调用智匠MindCraft中的大语言模型,帮助开发者快速上手。 注册与登录 访问智匠MindCraft官网,注册并登录账号。 进入开发者平台&…...

【TabBar嵌套Navigation案例-新特性页面-代码位置 Objective-C语言】

一、接下来,我们来说这个新特性页面 1.首先,看一下我们的示例程序,这里改一下,加一个叹号, command + R, 好,首先啊,这里边有一个新特性页面,当我这个程序是第一次安装、第一次运行、还有呢、就是当这个应用程序更新的时候,我应该去加载这个新特性页面, 然后呢,这…...

程序员如何提升并保持核心竞争力?——深入钻研、广泛学习与软技能的培养

一、引言  随着人工智能的不断发展,尤其是AIGC系列大语言模型的涌现,AI辅助编程工具正在日益普及,这对程序员的工作方式产生了深刻的影响。面对这一变革,程序员应如何应对?是专注于某个领域深耕细作,还是…...

Linux之Docker虚拟化部署

上传docker安装包 解压安装包 将解压后的docker文件夹移动到/usr/local/文件夹下 docker 启动命令/usr/local/docker/dockerd 但是启动报错,意思是没有docker用户组 创建docker用户组,执行完会生成套接字文件 将套接字文件加入该用户组管理 第二个错误原…...

多语言翻译工作流:OpenClaw协同千问3.5-27B实现文档自动本地化

多语言翻译工作流:OpenClaw协同千问3.5-27B实现文档自动本地化 1. 为什么需要智能翻译流水线? 去年参与一个开源项目时,我遇到了文档翻译的噩梦。团队需要将技术文档同步翻译成英、日、韩三种语言,传统流程是:先用机…...

从旋转矩阵到李代数:三维空间刚体运动的速度解析与几何直观

1. 刚体运动的基本概念:从旋转轴到角速度 想象你手里握着一个魔方,当你想让它旋转时,总会下意识地找一个转动轴。这个简单的动作背后,藏着描述三维空间刚体运动的核心数学工具。在机器人控制和计算机视觉领域,我们经常…...

2026年毕业论文写作避坑:学术AI工具怎么选才靠谱?

每到开题季,后台总会收到相似的问题:现在AI这么强,写论文到底该用哪个?不少同学的教训是——随便找个通用聊天AI,输入题目“一键生成”几万字,结果查重不过、AI检测亮红灯、参考文献全是编的,导…...

NOKOV度量光学动捕系统赋能骨科手术机器人 破解股骨骨折微创植板精度难题

在精准医疗、医疗机器人的行业发展趋势下,股骨骨干骨折微创钢板植入手术的精度难题成为骨科临床与医工交叉领域的研究重点。山东大学张勤河教授团队重磅研发双模式机器人辅助股骨干骨折钢板植入方法,依托NOKOV 度量光学三维动捕系统实现手术轨迹的精准采…...

GHelper:重构华硕笔记本硬件控制的颠覆式开源方案

GHelper:重构华硕笔记本硬件控制的颠覆式开源方案 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, …...

Phi-4-mini-reasoning保姆级教学:Web服务健康检查失败的5类根因与对策

Phi-4-mini-reasoning保姆级教学:Web服务健康检查失败的5类根因与对策 1. 问题背景与模型介绍 Phi-4-mini-reasoning 是一款专注于推理任务的文本生成模型,特别擅长处理数学题、逻辑题、多步分析和简洁结论输出。与通用聊天模型不同,它采用…...

Qwen3-14B私有部署案例:电商客服话术生成与情感倾向优化实践

Qwen3-14B私有部署案例:电商客服话术生成与情感倾向优化实践 1. 项目背景与需求分析 电商客服每天需要处理大量重复性问题,传统人工回复效率低下且难以保证一致性。我们基于Qwen3-14B模型构建了智能客服话术生成系统,主要解决以下痛点&…...

RoboStudio6.08学习记录(1)

一.软件安装一、下载RobotStudio软件官方1. 请登陆网址:https://new.abb.com/products/robotics/robotstudio。2. 单击进入页面“下载RobotStudio软件”3. 单击填写信息后,可以获得下载链接二、安装RobotStudio软件1. 下载完成后,对压缩包进行…...

Toybox代码贡献指南:从入门到精通的开源参与流程

Toybox代码贡献指南:从入门到精通的开源参与流程 【免费下载链接】toybox toybox 项目地址: https://gitcode.com/gh_mirrors/to/toybox Toybox是一个集成了多种Linux命令行工具的开源项目,通过单一的多调用二进制文件提供丰富功能。本指南将带您…...

NVIDIA Profile Inspector深度解析:解锁显卡隐藏性能与高级配置实战指南

NVIDIA Profile Inspector深度解析:解锁显卡隐藏性能与高级配置实战指南 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector NVIDIA Profile Inspector是一款面向技术爱好者和开发者的专业显卡配…...