01_JDBC
文章目录
- 一、概述
- 1.1、什么是JDBC
- 1.2、JDBC原理
- 二、JDBC入门
- 2.1、准备工作
- 2.1.1、建库建表
- 2.1.2、新建项目
- 2.2、建立连接
- 2.2.1、准备四大参数
- 2.2.2、加载驱动
- 2.2.3、准备SQL语句
- 2.2.4、建立连接
- 2.2.5、常见问题
- 2.3、获取发送SQL的对象
- 2.4、执行SQL语句
- 2.5、处理结果
- 2.6、释放资源
- 2.7、完整代码
- 2.8、上面的程序改进
- 2.9、改进后的完整代码
- 三、查询操作
- 3.1、获取结果集
- 3.2、处理结果集
- 3.3、查询操作完整代码
- 四、PreparedStatement
- 4.1、SQL注入
- 4.1.1、什么是SQL注入
- 4.1.2、SQL注入案例
- 4.1.2、如何避免SQL注入
- 4.2、PreparedStatement使用
- 4.2.1、预编译SQL语句
- 4.2.2、设置参数
- 4.2.3、完整代码
- 五、使用JDBC进行CRUD操作(掌握)
- 5.1、添加操作
- 5.2、删除操作
- 5.3、修改操作
- 5.4、查询操作
- 六、封装工具类
- 6.1、工具类
- 6.2、工具类使用
一、概述
1.1、什么是JDBC
JDBC(Java DataBase Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。
简单说就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
1.2、JDBC原理
早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API实现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动。
JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。
JDBC – Java官方提供 – 一系列接口 – 规范
驱动 – 数据库厂商提供 – JDBC接口的实现类 – 实现
二、JDBC入门
2.1、准备工作
2.1.1、建库建表
DROP DATABASE IF EXISTS mydbjdbc;CREATE DATABASE mydbjdbc;
USE mydbjdbc;CREATE TABLE tb_stu ( sid INT PRIMARY KEY auto_increment, sname VARCHAR (50), sage INT, sgender VARCHAR (10)
);
INSERT INTO tb_stu(sname, sage, sgender) VALUES('John', 20, "male");
INSERT INTO tb_stu(sname, sage, sgender) VALUES('bob', 20, "male");CREATE TABLE USER(username VARCHAR (20), password VARCHAR (20)
);
INSERT INTO USER VALUES('Peter', '123');
INSERT INTO USER VALUES('John', '123');
2.1.2、新建项目
- 新建Java项目;
- 在项目下新建lib目录;
- 将MySQL驱动jar包拷贝到lib目录下;
- 选中lib目录右键Add as Library–单击OK。
2.2、建立连接
2.2.1、准备四大参数
//驱动名
String driverName = "com.mysql.jdbc.Driver";
//连接数据库的url
String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";
//用户名
String username = "root";
//密码
String password = "root";
2.2.2、加载驱动
//手动加载字节码文件到JVM中
Class.forName(driverName);
2.2.3、准备SQL语句
//SQL语句
String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('Peter', 20, 'male')";
2.2.4、建立连接
//建立连接
Connection connection = DriverManager.getConnection(url, username, password);//验证是否成功建立连接
System.out.println(connection);
如果能够正常输出连接信息,说明连接建立成功,这是后续一切操作的基础。
2.2.5、常见问题
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
原因:项目中没有添加MySQL驱动或驱动的名字写错
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
原因:用户名或密码错误
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'mydbjdbc1'
原因:数据库名称不正确
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago
原因:MySQL服务没有启动或网络故障
2.3、获取发送SQL的对象
Statement statement = connection.createStatement();
2.4、执行SQL语句
//使用Statement发送SQL语句,返回受影响的行数
int i = statement.executeUpdate(sql);
增、删、改使用
executeUpdate
查询使用
executeQuery
2.5、处理结果
if(i == 1) {System.out.println("添加成功");
}
2.6、释放资源
遵循先开后关原则,释放所使用到的资源对象。
//释放资源
statement.close();
connection.close();
资源对于系统来说非常重要,而且是有限的,用完之后一定要释放。
2.7、完整代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class TestJdbc1 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//SQL语句String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('Peter', 20, 'male')";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//System.out.println(connection);Statement statement = connection.createStatement();//发送SQL语句int i = statement.executeUpdate(sql);//处理结果if(i == 1) {System.out.println("添加成功");}//释放资源statement.close();connection.close();}
}
举一反三,我们可以按照上面的套路进行删除、修改操作。
2.8、上面的程序改进
我们在进行添加或其他操作时,SQL语句中的内容是不可能在程序中写死的,在数据库中操作的数据一定是能够变化的。我们对程序进行如下修改,其他部分不变。
//假设用户输入的数据
String name = "zs";
int age = 10;
String gender = "male";//SQL语句
//String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('Peter', 20, 'male')";
String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('" + name + "', " + age + ", '" + gender + "')";
通过上面的修改,我们就可以通过Java代码向数据库中添加变化的数据而不是在代码中写死。
同理,删除和修改操作也可以按照这样的套路进行操作。
2.9、改进后的完整代码
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class TestJdbc2 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//假设用户输入的数据String name = "zs";int age = 10;String gender = "male";//SQL语句//String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('Peter', 20, 'male')";String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES('" + name + "', " + age + ", '" + gender + "')";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//System.out.println(connection);Statement statement = connection.createStatement();//发送SQL语句int i = statement.executeUpdate(sql);//处理结果if(i == 1) {System.out.println("添加成功");}//释放资源statement.close();connection.close();}
}
三、查询操作
查询操作和增删改操作在结果处理上有很大区别,我们有必要深入研究一下。
3.1、获取结果集
//假设用户输入的数据
int stuid = 1;//SQL语句
String sql = "SELECT * FROM tb_stu WHERE sid=" + stuid;
//建立连接
Connection connection = DriverManager.getConnection(url, username, password);//System.out.println(connection);
Statement statement = connection.createStatement();
//发送SQL语句,获取结果集
ResultSet resultSet = statement.executeQuery(sql);
查询使用
executeQuery
3.2、处理结果集
ResultSet 以表(table)结构进行临时结果的存储,需要通过JDBC API将其中数据进行依次获取。
- 数据行指针:初始位置在第一行数据前,每调用一次
boolean next()
方法ResultSet的指针向下移动一行,结果为 true,表示当前行有数据;resultSet.getXxx(整数)
:代表根据列的编号顺序获得,从1开始(一定要注意);resultSet.getXxx("列名")
:代表根据列名获得。
int getInt(int columnIndex) throws SQLException //获得当前行第N列的int值
int getInt(String columnLabel) throws SQLException //获得当前行columnLabel列的int值double getDouble(int columnIndex) throws SQLException //获得当前行第N列的double值
double getDouble(String columnLabel) throws SQLException //获得当前行columnLabel列的double值String getString(int columnIndex) throws SQLException //获得当前行第N列的String值
String getString(String columnLabel) throws SQLException //获得当前行columnLabel列的String值//处理结果
while(resultSet.next()) {int id = resultSet.getInt("sid");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");String sgender = resultSet.getString("sgender");System.out.println(id);System.out.println(sname);System.out.println(sage);System.out.println(sgender);
}
3.3、查询操作完整代码
import java.sql.*;public class TestJdbc3 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//假设用户输入的数据int stuid = 1;//SQL语句String sql = "SELECT * FROM tb_stu WHERE sid=" + stuid;//建立连接Connection connection = DriverManager.getConnection(url, username, password);//System.out.println(connection);Statement statement = connection.createStatement();//发送SQL语句ResultSet resultSet = statement.executeQuery(sql);//处理结果while(resultSet.next()) {int id = resultSet.getInt("sid");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");String sgender = resultSet.getString("sgender");System.out.println(id);System.out.println(sname);System.out.println(sage);System.out.println(sgender);}//释放资源resultSet.close();statement.close();connection.close();}
}
四、PreparedStatement
4.1、SQL注入
4.1.1、什么是SQL注入
用户输入的数据中有SQL关键字或语法并且参与了SQL语句的编译,导致SQL语句编译后的条件含义为true,一直得到正确的结果。这种现象称为SQL注入。
4.1.2、SQL注入案例
import java.sql.*;public class TestJdbc4 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//假设用户输入的数据String n = "abc' OR 1=1 OR '1=1";String p = "123";//SQL语句String sql = "SELECT * FROM user WHERE username='" + n + "' AND password='" + p + "'";System.out.println(sql);//建立连接Connection connection = DriverManager.getConnection(url, username, password);//System.out.println(connection);Statement statement = connection.createStatement();//发送SQL语句ResultSet resultSet = statement.executeQuery(sql);//处理结果while(resultSet.next()) {System.out.println(resultSet.getString("username"));System.out.println(resultSet.getString("password"));}//释放资源resultSet.close();statement.close();connection.close();}
}
4.1.2、如何避免SQL注入
由于编写的SQL语句是在用户输入数据,整合后再进行编译。所以为了避免SQL注入的问题,我们要使SQL语句在用户输入数据前就已进行编译成完整的SQL语句,再进行填充数据。
使用PreparedStatement。
4.2、PreparedStatement使用
PreparedStatement继承了Statement接口,执行SQL语句的方法无异。
作用:
- 预编译SQL 语句,效率高。
- 安全,避免SQL注入 。
- 可以动态的填充数据,执行多个同构的 SQL 语句。
4.2.1、预编译SQL语句
//SQL语句
String sql = "SELECT * FROM user WHERE username=? AND password=?";//预编译SQL语句
PreparedStatement statement = connection.prepareStatement(sql);
4.2.2、设置参数
String n = "abc' OR 1=1 OR '1=1";
String p = "123";//设置参数
statement.setString(1, n);
statement.setString(2, p);
4.2.3、完整代码
import java.sql.*;public class TestJdbc5 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//假设用户输入的数据String n = "abc' OR 1=1 OR '1=1";String p = "123";//SQL语句String sql = "SELECT * FROM user WHERE username=? AND password=?";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//预编译SQL语句PreparedStatement statement = connection.prepareStatement(sql);//设置参数statement.setString(1, n);statement.setString(2, p);//发送SQL语句ResultSet resultSet = statement.executeQuery();//处理结果while(resultSet.next()) {System.out.println(resultSet.getString("username"));System.out.println(resultSet.getString("password"));}//释放资源resultSet.close();statement.close();connection.close();}
}
五、使用JDBC进行CRUD操作(掌握)
在项目实战中,推荐使用PreparedStatement而不是使用Statement。
以下的代码必须熟练掌握,能够举一反三,这是后续学习的基础。
5.1、添加操作
import java.sql.*;public class TestJdbc6 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//SQL语句String sql = "INSERT INTO tb_stu(sname, sage, sgender) VALUES(?, ?, ?)";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//创建PreparedStatementPreparedStatement pstmt = connection.prepareStatement(sql);pstmt.setString(1, "zhangsan");pstmt.setInt(2, 20);pstmt.setString(3, "male");//发送SQL语句int i = pstmt.executeUpdate();//处理结果if(i == 1) {System.out.println("添加成功");}//释放资源pstmt.close();connection.close();}
}
5.2、删除操作
import java.sql.*;public class TestJdbc7 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//SQL语句String sql = "DELETE FROM tb_stu WHERE sid=?";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//创建PreparedStatementPreparedStatement pstmt = connection.prepareStatement(sql);pstmt.setInt(1, 5);//发送SQL语句int i = pstmt.executeUpdate();//处理结果if(i == 1) {System.out.println("删除成功");}//释放资源pstmt.close();connection.close();}
}
5.3、修改操作
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class TestJdbc8 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//SQL语句String sql = "UPDATE tb_stu SET sage=? WHERE sid=?";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//创建PreparedStatementPreparedStatement pstmt = connection.prepareStatement(sql);pstmt.setInt(1, 25);pstmt.setInt(2, 1);//发送SQL语句int i = pstmt.executeUpdate();//处理结果if(i == 1) {System.out.println("修改成功");}//释放资源pstmt.close();connection.close();}
}
5.4、查询操作
import java.sql.*;public class TestJdbc9 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//驱动名String driverName = "com.mysql.jdbc.Driver";//连接数据库的urlString url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";//用户名String username = "root";//密码String password = "root";//加载驱动Class.forName(driverName);//SQL语句String sql = "SELECT * FROM tb_stu WHERE sgender=?";//建立连接Connection connection = DriverManager.getConnection(url, username, password);//预编译SQL语句PreparedStatement statement = connection.prepareStatement(sql);//设置参数statement.setString(1, "male");//发送SQL语句ResultSet resultSet = statement.executeQuery();//处理结果while(resultSet.next()) {int sid = resultSet.getInt("sid");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");String sgender = resultSet.getString("sgender");System.out.println(sid + "---" + sname + "---" + sage + "---" + sgender);}//释放资源resultSet.close();statement.close();connection.close();}
}
六、封装工具类
上面的代码大部分是重复的,我们有必要把重复的代码进行提取。
6.1、工具类
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JdbcUtil {//定义成员变量用来保存四大参数private static String driverName;private static String url;private static String username;private static String password;static {try {//读取配置文件到输入流InputStream in = JdbcUtil.class.getResourceAsStream("/jdbc.properties");Properties properties = new Properties();//加载配置文件中的数据到Properties中properties.load(in);//获取四大参数driverName = properties.getProperty("jdbc.driverName");url = properties.getProperty("jdbc.url");username = properties.getProperty("jdbc.username");password = properties.getProperty("jdbc.password");//加载驱动Class.forName(driverName);} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}//获取连接public static Connection getConnection() {Connection connection = null;try {connection = DriverManager.getConnection(url, username, password);} catch (SQLException throwables) {throwables.printStackTrace();}return connection;}//释放资源public static void close(Connection connection, Statement statement, ResultSet rSet) {try {if(rSet != null) {rSet.close();}if(statement != null) {statement.close();}if(connection != null) {connection.close();}} catch (SQLException throwables) {throwables.printStackTrace();}}
}
6.2、工具类使用
在src下创建jdbc.properties文件
jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false
jdbc.username=root
jdbc.password=root
在Java代码中使用工具类
import tech.code2048.utils.JdbcUtil;import java.sql.*;public class TestJdbc10 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//SQL语句String sql = "SELECT * FROM tb_stu WHERE sgender=?";//建立连接 --- 使用工具类Connection connection = JdbcUtil.getConnection();//预编译SQL语句PreparedStatement statement = connection.prepareStatement(sql);//设置参数statement.setString(1, "male");//发送SQL语句ResultSet resultSet = statement.executeQuery();//处理结果while(resultSet.next()) {int sid = resultSet.getInt("sid");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");String sgender = resultSet.getString("sgender");System.out.println(sid + "---" + sname + "---" + sage + "---" + sgender);}//释放资源 --- 使用工具类JdbcUtil.close(connection, statement, resultSet);}
}
通过使用工具类,我们的代码变得简洁更容易维护。
相关文章:
01_JDBC
文章目录 一、概述1.1、什么是JDBC1.2、JDBC原理 二、JDBC入门2.1、准备工作2.1.1、建库建表2.1.2、新建项目 2.2、建立连接2.2.1、准备四大参数2.2.2、加载驱动2.2.3、准备SQL语句2.2.4、建立连接2.2.5、常见问题 2.3、获取发送SQL的对象2.4、执行SQL语句2.5、处理结果2.6、释…...
三层架构与分层解耦:深入理解IOC与DI设计模式
目录 一、软件架构演进与三层架构概述 1.1 从单体架构到分层架构 1.2 经典三层架构详解 1.3 三层架构的优势 二、分层解耦的核心思想 2.1 耦合与解耦的基本概念 2.2 分层解耦的实现手段 2.3 分层解耦的实践原则 三、控制反转(IOC)深度解析 3.1…...
[react]Next.js之自适应布局和高清屏幕适配解决方案
序言 阅读前首先了解即将要用到的两个包的作用 1.postcss-pxtorem 自动将 CSS 中的 px 单位转换为 rem 单位按照设计稿尺寸直接写 px 值,由插件自动计算 rem 值 2.amfe-flexible 动态设置根元素的 font-size(即 1rem 的值)根据设备屏幕宽度和…...
TensorFlow深度学习实战——基于语言模型的动态词嵌入技术
TensorFlow深度学习实战——基于语言模型的动态词嵌入技术 0. 前言1. 基于语言模型的词嵌入1.1 ELMo 与 ULMFiT1.2 GPT1.3 BERT 2. 使用 BERT 作为特征提取器相关链接 0. 前言 基于语言模型的词嵌入技术,通过利用上下文信息来生成动态的词向量,大大提升…...
欧拉服务器操作系统部署deekseep(Ollama+DeekSeep+open WebUI)
一、解压并安装 Ollama # 1. 解压文件(默认会得到一个二进制文件) tar -xzvf ollama-linux-amd64.tgz# 2. 将二进制文件安装到系统路径 sudo mv ollama /usr/local/bin/ sudo chmod x /usr/local/bin/ollama# 3. 验证安装 ollama --version链接…...
cocosCreator安卓隐私弹窗(链接版)
每次新上游戏都要重新弄这个隐私弹窗,记录一下下次直接抄。 一、创建Activity 1 用androidStudio 打开项目并切换到Android视角。 2 右键项目new一个空的Activity 3 修改Activity的名字并完成如下图 二、增加依赖文件 1 增加全局颜色定义文件:项目根目录 / res/values/ …...
统计销量前十的订单
传入参数: 传入begin和end两个时间 返回参数 返回nameList和numberList两个String类型的列表 controller层 GetMapping("/top10")public Result<SalesTop10ReportVO> top10(DateTimeFormat(pattern "yyyy-MM-dd") LocalDate begin,Dat…...
【Python爬虫】简单案例介绍2
本文继续接着我的上一篇博客【Python爬虫】简单案例介绍1-CSDN博客 目录 跨页 3.2 环境准备 跨页 当对单个页面的结构有了清晰的认识并成功提取数据后,接下来就需要考虑页面之间的跨页问题。此时我们便迎来了下一个关键任务:如何实现跨页爬取…...
适合单片机裸机环境的运行的软件定时器框架
如下这篇文档介绍了一个适用于裸机环境的软件定时器模块,其核心功能和实现如下: 模块功能:该模块通过硬件定时器中断实现时基累加,适合用于裸机程序的调度处理。它使用硬件定时中断(如1ms一次)来增加hw_ti…...
【ComfyUI】蓝耘元生代 | ComfyUI深度解析:高性能AI绘画工作流实践
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能(AI)通过算法模拟人类智能,利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络(如ChatGPT&…...
js的es6模块中 暴露的使用方法简介
在 JavaScript 的 ES6 模块系统中,一个模块文件只能有一个 export default。export default 用于导出一个默认值,这个默认值在导入时可以使用任意名称。 示例: 导出默认值: // myModule.jsexport default function greet() {con…...
基于Android的旅游自助APP(源码+lw+部署文档+讲解),源码可白嫖!
摘要 旅游自助APP设计的目的是为用户提供对景点信息和路线攻略、周边美食等方面的平台。 与PC端应用程序相比,旅游自助的设计主要面向于旅行者,旨在为用户提供一个旅游自助。用户可以通过APP及时景点信息,并对景点进行购票或收藏等。相反&am…...
SQL(7):合并字段,使用UNION,首先应使用SELECT进行检索,再使用UMION进行拼接
核心功能:合并查询结果 想象一下,你有两个不同的名单,你想把它们合并成一个大名单。UNION 和 UNION ALL 都是 SQL 里用来干这个“合并名单”的活儿的。它们可以把两个(或更多)SELECT 查询语句的结果合并到一起&#x…...
Spring MVC 全栈指南:RESTful 架构、核心注解与 JSON 实战解析
目录 RESTful API 设计规范Spring MVC 核心注解解析静态资源处理策略JSON 数据交互全解高频问题与最佳实践 一、RESTful API 设计规范 1.1 核心原则 原则说明示例 URI资源为中心URI 使用名词(复数形式)/users ✔️ /getUser ❌HTTP 方法语义化GET&…...
【第43节】实验分析windows异常分发原理
目录 前言 一、异常处理大致流程图 二、实验一:分析 KiTrap03 三、实验二:分析CommonDispatchException 四、代码探究:分析 KiDispatchException 函数 五、代码探究:伪代码分析用户层KiUserExceptionDispatcher 前言 在Wind…...
自动化测试概念篇
文章目录 目录1. 自动化1.1 自动化概念1.1.1 回归测试 1.2 自动化分类1.3 自动化测试金字塔 2. web自动化测试2.1 驱动2.1.1 安装驱动管理2.1.2 selenium库 3. Selenium3.1 一个简单的web自动化示例3.2 selenium驱动浏览器的工作原理 目录 自动化web自动化测试Selenium 1. 自…...
「数据可视化 D3系列」之开篇:开启数据可视化之旅
一、系列介绍 欢迎来到《快速学习D3.js》系列!在这个系列中,我们将一起从零开始掌握D3.js(Data-Driven Documents),一个强大的JavaScript库,用于创建动态、交互式的数据可视化。 无论你是前端开发者、数据…...
编译构建 WSO2 产品时的一些注意事项
编译构建 WSO2 产品时的一些注意事项 1、JDK 版本2、maven 版本3、npm 和 node 版本4、编译命令示例 1、JDK 版本 对于 WSO2 ESB、WSO2 EI 老产品,可以直接使用 JDK 1.8对于 WSO2 APIM、WSO2 IS、WSO2 MI 等产品的新版本,需要 JDK 11 以上 特别注意&…...
字符串与相应函数(下)
字符串处理函数分类 求字符串长度:strlen长度不受限制的字符串函数:strcpy,strcat,strcmp长度受限制的字符串函数:strncpy,strncat,strncmp字符串查找:strstr字符串切割:strtok错误信息报告:strerror字符操作…...
驾驭 Linux 云: JavaWeb 项目安全部署
目录 1. 引言 2. Linux 基础指令 2.1 ls 展示目录/文件 2.2 pwd 查看所在路径 2.3 mkdir 创建文件夹 2.4 cd 切换路径 2.5 touch 创建文件 2.6 rm 删除文件 2.6 rm -r/rf 删除文件夹 2.7 rz/sz 上传/下载文件 2.7.1 rz 上传文件 2.7.2 sz 下载文件 2.8 mv 移动文件…...
【MySQL数据库】InnoDB存储引擎:逻辑存储结构、内存架构、磁盘架构
逻辑存储结构 一个数据库是由一张张表组成的,而表中是由一个个段构成的,一个段是由区构成的,区空间是由页构成的,页是行构成的。 ①表空间:.ibd文件,一个mysql实例可以对应多个表空间,用于存储…...
HJ16 购物单
https://www.nowcoder.com/exam/oj/ta?tpId37 HJ16 购物单 描述 王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件。 主件可以没有附件,至多有 2个附件。附件不再有从属于自己的附件。如果要买归类为附件的物品,必…...
SLAM文献之DM-VIO: Delayed Marginalization Visual-Inertial Odometry
1. 算法概述 DM-VIO (Delayed Marginalization Visual-Inertial Odometry) 是一种基于延迟边缘化的视觉-惯性里程计算法,它结合了视觉和惯性测量单元(IMU)的数据进行位姿估计。该算法是VINS-Mono的改进版本,主要创新点在于采用了一种延迟边缘化策略&…...
【信息安全】黑芝麻A1000芯片安全启动方案
基于黑芝麻A1000芯片的安全启动方案实现指南: 一、安全启动流程架构设计 // 启动阶段状态机定义(基于A1000芯片手册) typedef enum {ROM_BOOT = 0x01, // BootROM验证 SPL_VERIFY = 0x02, // 二级加载器验证 ATF_SIGN_CHECK = 0x03, // ARM Trusted Firmware验证 OS_LOADE…...
初识Redis · list和hash类型
目录 前言: 哈希类型 基本命令 编码方式 应用场景 列表 基本命令 编码方式 应用场景 前言: 前文我们已经介绍了string的基本使用,以及对应的基本命令,最后也是简单的理解了一下string的应用场景,比如计数统计…...
golang-非orm数据库的操作与对比 database/sql、sqlx 和 sqlc
简单介绍 database/sql database/sql 是一个标准库软件包,负责与数据库(主要是 SQL 关系数据库)的连接和交互。 它为类 SQL 交互提供泛型接口、类型和方法。database/sql 在创建时将简单易用纳入考量,配置为支持与类 SQL 数据库…...
DeepSeek模型在非图形智能体的应用中是否需要GPU
答:不一定 概念 1、是否需要GPU与应用是否图形处理应用无关 2、文本内容智能体大多也需要GPU来提供更好的性能 3、DeepSeek模型在非图形智能体的应用中是否需要GPU取决于具体的模型版本和部署环境 不需要GPU的模型版本 DeepSeek-R1-1.5B: 这…...
RadioMaster POCKET遥控器进入ExpressLRS界面一直显示Loading的问题解决方法
RadioMaster POCKET遥控器进入ExpressLRS界面一直显示Loading的问题解决方法 问题描述解决方法 问题描述 有一天我发现我的 RadioMaster POCKET 遥控器进入 ExpressLRS 设置界面时,界面却一直停留在 “Loading” 状态,完全无法进入设置界面。 我并没有…...
idea的快捷键使用以及相关设置
文章目录 快捷键常用设置 快捷键 快捷键作用ctrlshift/注释选中内容Ctrl /注释一行/** Enter文档注释ALT SHIFT ↑, ALT SHIFT ↓上下移动当前代码Ctrl ALT L格式化代码Ctrl X删除所在行并复制该行Ctrl D复制当前行数据到下一行main/psvm快速生成入口程序soutSystem.o…...
【DDR 内存学习专栏 1.4 -- DDR 的 Bank Group】
文章目录 BankgroupBankgroup 与 Bank 的关系 DDR4 中的 BankgroupDDR4-3200 8Gb芯片为例组织结构访问场景 实际应用示例 Bankgroup Bankgroup是DDR4及后续标准(DDR5)中引入的一个更高层次的组织结构。它将多个Bank组合在一起形成一个Bankgroup,目的是为了进一步提…...
新晋前端框架技术:小程序容器与SuperApp构建
2025年,前端开发领域持续迭代,主流框架如Vue、React等纷纷推出新版本,在性能、开发效率及适用场景上实现突破,进一步巩固其技术地位。 1. Vue 3的全面普及与创新 Vue 3通过多项核心特性优化了开发体验: Teleport组件…...
强化学习:基于价值的方法做的是回归,基于策略的方法做的是分类,可以这么理解吗?
在强化学习领域,基于价值的方法(Value-based Methods)和基于策略的方法(Policy-based Methods)是两种核心范式。本文将从目标函数、优化机制以及与机器学习任务的类比角度,探讨这两种方法是否可以被分别理解为回归和分类任务,并深入分析其内在逻辑。 一、基于价值的方法…...
蓝耘元生代AIDC OS:一站式MaaS平台,助力AI应用快速落地
文章目录 引言1. 什么是MaaS平台?MaaS平台的典型特点 2. 蓝耘元生代AIDC OS 热门模型3. 快速入门:如何调用API?步骤1:注册并获取API Key步骤2:调用API(Python示例) 4. 与Chatbox搭配使用&#x…...
3.2.2.3 Spring Boot配置拦截器
在Spring Boot应用中配置拦截器(Interceptor)可以对请求进行预处理和后处理,实现如权限检查、日志记录等功能。通过实现HandlerInterceptor接口并注册到Spring容器,拦截器可以自动应用到匹配的请求路径。案例中,创建了…...
Python----机器学习(基于PyTorch的蘑菇逻辑回归)
Logistic Regression(逻辑回归)是一种用于处理二分类问题的统计学习方法。它基于线性回归 模型,通过Sigmoid函数将输出映射到[0, 1]范围内,表示概率。逻辑回归常被用于预测某个实 例属于正类别的概率。 一、数据集介绍 本例使用了…...
Python----机器学习(基于PyTorch的乳腺癌逻辑回归)
Logistic Regression(逻辑回归)是一种用于处理二分类问题的统计学习方法。它基于线性回归 模型,通过Sigmoid函数将输出映射到[0, 1]范围内,表示概率。逻辑回归常被用于预测某个实 例属于正类别的概率。 一、数据集介绍 在本例中&…...
如何配置AWS EKS自动扩展组:实现高效弹性伸缩
本文详细讲解如何在AWS EKS中配置节点组(Node Group)和Pod的自动扩展,优化资源利用率并保障应用高可用。 一、准备工作 工具安装 安装并配置AWS CLI 安装eksctl(EKS管理工具) 安装kubectl(Kubernetes命令…...
【C++ Qt】认识Qt、Qt 项目搭建流程(图文并茂、通俗易懂)
每日激励:“不设限和自我肯定的心态:I can do all things。 — Stephen Curry” 绪论: 本章将开启Qt的学习,Qt是一个较为古老但仍然在GUI图形化界面设计中有着举足轻重的地位,因为它适合嵌入式和多种平台而被广泛使用…...
用Python打造去中心化知识产权保护系统:科技驱动创作者权益新方案
用Python打造去中心化知识产权保护系统:科技驱动创作者权益新方案 近年来,区块链技术和去中心化系统的兴起为知识产权保护提供了新的可能性。在传统模式下,知识产权保护通常依赖于集中化管理机构,这种方式不仅成本高,还可能因不透明导致权益争议。于是,我们萌生了一个设…...
CVE重要漏洞复现-Fastjson1.2.24-RCE漏洞
本文仅供网络学习,不得用于非法目的,否则后果自负 1、漏洞简介 fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,也可以从JSON字符串反序列化到JavaBean。即fastjson的主要功能就是将Java Bean序列化成JSON字符…...
Windows 图形显示驱动开发-WDDM 1.2功能—显示设备硬件软件认证要求
一、容器技术id技术的硬件级实现要求 1.1 EDID规范深度适配 1.物理层要求: 必须使用EDID 2.0及以上版本数据结构 容器ID需写入VSDB区块的0x50-0x6F区域,采用Little-Endian格式存储 允许的最大传输延迟:I2C总线时钟频率≤100KHz时…...
Coze流搭建--写入飞书多维表格
目标 使用coze搭建一个业务流,将业务流生产出的数据写入飞书保存 测试业务流 使用图片生成插件,配置prompt生产图片,将生产的结果写入飞书文档 coze流 运行后最终效果 搭建流程 第一步:飞书创建多维表格 注册飞书创建多维表…...
4.14:计组第三章
一、数据的强制类型转换与存储 1、边界对齐与大端小端方式 2、真-强制类型转换 二、存储器的基本知识(不包含磁盘存储器) 1、主存储器 (1)...
Vue3+Vite前端项目部署后部分图片资源无法获取、动态路径图片资源报404错误的原因及解决方案
目录 Vue3vite前端项目部署后部分图片资源无法获取、动态路径图片资源报404错误的原因及解决方案 一、情景介绍 1、问题出现的场景 2、无法加载的图片写法 二、反向代理原理简介 三、造成该现象的原因 四、解决方案 1、放弃动态渲染 2、在页面挂载的时候引入图片资源 …...
Nacos操作指南
第一章:Nacos 概述 1.1 什么是 Nacos? 定义与定位 Nacos(Naming and Configuration Service)是阿里巴巴于2018年开源的动态服务发现、配置管理和服务管理平台,现已成为微服务生态中的重要基础设施。其核心价值在于帮…...
2025年常见渗透测试面试题-红队面试宝典下(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 一、Java反序列化过程及利用链示例 二、大型网络渗透经验 三、Cobalt Strike的两种Dump Hash区别 四…...
扩增子分析|基于R语言microeco包进行微生物群落网络分析(network网络、Zi-Pi关键物种和subnet子网络图)
一、引言 microeco包是福建农林大学姚敏杰教授团队开发的扩增子测序集成分析。该包综合了扩增子测序下游分析的多种功能包括群落组成、多样性、网络分析、零模型等等。通过简单的几行代码可实现复杂的分析。因此,microeco包发表以来被学界广泛关注,截止2…...
flutter-Text等组件出现双层黄色下划线的问题
文章目录 1. 现象2. 原因3. 解决方法 1. 现象 这天我正在写Flutter项目的页面功能,突然发现我的 Text 文字出现了奇怪的样式,具体如下: 文字下面出现了双层黄色下划线文字的空格变得很大,文字的间距也变得很大 我百思不得其解&a…...
优化运营、降低成本、提高服务质量的智慧物流开源了
智慧物流视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本可通过边缘计算技术…...
leetcode第二题
功能函数 typedef struct ListNode {int val;struct ListNode *next; } ListNode;struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {ListNode *dummy (ListNode *)malloc(sizeof(ListNode));ListNode *cur dummy;int carry 0; //carry是进位值…...