Day34

Day34

三大范式及反范式设计

第一范式:

存在问题:
1.存在非常严重的数据冗余(重复)
2.数据添加存在问题
3.数据删除存在问题

第二范式:

解决了一部分数据冗余,但仍然存在较严重的数据冗余问题,数据添加和删除问题依然存在。

第三范式:

数据冗余问题解决,数据添加和删除问题也解决,但是由于分了很多表,大大降低了查询效率。

反范式设计:
多表关联在查询时会消耗较多的时间,使用反范式设计会存在数据的冗余,但是减少了表的存在,也就是说牺牲了空间换取更多的时间

封装DBUtil(上)

编写一个工具类DBUtil,完成获取连接对象和发送sql指令对象以及关闭资源的功能。

注意:1.通过配置文件将driverName,url,username,password等参数传入。

2.工具类里面需要考虑哪些地方要处理异常,哪些地方抛出异常(涉及到具体业务的时候抛出)

package com.qf.utils;import java.io.IOException;
import java.sql.*;
import java.util.Properties;public class DBUtil {private static String url;private static String username;private static String password;static{Properties properties = new Properties();try {properties.load(DBUtil.class.getClassLoader().getResourceAsStream("DBConfig.properties"));} catch (IOException e) {throw new RuntimeException(e);}String driverName=properties.getProperty("diverName");url= properties.getProperty("url");username= properties.getProperty("username");password=properties.getProperty("password");}public static Connection getConnection() throws SQLException {Connection connection = DriverManager.getConnection(url,username,password);return connection;}public static void close(Connection connection, Statement statement, ResultSet resultSet){if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (statement!=null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(connection!=null){try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
}

配置文件:

driverName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/2042javaee?characterEncoding=utf8&serverTimezone=UTC
username=root
password=123456

使用工具类:

package com.qf.jdbc01;import com.qf.utils.DBUtil;
import org.junit.Test;import java.sql.*;/*** 知识点:JDBC
*/
public class Test01 {//增@Testpublic void test01() throws ClassNotFoundException, SQLException {//获取连接对象Connection connection = DBUtil.getConnection();//获取发送sql指令对象Statement statement = connection.createStatement();//发送sql指令String sql="insert into student(name,sex,salary,age,course) values('喜羊羊','男',5000,28,'Java');";int num = statement.executeUpdate(sql);System.out.println("对"+num+"行产生了影响");//关闭资源DBUtil.close(connection,statement,null);}//删@Testpublic void test02() throws ClassNotFoundException, SQLException {//获取连接对象Connection connection = DBUtil.getConnection();//获取发送sql指令对象Statement statement = connection.createStatement();//发送sql指令String sql="delete from student where id>8;";int num = statement.executeUpdate(sql);System.out.println("对"+num+"行产生了影响");//关闭资源DBUtil.close(connection,statement,null);}//改@Testpublic void test03() throws ClassNotFoundException, SQLException {//获取连接对象Connection connection = DBUtil.getConnection();//获取发送sql指令对象Statement statement = connection.createStatement();//发送sql指令String sql="update student set salary=30000 where id=1;";int num = statement.executeUpdate(sql);System.out.println("对"+num+"行产生了影响");//关闭资源DBUtil.close(connection,statement,null);}//查@Testpublic void test04() throws ClassNotFoundException, SQLException {//获取连接对象Connection connection = DBUtil.getConnection();//获取发送sql指令对象Statement statement = connection.createStatement();//发送sql指令String sql="select * from student;";ResultSet resultSet = statement.executeQuery(sql);//遍历结果集while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");String sex = resultSet.getString("sex");double salary = resultSet.getDouble("salary");String course = resultSet.getString("course");System.out.println(id+"--"+name+"--"+sex+"--"+salary+"--"+course);}//关闭资源DBUtil.close(connection,statement,resultSet);}
}

SQL注入问题

知识点:SQL注入问题

需求:模拟登录功能

出现原因:MySQL不知道哪些是sql命令,哪些是数据

package com.qf.jdbc02;import com.qf.utils.DBUtil;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;public class Test01 {/*** 知识点:SQL注入问题** 需求:模拟登录功能** 出现原因:MySQL不知道哪些是sql命令,哪些是数据*/public static void main(String[] args) throws SQLException {Connection connection = DBUtil.getConnection();Statement statement = connection.createStatement();Scanner scan = new Scanner(System.in);System.out.println("请输入账号:");String usernameVal = scan.nextLine();System.out.println("请输入密码:");String passwordVal = scan.nextLine();//select * from user where username='' or 1=1 #' and password='123456789'String sql = "select * from user where username='" + usernameVal + "' and password='" + passwordVal + "';";ResultSet resultSet = statement.executeQuery(sql);if(resultSet.next()){System.out.println("登录成功");String username = resultSet.getString("username");String password = resultSet.getString("password");String nickName = resultSet.getString("nick_name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");System.out.println(username + " -- " + password + " -- " + nickName + " -- " + sex + " -- " + age);}else{System.out.println("登录失败");}DBUtil.close(connection,statement,resultSet);}
}

注:当账号中输入’ or 1=1 #时,由于拼接的逻辑会变成账号输入为空(false)或者1=1(true)并且注释掉密码,然后返回值。出现原因:MySQL不知道哪些是sql命令,哪些是数据。

此类问题为SQL注入问题

解决方法:使用prepareStatement()方法告诉MySQL哪些是sql命令,哪些是数据。

package com.qf.jdbc02;import com.qf.utils.DBUtil;import java.sql.*;
import java.util.Scanner;public class Test02 {/*** 知识点:SQL注入问题** 需求:模拟登录功能** 出现原因:MySQL不知道哪些是sql命令,哪些是数据* 解决方案:告诉MySQL哪些是sql命令,哪些是数据*/public static void main(String[] args) throws SQLException {Connection connection = DBUtil.getConnection();//获取PreparedStatement对象String sql = "select * from user where username=? and password=?";PreparedStatement statement = connection.prepareStatement(sql);//设置参数Scanner scan = new Scanner(System.in);System.out.println("请输入账号:");String usernameVal = scan.nextLine();System.out.println("请输入密码:");String passwordVal = scan.nextLine();statement.setString(1,usernameVal);statement.setString(2,passwordVal);ResultSet resultSet = statement.executeQuery();if(resultSet.next()){System.out.println("登录成功");String username = resultSet.getString("username");String password = resultSet.getString("password");String nickName = resultSet.getString("nick_name");String sex = resultSet.getString("sex");int age = resultSet.getInt("age");System.out.println(username + " -- " + password + " -- " + nickName + " -- " + sex + " -- " + age);}else{System.out.println("登录失败");}DBUtil.close(connection,statement,resultSet);}
}

注:由于已经传入了sql命令,并且已经用set方法传入了参数,所以后面提交命令的时候不用再次传入sql。

主键回填

主键回填(Key Backfilling)是指在数据库插入操作后,自动生成的主键(通常是自增的主键值)被返回并填充到应用程序中相应的对象或变量中的过程。这在许多应用场景中非常有用,因为插入一条新记录后,我们往往需要立即知道这条记录的唯一标识符(主键)以便进行后续的操作,如更新、删除或关联到其他数据。

在 JDBC 中,通过使用 PreparedStatement和 RETURN_GENERATED_KEYS 常量,可以实现主键回填。

public static int commonInsert(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);paramsHandler(statement,params);statement.executeUpdate();resultSet = statement.getGeneratedKeys();int primaryKey = 0;if(resultSet.next()){primaryKey = resultSet.getInt(1);}return primaryKey;} finally {close(connection,statement,resultSet);}}

封装DBUtil(中)

动态地将查询结果填充到指定类型的对象中,适用于许多不同类型的查询和数据对象。

public static <T> List<T> commonQuery(Class<T> clazz,String sql,Object... params) throws SQLException, InstantiationException, IllegalAccessException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramsHandler(statement,params);resultSet = statement.executeQuery();//获取表信息对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int fieldCount = metaData.getColumnCount();List<T> list = new ArrayList<>();while(resultSet.next()){//创建对象T t = clazz.newInstance();for (int i = 1; i <= fieldCount ; i++) {//获取字段名String fieldName = metaData.getColumnName(i);//获取该数据行上对应字段的数据Object val = resultSet.getObject(fieldName);//利用反射设置对象里对应的属性setField(t,fieldName,val);}//将对象添加到List集合中list.add(t);}return list;} finally {close(connection,statement,resultSet);}}

其中获取属性和设置属性方法为:

/*** 获取当前类及其父类的属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/private static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置对象中的属性* @param obj 对象* @param name 属性名* @param value 属性值*/private static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}

事务

事务是数据库执行的工作单位,一条SQL语句默认认为是一个事务,事务是自动管理提交的。若想多条SQL语句同时实行完毕,就需要将多条SQL语句放在同一个事务里

# 开启事务
START TRANSACTION;UPDATE bank SET money=money-200 WHERE name='aaa';
UPDATE bank SET money=money+200 WHERE name='bbb';# 提交事务:将事务提交给数据库管理系统
# COMMIT;# 回滚事务:将数据回滚到开启事务的状态
ROLLBACK;

JDBC中操作:

public class Test01 {/*** 知识点:事务** 需求:模拟银行用户转账*/public static void main(String[] args) {Connection connection = null;PreparedStatement statement1 = null;PreparedStatement statement2 = null;try {connection = DBUtil.getConnection();//开启事务connection.setAutoCommit(false);String sql1 = "UPDATE bank SET money=money-200 WHERE name='aaa';";statement1 = connection.prepareStatement(sql1);statement1.executeUpdate();System.out.println(10/0);String sql2 = "UPDATE bank SET money=money+200 WHERE name='bbb';";statement2 = connection.prepareStatement(sql2);statement2.executeUpdate();//提交事务connection.commit();} catch (Exception e) {//回滚事务//通过在进行数据库操作(如回滚、提交或关闭)之前检查 connection 对象是否为 null,可以避免空指针异常if(connection != null){try {connection.rollback();} catch (SQLException ex) {throw new RuntimeException(ex);}}System.out.println("发生异常,回滚事务了");} finally {DBUtil.close(null,statement2,null);DBUtil.close(connection,statement1,null);}}
}

但是转账逻辑中应该是同一个连接,并且多个转账事件同时发生时应该有自己的连接。因此要对DBUtil进行修改。

封装DBUtil(下)

使用ThreadLocal,确保每个线程有自己的连接。

package com.qf.utils;import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;public class DBUtil {private static String url;private static String username;private static String password;static{Properties properties = new Properties();try {properties.load(DBUtil.class.getClassLoader().getResourceAsStream("DBConfig.properties"));} catch (IOException e) {throw new RuntimeException(e);}String driverName = properties.getProperty("driverName");url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");try {Class.forName(driverName);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}local = new ThreadLocal<>();}private static ThreadLocal<Connection> local;/*** 开启事务*/public static void startTransaction() throws SQLException {Connection connection = getConnection();connection.setAutoCommit(false);}/*** 提交事务*/public static void commit() throws SQLException {Connection connection = local.get();if(connection != null){connection.commit();connection = null;}}/*** 回滚事务*/public static void rollback() throws SQLException {Connection connection = local.get();if(connection != null){connection.rollback();connection = null;}}/*** 获取连接对象*/public static Connection getConnection() throws SQLException {Connection connection = local.get();if(connection == null){connection = DriverManager.getConnection(url, username, password);local.set(connection);}return connection;}/*** 关闭资源*/public static void close(Connection connection, Statement statement, ResultSet resultSet)  {if(resultSet != null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(statement != null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(connection != null){try {if(connection.getAutoCommit()) {//自动提交事务的情况下connection.close();local.set(null);}} catch (SQLException e) {throw new RuntimeException(e);}}}/*** 更新数据(添加、删除、修改)*/public static int commonUpdate(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramsHandler(statement,params);int num = statement.executeUpdate();return num;} finally {close(connection,statement,null);}}/*** 主键回填*/public static int commonInsert(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);paramsHandler(statement,params);statement.executeUpdate();resultSet = statement.getGeneratedKeys();int primaryKey = 0;if(resultSet.next()){primaryKey = resultSet.getInt(1);}return primaryKey;} finally {close(connection,statement,resultSet);}}public static <T> List<T> commonQuery(Class<T> clazz,String sql,Object... params) throws SQLException, InstantiationException, IllegalAccessException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramsHandler(statement,params);resultSet = statement.executeQuery();//获取表信息对象ResultSetMetaData metaData = resultSet.getMetaData();//获取字段个数int fieldCount = metaData.getColumnCount();List<T> list = new ArrayList<>();while(resultSet.next()){//创建对象T t = clazz.newInstance();for (int i = 1; i <= fieldCount ; i++) {//获取字段名String fieldName = metaData.getColumnName(i);//获取该数据行上对应字段的数据Object val = resultSet.getObject(fieldName);//利用反射设置对象里对应的属性setField(t,fieldName,val);}//将对象添加到List集合中list.add(t);}return list;} finally {close(connection,statement,resultSet);}}/*** 处理sql命令中的参数*/private static void paramsHandler(PreparedStatement statement,Object... params) throws SQLException {for (int i = 0; i < params.length; i++) {statement.setObject(i+1,params[i]);}}/*** 获取当前类及其父类的属性对象* @param clazz class对象* @param name 属性名* @return 属性对象*/private static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 设置对象中的属性* @param obj 对象* @param name 属性名* @param value 属性值*/private static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}

场景

package com.qf.jdbc04;import com.qf.utils.DBUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class Test02 {/*** 知识点:事务** 需求:模拟银行用户转账*/public static void main(String[] args) {//转账的场景
//        try {
//            DBUtil.startTransaction();
//
//            subtraction("aaa",200);
//
//            //System.out.println(10/0);
//
//            addition("bbb",200);
//
//            DBUtil.commit();
//        } catch (Exception e) {
//            try {
//                DBUtil.rollback();
//            } catch (SQLException ex) {
//                throw new RuntimeException(ex);
//            }
//        }//单独存取钱的场景try {subtraction("aaa",500);} catch (SQLException e) {throw new RuntimeException(e);}try {addition("bbb",1000);} catch (SQLException e) {throw new RuntimeException(e);}}public static void addition(String name,float money) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = DBUtil.getConnection();System.out.println(connection);String sql = "UPDATE bank SET money=money+? WHERE name=?;";statement = connection.prepareStatement(sql);statement.setFloat(1,money);statement.setString(2,name);statement.executeUpdate();} finally {DBUtil.close(connection,statement,null);}}public static void subtraction(String name,float money) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = DBUtil.getConnection();System.out.println(connection);String sql = "UPDATE bank SET money=money-? WHERE name=?;";statement = connection.prepareStatement(sql);statement.setFloat(1,money);statement.setString(2,name);statement.executeUpdate();} finally {DBUtil.close(connection,statement,null);}}}

事务的特点

事务的特性:ACID

原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )和持久性( Durability )

原子性:事务是数据库的逻辑工作单位,事务中包含的各操作要么都完成,要么都不完成

一致性:事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性状态。如果数据库系统 运行中发生故障,有些事务尚未完成就被迫中断,这些未完成事务对数据库所做的修改有一部分已写入物理数据库,这时数据库就处于一种不正确的状态,或者说是 不一致的状态。

**隔离性:**一个事务的执行不能其它事务干扰。即一个事务内部的操作及使用的数据对其它并发事务是隔离的,并发执行的各个事务之间不能互相干扰。

持久性:指一个事务一旦提交,它对数据库中的数据的改变就应该是永久性的。接下来的其它操作或故障不应该对其执行结果有任何影响。

事务的隔离级别:

属于事务的。都已开启了事务为前提。

不考虑事务的隔离级别,会出现以下的情况

l 脏读:一个线程中的事务读到了另外一个线程中未提交的数据。

l 不可重复读:一个线程中的事务读到了另外一个线程中已经提交的update的数据。

l 虚读:一个线程中的事务读到了另外一个线程中已经提交的insert的数据。

要想避免以上现象,通过更改事务的隔离级别来避免:

l READ UNCOMMITTED 脏读、不可重复读、虚读有可能发生。

l READ COMMITTED 避免脏读的发生,不可重复读、虚读有可能发生。

l REPEATABLE READ 避免脏读、不可重复读的发生,虚读有可能发生。

l SERIALIZABLE 避免脏读、不可重复读、虚读的发生。

set transaction isolation level READ UNCOMMITTED;

级别依次升高,效率依次降低。

MySQL:默认REPEATABLE READ

ORACLE:默认READ COMMITTED

JDBC中设置隔离级别:

//设置事务的隔离界别connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);

批处理

在jdbc的url中添加rewriteBatchedStatements=true参数,可以提高批处理执行效率。

url=jdbc:mysql://localhost:3306/2042javaee?characterEncoding=utf8&serverTimezone=UTC&rewriteBatchedStatements=true

知识点:批处理
理解:批量处理数据

需求:批量执行多条sql语句,sql语句不相同

public static void main(String[] args) throws SQLException {Connection connection = DBUtil.getConnection();Statement statement = connection.createStatement();//把多条SQL语句添加到Batch包中String sql1 = "INSERT INTO student(name,sex,age,salary,course) VALUES('aaa','女',24,8000,'HTML');";String sql2 = "update student set salary=99999 where id=1";statement.addBatch(sql1);statement.addBatch(sql2);//发送Batch包statement.executeBatch();DBUtil.close(connection,statement,null);}

需求:批量插入100条记录,sql语句相同,只是参数值不同

 public static void main(String[] args) throws SQLException {Connection connection = DBUtil.getConnection();String sql = "INSERT INTO student(name,sex,age,salary,course) VALUES(?,'男',24,8000,'HTML')";PreparedStatement statement = connection.prepareStatement(sql);for (int i = 1; i <= 100; i++) {statement.setString(1,"xxx" + i);statement.addBatch();}statement.executeBatch();DBUtil.close(connection,statement,null);}

当数据量过大时,采用批处理 + 事务,减少提交次数

public static void main(String[] args) throws SQLException {Connection connection = DBUtil.getConnection();connection.setAutoCommit(false);String sql = "INSERT INTO student(name,sex,age,salary,course) VALUES(?,'男',24,8000,'HTML')";PreparedStatement statement = connection.prepareStatement(sql);for (int i = 1; i <= 10000; i++) {statement.setString(1,"yyy" + i);statement.addBatch();if(i%1000 == 0){statement.executeBatch();statement.clearBatch();//清空数据包中的sql命令}}connection.commit();DBUtil.close(connection,statement,null);}

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

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

相关文章

Java学习-JDBC(五)

JDBC优化及工具类封装 现有问题 ①创建连接池②获取连接③连接回收 ThreadLocal 为解决多线程程序的并发问题提供了一种新的思路&#xff0c;使用这个工具类可以很简洁地编写出优美的多线程程序&#xff0c;通常用在多线程中管理共享数据库连接、Session等ThreadLocal用于保…

leetcode hot100 补充

除了 hot100 外&#xff0c;还有一些常见的题目&#xff0c;也是值得我们复习的。我们新开一个 补充 栏目&#xff0c;进行梳理。 hot 100补充 回溯法 回溯法 medium 组合之和 II dfs

6.全开源源码---小红书卡片-跳转微信-自动回复跳转卡片-商品卡片-发私信-发群聊-安全导流不封号-企业号白号都可以用

现在用我们的方法&#xff0c;可以规避违规风险&#xff0c;又可以丝滑引流&#xff0c;因为会以笔记的形式发给客户&#xff0c;点击之后直接跳微信&#xff0c;我们来看看演示效果吧&#xff08;没有风险提示&#xff09; 无论是引流还是销售产品都会事半功倍。

关于如何设置 TMOD (定时/计数 高低 共 8 位 寄存器)

TMOD 寄存器简介 TMOD 是 8051 单片机的定时器模式寄存器。它是一个 8 位寄存器&#xff0c;用于配置定时器/计数器的工作模式。TMOD 的每一位有特定的含义。 TMOD 的结构如下&#xff1a; GATE | C/T | M1 | M0 | GATE | C/T | M1 | M07 | 6 | 5 | 4 | 3 | 2 | …

python使用聚类分析来分析数据

""" 聚类分析 """ import os import pandas as pd #导入处理二维表格的库 import numpy as np #导入数值计算的库 from sklearn.preprocessing import StandardScaler #导入数据标准化模块 import matplotlib.pyplot as plt #导入画…

搞懂银行的各类号码 — Account Number, Routing Number 和 Swift Code

1. 前言2. 名词解释 2.1. Debit Card Number 储蓄卡卡号2.2. Account Number 账户号码2.3. Routing Number 路由号码2.4. SWIFT Code SWIFT 号码3. 查找信息 3.1. 支票3.2. 网上银行3.3. 手机银行4. SWFIT Code 4.1. 看懂 SWIFT Code4.2. 询问银行4.3. Google 大神4.4. 部分常用…

MySQL: 表的增删改查(基础)

文章目录 1. 注释2. 新增(Create)3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重: distinct3.6 排序: order by3.7条件查询3.8 分页查询 4. 修改 (update)5. 删除(delete)6. 内容重点总结 1. 注释 注释&#xff1a;在SQL中可以使用“–空格…

Day 25 二叉树的终止

450.删除二叉搜索树中的节点 不理解用tmp保存root节点&#xff0c;然后删除&#xff1f;rootroot->right不会覆盖吗&#xff1f; 需要考虑要删除的节点是不是叶子节点&#xff0c;有无左右孩子 有左右孩子的话&#xff0c;需要将左孩子节点移动到右孩子节点的左面节点的左…

了解常用智能指针

智能指针 1、概念 C中引入智能指针的主要目的是为了解决内存管理的问题&#xff0c;传统的指针&#xff08;裸指针&#xff09;在使用时需要手动分配和释放内存&#xff0c;容易出现内存泄漏和悬挂指针等问题。智能指针通过封装裸指针&#xff0c;并提供自动内存管理功能&…

一、Socket创建和连接

C网络编程&#xff08;asio&#xff09; 文章目录 C网络编程&#xff08;asio&#xff09;1、Asio概述2、网络编程基本流程2、创建socket3、创建监听socket4、绑定accpet监听套接字5、连接指定的端点6、服务器接收连接 点击查看代码 1、Asio概述 ​ Asio起源于Boost库&#xf…

shell编程(三)—— 运算符

和其他编程语言一样&#xff0c;bash也有多种类型的运算符&#xff0c;本篇对bash的相关运算符做简单介绍。 一、运算符 1.1 算术运算符 常见的算术运算符&#xff0c;如加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xf…

OpenGauss数据库-4.表的创建、修改与删除

第1关&#xff1a;创建表 gsql -d postgres -U gaussdb -W passwd123123 create database testdb; \c testdb; passwd123123 create table test_table (test_id integer not null,test_info char(36)); 第2关&#xff1a;修改表 gsql -d testsb -U gaussdb -W passwd123123 …

YOLOv5的predict.py逐句讲解(学习笔记)

因为太多依赖python的各种库,导致自己对YOLO的开发能力有所下降,最近准备重新整理一下YOLO系列的代码以供以后自己查阅。 YOLOv5-v7.0将分类脱离出来了。predict.py为分类的推理代码。predict.py主要有run(),parse_opt(),main()三个函数构成。 一、导入模块 这部分导入pyth…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 机场航班调度程序(100分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 📎在线评测链接 🌍 评测功能需要订阅专栏后私信联系清隆解锁~ 文章目录 …

Flink 基于 TDMQ Apache Pulsar 的离线场景使用实践

背景 Apache Flink 是一个开源的流处理和批处理框架&#xff0c;具有高吞吐量、低延迟的流式引擎&#xff0c;支持事件时间处理和状态管理&#xff0c;以及确保在机器故障时的容错性和一次性语义。Flink 的核心是一个分布式流数据处理引擎&#xff0c;支持 Java、Scala、Pytho…

DeepSORT(目标跟踪算法)中的马氏距离详解(很详细)

DeepSORT&#xff08;目标跟踪算法&#xff09;中的马氏距离详解&#xff08;很详细&#xff09; flyfish 马氏距离的公式是由印度统计学家【普拉萨纳钱德拉马哈拉诺比斯&#xff08;Prasanta Chandra Mahalanobis&#xff09;】&#xff09;&#xff08;好长的名字&#xff…

怎样快速获取Vmware VCP 证书,线上考试,voucher报名优惠

之前考一个VCP证书&#xff0c;要花大一万的费用&#xff0c;可贵了&#xff0c;考试费不贵&#xff0c;贵就贵在培训费&#xff0c;要拿到证书&#xff0c;必须交培训费&#xff0c;即使vmware你玩的很溜&#xff0c;不需要再培训了&#xff0c;但是一笔贵到肉疼的培训费你得拿…

哈希表与哈希扩容

一&#xff0c;哈希表 哈希表简单的理解&#xff1a;在记录的存储位置和它的关键字之间建立一个确定的对应关系f&#xff0c;使每个关键字和结构中一个唯一的存储位置相对应。 哈希表基于数组的&#xff0c;正因为数组创建后难于扩展某些哈希表被基本填满时&#xff0c;性能下…

JS类型转换面试题:[] == ![] 为true?

前言 OK,又是在学习的路上遇到了难点&#xff0c;今天拿来分享一哈。ok&#xff0c;话不多说&#xff0c;开始分享。 下面是一道面试题 console.log([]![])你觉得上面的值打印为多少&#xff1f;我告诉你&#xff0c;打印的结果是true。如果你是猜对的或者不会可以看看我对这…

Python从入门到精通的学习路径

Python从入门到精通的学习路径 基础语法&#xff1a; 学习Python的基本语法&#xff0c;包括变量、数据类型、运算符、流程控制&#xff08;如if、else、for、while&#xff09;等。参考书籍或在线教程&#xff0c;如《Python从入门到精通》系列教程&#xff0c;特别是“Pytho…