MYSQL的Java操作器——JDBC
MYSQL的Java操作器——JDBC
在学习了Mysql之后,我们就要把Mysql和我们之前所学习的Java所结合起来
而JDBC就是这样一种工具:帮助我们使用Java语言来操作Mysql数据库
JDBC简介
首先我们先来了解一下JDBC
JDBC概念:
- JDBC是使用Java语言操作关系数据库的一套API
- 全称:(Java DataBase Connectivity)Java数据库连接
JDBC本质:
- 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
- 各个数据库厂商去实现这套接口,提供数据库驱动jar包
- 我们可以使用这套接口(JDBC)编程,真正运行的代码时驱动jar包中的实现类
JDBC优点:
- 各数据库厂商使用相同的接口,Java代码不需要针对不同数据库分别开发
- 可随时替代基层数据库,访问数据库的Java代码基本不变
JDBC快速入门
下面我们通过JDBC的基本步骤和一段实例代码来带大家体验一下JDBC
基本步骤:
// 0.创建工程,导入驱动jar包 (资源可以在网络搜索)
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获得连接
Connection conn = DriverManager.getConnection(url,username,password);
// 3.定义MYSQL语句
String sql = "~~~";
// 4.获得执行对象
Statement stmt = conn.createStatement();
// 5.执行SQL语句
stmt.executeUpdate(sql);
// 6.处理返回结果
// 7.释放资源
实例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
// JDBC快速入门
public class Demo1 {
public static void main(String[] arg) throws Exception{
// 1.注册驱动(这里是固定语法,是Java中的反射)
Class.forName("com.mysql.jdbc.Driver");
// 2.获得连接(Connection是类,最后需要释放资源)
// (url前面固定jdbc:mysql://127.0.0.1:3306/,最后加上你所需要的数据库test,username为数据库账号,password为数据库密码)
String url = "jdbc:mysql://127.0.0.1:3306/test";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
// 3.定义SQL语句(这里SQL语句与MYSQL语句相同)
String sql = "update jdbc_test set age = 20 where id = 1";
// 4.获得执行SQL对象(这里也是类)
Statement stmt = conn.createStatement();
// 5.执行SQL(注意这里返回的是count,是sql中受影响的行数)
int count = stmt.executeUpdate(sql);
// 6.返回执行结果
System.out.println(count);
// 7.释放内存
stmt.close();
conn.close();
}
}
JDBC API详解
JDBC中的API主要有四种,我们将在下面一一介绍:
DriverManager
DriverManager主要包含两个作用:
- 注册驱动
// 注册驱动是JDBC使用的第一步
Class.forName("com.mysql.jdbc.Driver");
// 上述的操作虽然是Class类的forName操作,但实际上是由Driver类的static函数组成的,如果含兴趣可以上网搜索该代码
注意:
- MYSQL5之后的版本,我们可以省略注册驱动的步骤
- 自动加载jar包中的META-INF/services/java.sql.Driver文件中的驱动类
- 获取连接
// 2.获得连接
// (url前面固定jdbc:mysql://127.0.0.1:3306/,最后加上你所需要的数据库test,username为数据库账号,password为数据库密码)
String url = "jdbc:mysql://127.0.0.1:3306/test";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
这里getConnection包含三个参数,username和password分别表示账号和密码,不需要解释
我们主要关注url的构造:
// 语法: jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2...
// 实例: String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
注意:
- 当我们是主机并在主机进行MYSQL操作时,127.0.0.1:3306可以省略不写
- 当我们正常书写时,会有warning警告,我们可以采用useSSL=false来消除警告
最后我们给出整体代码来展现DriverManager所学到的部分:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
// JDBC_DriverManager
public class Demo2 {
public static void main(String[] arg) throws Exception{
// 我们在MYSQL5.0以上版本可以省略注册驱动的步骤
// Class.forName("com.mysql.jdbc.Driver");
// 当我们在主机使用MYSQL时,可以省略27.0.0.1:3306
// 如果我们希望省略SSL警告语言可以设置关闭
String url = "jdbc:mysql:///test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
String sql = "update jdbc_test set age = 20 where id = 1";
Statement stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
System.out.println(count);
stmt.close();
conn.close();
}
}
Connection
Connection主要包含两个作用:
- 获得执行SQL对象
我们有三种方法可以获得SQL执行对象,这里先做出语法介绍,在后续我们会进行详细解释:
- 普通执行SQL对象
Statement stmt = conn.createStatement();
- 预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement pstmt = conn.prepareStatement(sql);
- 执行存储过程的对象
CallableStatement cstmt = conn,prepareCall(sql);
- 事务管理
我们可以通过Connection来进行MYSQL中的事务管理
我们通过对比MYSQL的事务来解释:
# 开启事务
BEGIN;
# 提交事务
COMMIT;
# 回滚事务
ROLLBACK;
-- mysql自动提交事务
我们的JDBC也同样提供三种方法来对应mysql事务:
// 开启事务 boolean autoCommit有两种选择:true为自动提交,false为手动提交(如果希望手动提交设置为false)
conn.setAutoCommit(boolean autoCommit)
// 提交事务
conn.commit();
// 回滚事务
conn.rollback();
最后我们给出整体代码来展现Connection所学到的部分:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
// JDBC_Connection
public class Demo3 {
public static void main(String[] arg) throws Exception{
String url = "jdbc:mysql:///test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
// 我们来研究事务的执行 (我们希望下面两条语句在一个事务中同时执行)
String sql1 = "update jdbc_test set age = 16 where id = 1";
String sql2 = "update jdbc_test set age = 16 where id = 2";
Statement stmt = conn.createStatement();
// 我们需要在try中进行,因为为了当出错时可以采用回滚方法
try {
// 开启事务
conn.setAutoCommit(false);
int count1 = stmt.executeUpdate(sql1);
System.out.println(count1);
int count2 = stmt.executeUpdate(sql2);
System.out.println(count2);
// 提交事务
conn.commit();
} catch (Exception e){
// 出错时回滚事务
conn.rollback();
}
stmt.close();
conn.close();
}
}
Statement
Statement只有一个作用:执行SQL语句
Statement的执行方式主要分为两种:
- executeUpdate(DML,DDL)
Statement可以执行Update操作,主要针对mysql的DML和DDL操作
// 下述是Statement执行DML和DDL操作的语法,sql为String类型的mysql语句
int count = stmt.executeUpdate(sql);
// 注意:返回值是DML和DDL语句所影响的行数
下面我们给出整体案例解释Statement的executeUpdate操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
// JDBC_DriverManager
public class Demo4 {
public static void main(String[] arg) throws Exception{
}
public static void test_DML() throws SQLException {
String url = "jdbc:mysql:///test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
String sql = "update jdbc_test set age = 20 where id = 1";
Statement stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
// 我们在实际页面制作时,需要给用户反馈是否成功
// 对于DML语句,当count>0时基本为操作成功
if(count>0){
System.out.println("操作成功!");
}else {
System.out.println("操作失败~");
}
stmt.close();
conn.close();
}
public static void test_DDL() throws SQLException {
String url = "jdbc:mysql:///test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
String sql = "update jdbc_test set age = 20 where id = 1";
Statement stmt = conn.createStatement();
int count = stmt.executeUpdate(sql);
// 我们在实际页面制作时,需要给用户反馈是否成功
// 对于DDL语句,DROP时count为0,所以不能用count判断,基本情况下不报错即为成功
stmt.close();
conn.close();
}
}
- executeQuery(DQL)
Statement可以执行Query操作,主要针对mysql的DQL操作
// 下述是Statement执行DQL操作的语法,sql为String类型的mysql语句
ResultSet resultSet = stmt.executeQuery(sql);
// 注意:ResultSet是stmt.executeQuery的返回类型,下面我们将着重介绍一下
ResultSet的作用:
- 封装了DQL查询语句的结果
那么如何获得ResultSet所储存的值:
// ResultSet具有next()方法,其作用是:将当前光标向前移动一行,并判断当前行是否为有效行并返回true或false
// ResultSet在获得结果后的光标指向目录行,移动一行后得到第一行数据,
boolean next():
/*
true:表示当前行有数据,可以提取或者直接输出搜索成功
false:表示当前行没有数据,表示搜索失败
*/
// ResultSet具有getXxx(参数)方法,其作用是获得当前行保存的数据
Xxx name = resultSet.getXxx(参数);
/*
Xxx 表示数据类型:Int,Double,String等
参数有两种:
1.数字参数,表示列数
2.字符串参数,表示列名
*/
// 具体遍历采用while语法
while(rs.next()){
//获得数据
int i = rs.getInt(1);
}
下面我们给出整体案例解释Statement的executeQuery操作:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
// JDBC_SQL
public class Demo5 {
public static void main(String[] arg) throws Exception{
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
// 我们接下来讲解SQL,因为SQL所获得的数据类型为ResultSet,所以我们单独讲解
// 先设置SQL语句
String sql = "select * from jdbc_test";
// 然后获得对象
Statement stmt = conn.createStatement();
// 然后开始执行语句
ResultSet resultSet = stmt.executeQuery(sql);
// 然后我们循环得到数据
// next最开始指向非数据行,然后开始执行:向下运行一行,并且判断是否为有效行
while (resultSet.next()){
// 当为有效行,获得数据(可以通过列数,也可以通过列名)
int id = resultSet.getInt("id");
String string = resultSet.getString(2);
int age = resultSet.getInt("age");
System.out.println(id);
System.out.println(string);
System.out.println(age);
System.out.println("----------------");
}
// 释放资源
resultSet.close();
stmt.close();
conn.close();
}
}
我们再给出一个mysql和Java结合的常用案例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import pojo.Student;
// JDBC_SQL案例演示
// 查询jdbc_test数据库,封装进Student对象,并存储到ArrayList集合中
public class Demo6 {
public static void main(String[] arg) throws Exception{
// 创建集合
List<Student> list = new ArrayList<>();
String url = "jdbc:mysql://127.0.0.1:3306/test?useSSL=false";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url,username,password);
// 先设置SQL语句
String sql = "select * from jdbc_test";
// 然后获得对象
Statement stmt = conn.createStatement();
// 然后开始执行语句
ResultSet resultSet = stmt.executeQuery(sql);
// 然后我们循环得到数据
while (resultSet.next()){
// 创建对象
Student s = new Student();
int id = resultSet.getInt("id");
String string = resultSet.getString(2);
int age = resultSet.getInt("age");
// 赋值
s.setId(id);
s.setName(string);
s.setAge(age);
// 把对象插入集合
list.add(s);
}
// 我们查看结果
System.out.println(list);
// 释放资源
resultSet.close();
stmt.close();
conn.close();
}
}
PreparedStatement
PreparedStatement的作用有两个:
- 预防SQL注入问题
首先我们先来介绍SQL注入问题:
我们给出一段Web端之前的账号登录匹配代码:
import com.itheima.pojo.Account;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* 用户登录
*/
public class JDBCDemo6_UserLogin {
@Test
public void testLogin() throws Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入 用户名和密码(这里直接写入,我们会在JavaWeb部分学到交互)
String name = "zhangsan";
String pwd = "fhsjkfhdsk";
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
// 获取stmt对象
Statement stmt = conn.createStatement();
// 执行sql
ResultSet rs = stmt.executeQuery(sql);
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}
}
我们可以注意到上述的sql语句采用的是字符串拼接,
因而当我们采用一些特殊字符时,就会导致mysql的搜索语句变为true,搜索到所有的mysql内容然后进入第一个账号
import com.itheima.pojo.Account;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
/**
* 用户登录
*/
public class JDBCDemo6_UserLogin {
/**
* 演示SQL注入
* @throws Exception
*/
@Test
public void testLogin_Inject() throws Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入 用户名和密码
String name = "hfkjsfhskj";
// 注意这里"' or '1' = '1"带入到sql语句中就会导致变为select * from tb_user where true
String pwd = "' or '1' = '1";
String sql = "select * from tb_user where username = '"+name+"' and password = '"+pwd+"'";
System.out.println(sql);
// 获取stmt对象
Statement stmt = conn.createStatement();
// 执行sql
ResultSet rs = stmt.executeQuery(sql);
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
stmt.close();
conn.close();
}
因而我们采用PreparedStatement来预防SQL注入问题
我们先来介绍PreparedStatement的语法:
// 获得PreparedStatement对象
// 首先我们需要设置sql语句,并且将参数用?代替
String sql = "select * from table where usename = ? and password = ?";
// 我们在创建PreparedStatement对象时需要直接将sql语句带入
PreparedStatement pstmt = conn.PreparedStatement(sql);
// 然后我们需要设置参数值
pstmt.setXxx(参数1,参数2);
/*
Xxx: 数据类型,包括Int,Double,String等
参数1:?的位置编号,从1开始
参数2:?的值
*/
// 最后执行SQL
pstmt.executeQuery();
下面我们给出整体案例解释PreparedStatement操作:
import org.junit.Test;
import java.sql.*;
import java.util.Date;
/**
* API详解:PreparedStatement
*/
public class JDBCDemo7_PreparedStatement {
@Test
public void testPreparedStatement() throws Exception {
//2. 获取连接:如果连接的是本机mysql并且端口是默认的 3306 可以简化书写
String url = "jdbc:mysql:///db1?useSSL=false";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收用户输入 用户名和密码
String name = "zhangsan";
String pwd = "' or '1' = '1";
// 定义sql
String sql = "select * from tb_user where username = ? and password = ?";
// 获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 设置?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
// 执行sql
ResultSet rs = pstmt.executeQuery();
// 判断登录是否成功
if(rs.next()){
System.out.println("登录成功~");
}else{
System.out.println("登录失败~");
}
//7. 释放资源
rs.close();
pstmt.close();
conn.close();
}
}
然后我们稍微拓展一下为什么PreparedStatement为什么不会导致字符串拼接错误:
- 因为PreparedStatement将?直接看作字符串的内容来带入,
- 你所写入的’或者“相当于/'和/",不会被当作java代码的一部分识别
- 预编译SQL,提高性能
PreparedStatement预编译原理:
- 在获得PreparedStatement对象时,将sql语句发送给mysql服务器进行检查编译(耗时)
- 执行后将不再执行这些步骤,因而速度变快
- 如果sql模板一样,则只需进行一次检查,编译
数据库连接池
首先我们对数据库连接池做出简单介绍:
- 数据库连接池是一个容器,负责分配,管理数据库连接(Connction)
- 它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
- 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
数据库连接池优点:
- 资源重用
- 提高系统响应速度
- 避免数据库连接遗漏
我们采用通俗解释来说:
- 正常情况:
我们的数据库会有很多人访问,每当来一个人操作数据库,MYSQL创建一个Connection,在这个人使用后,再将Connection删除,
这种资源重复创造删除,导致数据库效率低下
- 数据库连接池:
我们的数据库具有一定的Connection数量,当每来一个人,MYSQL分配给它一个Connection,并在使用后回收;
如果这个人的使用时间超过正常时间,MYSQL将会自动回收
数据库连接池实现
我们从三个方法讲解数据库连接池的实现:
标准接口:DataSource
- 官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口
- 功能:获得连接
Connection conn = DataSource.getConnection();
常见数据库连接池:
- DBCP
- C3P0
- Druid
Druid(德鲁伊)
- Druid连接池是阿里巴巴开发的数据库连接池
- 功能强大,性能优秀,是Java语言最好的数据库连接池之一
Druid(德鲁伊)使用
Druid的使用分为五步:
- 导入jar包
- 定义配置文件
- 加载配置文件
- 获得数据库连接池对象
- 获得连接
我们给出实例代码:
# 定义配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true
username=root
password=1234
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
/**
* Druid数据库连接池演示
*/
public class DruidDemo {
public static void main(String[] args) throws Exception {
//1.导入jar包(在网上可以找到,同JDBC包一样)
//2.定义配置文件
//3. 加载配置文件
Properties prop = new Properties();
prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
//4. 获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5. 获取数据库连接 Connection
Connection connection = dataSource.getConnection();
System.out.println(connection);
//System.out.println(System.getProperty("user.dir"));
}
}
结束语
好的,关于JDBC的内容我们就讲解到这里!
附录
该文章属于学习笔记,主要学习B站黑马JDBC视频
这里附上链接:黑马JDBC视频全套视频教程,快速入门jdbc原理+jdbc实战,一套掌握_哔哩哔哩_bilibili
MYSQL的Java操作器——JDBC的更多相关文章
- JDBC 数据库连接 Java操作数据库 jdbc快速入门
JDBC基本概念 Java DataBase Connectivity 数据库连接 java操作数据库 本质上(sun公司的程序员)定义的一套操作关系型数据库的规则 既接口 更新内容之前 代码 pa ...
- 总结java操作MySQL 即JDBC的使用
java.sql包中存在DriverManager类,Connection接口,Statement接口和ResultSet接口.类和接口作用如下: DriverManager:主要用于管理驱动程序和连 ...
- Java 操作MySql数据库
Java 项目开发中数据库操作是很重要的一个方面,对于初学者来说,MySql是比较容易熟悉的一种常见数据库,这篇文章记录了如何用Java来操作MySql数据库. 第一章 JDBC的概念 JDBC(Ja ...
- Java操作数据库——使用JDBC连接数据库
Java操作数据库——使用JDBC连接数据库 摘要:本文主要学习了如何使用JDBC连接数据库. 背景 数据持久化 数据持久化就是把数据保存到可掉电式存储设备中以供之后使用.大多数情况下,特别是企业级应 ...
- ava基础MySQL存储过程 Java基础 JDBC连接MySQL数据库
1.MySQL存储过程 1.1.什么是存储过程 带有逻辑的sql语句:带有流程控制语句(if while)等等 的sql语句 1.2.存储过程的特点 1)执行效率非常快,存储过程是数据库的服 ...
- Java操作Sqlite数据库-jdbc连接
Java操作Sqlite数据库步骤: 1. 导入Sqlite jdbc 本文使用sqlite-jdbc-3.7.2.jar,下载地址 http://pan.baidu.com/s/1kVHAGdD 2 ...
- Java连接MySQL数据库及操作
Java操作MySQL数据库,需要驱动mysql-connector-java 来进行操作,去下载对应的jar包 一.导入需要的jar包 我用的是maven对包进行管理,在maven中添加如下内容 ...
- Java数据库操作(JDBC)
JDBC Java数据库连接(Java DataBase Connectivity,JDBC)用于在Java程序中实现数据库操作功能,它提供了执行SQL语句.访问各种数据库的方法,并为各种不同的数据库 ...
- JAVA / MySql 编程——第七章 JDBC
1.JDBC:JDBA是Java数据库连接(Java DataBase Connectivity)技术的简称,提供连接各种常用数据库的能力: ●Java是通过JDBC技术实现对各种数据 ...
随机推荐
- 463. Island Perimeter - LeetCode
Question 463. Island Perimeter Solution 题目大意:给出一个二维数组1表示陆地0表示海,求陆地的周长 思路: 重新构造一张地图grid2即一个二维数组,比原数组大 ...
- unity---2d游戏杂记
2d游戏制作的笔记 save Layout 增加配置 Packges文件夹 插件 调整视野 鼠标中键 拉近拉远 鼠标右键 平移 Alt+鼠标左键 移动视角 Pivot/Center 当前物体中心和多个 ...
- CenterNet训练时黑白图片不能画框的问题
解决CenterNet在detect.py中不能画框的问题 在第centernet.py的第198行的中加上这一行 image = image.convert('RGB')
- [学习笔记] pd_ds黑科技
https://www.cnblogs.com/jiqimin/p/11226809.html 丢个链接,跑路 // Author: wlzhouzhuan #pragma GCC optimize( ...
- [刷题] IDA*
BZOJ3041 水叮当的舞步 Description & Solution 见hzw的博客 http://hzwer.com/1507.html Code // Author: wlzhou ...
- Ceph集群搭建记录
环境准备 基础环境 node00 192.168.247.144 node00 node01 192.168.247.135 node01 node02 192.168.247.143 node02 ...
- c++ 关于二分的STL 详解
一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...
- 想学设计模式、想搞架构设计,先学学UML系统建模吧您
UML系统建模 1 概述 1.1 课程概述 汇集UML及其相关的一些话题 回顾UML相关的符号与概念 以电商订单相关业务为例,借助UML完成系统建模 将UML变成提升建模效率,表达架构思想的工具 1. ...
- 【Redis】哨兵初始化和主观下线
在的redis启动函数main(server.c文件)中,对哨兵模式进行了检查,如果是哨兵模式,将调用initSentinelConfig和initSentinel进行初始化,initServer函数 ...
- OpenSSF安全计划:SBOM将驱动软件供应链安全
在 软件成分分析(SCA)一文中,我们简单提到软件物料清单(SBOM)在安全实践中的价值. 本期文章将带你深入了解 "SBOM 无处不在"计划是什么,以及 SBOM 对未来软件供应 ...