《手写Spring渐进式源码实践》实践笔记(第十八章 JDBC功能整合)

文章目录

  • 第十八章 JDBC功能整合
    • 背景
      • 技术背景
        • JDBC
      • JdbcTemplate
        • 关键特性
      • 用法示例
      • 业务背景
    • 目标
    • 设计
    • 实现
      • 代码结构
      • 类图
      • 实现步骤
    • 测试
      • 事先准备
      • 属性配置文件
      • 测试用例
      • 测试结果:
    • 总结


第十八章 JDBC功能整合

背景

技术背景

JDBC

JDBC(Java Database Connectivity)是一个Java API,用于连接和执行查询在数据库中。它提供了一种标准的方法,允许Java程序连接到各种关系型数据库执行SQL语句,并处理结果。JDBC是一个强大的工具,它为Java应用程序提供了与数据库交互的能力,无论是进行数据检索还是更新。通过使用JDBC,开发者可以编写可移植的代码,这些代码可以在不同的数据库系统之间运行,而无需对代码进行大量修改。

以下是JDBC的一些关键点介绍:

  1. 数据库连接
    • JDBC使用DriverManager类来管理数据库连接。通过传递数据库URL、用户名和密码,可以获取到一个Connection对象,该对象代表与特定数据库的连接。
  2. 驱动程序
    • JDBC驱动程序是一个允许Java应用程序与数据库进行交互的软件组件。JDBC驱动程序可以是类型1(原生方法)、类型2(基于Java的独立驱动程序)、类型3(纯Java驱动程序,使用JDBC网络协议)、类型4(JDBC驱动程序,使用数据库的薄客户端)。
  3. Statement和PreparedStatement
    • Statement对象用于执行静态SQL语句,并返回它所生成的结果。
    • PreparedStatementStatement的子接口,它允许预编译SQL语句,可以提高性能并防止SQL注入攻击。
  4. 执行SQL语句
    • 通过StatementPreparedStatement对象,可以执行各种SQL语句,包括查询(SELECT)、更新(UPDATE、DELETE)、插入(INSERT)和DDL(CREATE、DROP等)语句。
  5. 处理结果
    • 查询数据库后,可以通过ResultSet对象处理返回的数据。ResultSet提供了一种方式来遍历查询结果集中的数据。
  6. 事务处理
    • JDBC支持事务处理,默认情况下,每个Statement执行的SQL语句都是自动提交的。可以通过Connection对象来设置自动提交模式,并使用commit()rollback()方法来管理事务。
  7. 批处理
    • JDBC提供了批处理功能,允许一次执行多个SQL语句,这可以减少网络往返次数,提高性能。
  8. 元数据
    • DatabaseMetaData接口提供了关于数据库的整体元数据信息,如表的结构、存储过程、支持的SQL语法等。
  9. 关闭资源
    • 为了释放数据库资源,应该在使用完毕后关闭ResultSetStatementConnection对象。
  10. 异常处理
    • JDBC操作可能会抛出SQLException,因此需要适当的异常处理机制来确保程序的健壮性。

JdbcTemplate

JdbcTemplate 是 Spring 框架中提供的一个用于简化 JDBC 编程的模板类。它处理了资源的创建和释放,并且提供了执行 SQL 语句和查询的便捷方法,从而减少了编写 JDBC 代码时常见的样板代码。

以下是 JdbcTemplate 的一些关键特性和用法:

关键特性
  1. 简化资源管理JdbcTemplate 管理数据库连接,确保在每次执行后都正确关闭连接,从而避免了资源泄漏。

  2. 异常处理:它将 JDBC 的 SQLException 转换为 Spring 的 DataAccessException,这使得异常处理更加一致和易于管理。

  3. 便捷的方法:提供了多种便捷方法来执行 SQL 语句,包括 update(用于执行插入、更新、删除等)、query(用于执行查询)以及 queryForObjectqueryForMapqueryForList 等。

  4. 参数化查询:支持使用 PreparedStatement 来执行参数化查询,从而防止 SQL 注入攻击。

  5. 结果集处理:提供了将结果集映射到 Java 对象的功能,包括将单行结果映射到一个对象,将多行结果映射到一个列表等。

用法示例

以下是一个简单的 JdbcTemplate 用法示例:

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;public class JdbcTemplateExample {public static void main(String[] args) {// 配置数据源DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/yourdatabase");dataSource.setUsername("yourusername");dataSource.setPassword("yourpassword");// 创建 JdbcTemplate 实例JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);// 执行查询String sql = "SELECT * FROM your_table WHERE id = ?";Object[] params = new Object[] { 1 };Map<String, Object> result = jdbcTemplate.queryForMap(sql, params);// 输出查询结果System.out.println(result);// 执行更新String updateSql = "UPDATE your_table SET name = ? WHERE id = ?";Object[] updateParams = new Object[] { "new name", 1 };int rowsAffected = jdbcTemplate.update(updateSql, updateParams);// 输出更新结果System.out.println("Rows affected: " + rowsAffected);}
}

在这个示例中,我们首先配置了一个 DriverManagerDataSource,然后创建了一个 JdbcTemplate 实例。接着,我们使用 JdbcTemplate 执行了一个查询操作和一个更新操作,并输出了相应的结果。

业务背景

  1. 日常开发过程中,离不开和数据库的交互。JDBC提供了Java应用程序提供与数据库交互的能力,无论是进行数据检索还是更新。

  2. JDBC交互的套路操作有:

    • 配置数据库账号、密码、连接信息等参数

    • 打开数据库连接

    • 根据业务需求编写sql语句

    • 预编译并执行sql语句

    • 处理执行结果

    • 处理抛出的异常

    • 处理事务

    • 关闭数据库连接

  3. 为了方便Spring框架与数据库的交互,我们需要将上述过程进行抽象化,实现jdbcTemplate模板类, 来执行jdbc交互的大部分通用步骤,形成spring-jdbc模块。spring-jdbc接收参数信息、JdbcTemplate接收业务需求sql进行处理并返回结果,应用返回结果数据。

目标

基于当前实现的 Spring 框架,实现jdbcTempate模板类,完成spring对jdbc调用的封装。

设计

为了方便Spring框架与数据库的交互,我们需要将JDBC交互的过程进行抽象化,实现jdbcTemplate模板类, 来执行jdbc交互的大部分通用步骤。整体设计结构如下图:

image-20241109173926098

  • 首先定义好JdbcTemplate类需要支持的操作,包括:解析数据源参数、获取数据源、获取连接、预编译执行sql、处理执行结果、处理异常、关闭连接。

  • 通过JdbcTemplate类封装了和JDBC的交互细节,用户只需要通过调用jdbcTemplate方法,就可以很方便的完成数据库交互。

实现

代码结构

image-20241105182058764

源码实现:https://github.com/swg209/spring-study/tree/main/step18-spring-jdbc

类图

image-20241105182058764
  1. 在整个类图中,通过JdbcAccessor实现InitializingBean,将jdbcTemplate接入当前框架。数据源相关通过DataSourceUtils来接入,JdbcTemplate实现了jdbcOperation定义的接口,实现与数据库的交互操作。

DataSource

​ 用来提供Connection,之所以有那么多辅助类(ConnectionHanlder、ConnectionHandle)是为了可以和数据库事务结合

JdbcTemplate

这个类是进行执行操作的入口类,里面有很多重载方法。

  • T execute(StatementCallback action, boolean closeResources)

    这个是JdbcTemplate内部的私有实现方法,JdbcOperations接口中定义的一系列execute()方法也是调用的该方法

JdbcOperations

这个接口定义了非常多的入口方法,实现类就是JdbcTemplate

  • T query(String sql, ResultSetExtractor rse)

  • T query(String sql, ResultSetExtractor rse)

    这个是query系列方法的最后调用方法,该方法会调用JdbcTemplate内部的私有execute方法。

ResultSetExtractor

  • 进行数据库查询之后会得到结果集即:ResultSet,这个类用于结果集数据提取

RowMapper

  • 用于将结果集每行数据转换为需要的类型

实现步骤

  1. 数据源连接类,DataSourceUtils提供Connection。

    public abstract class DataSourceUtils {public static Connection getConnection(DataSource dataSource) {try {return doGetConnection(dataSource);} catch (SQLException e) {throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", e);}}public static Connection doGetConnection(DataSource dataSource) throws SQLException {Connection connection = fetchConnection(dataSource);ConnectionHolder holderToUse = new ConnectionHolder(connection);return connection;}private static Connection fetchConnection(DataSource dataSource) throws SQLException {Connection conn = dataSource.getConnection();if (null == conn) {throw new IllegalArgumentException("DataSource return null from getConnection():" + dataSource);}return conn;}public static void releaseConnection(Connection con, DataSource dataSource) {try {doReleaseConnection(con, dataSource);} catch (SQLException ex) {
    //            logger.debug("Could not close JDBC Connection", ex);} catch (Throwable ex) {
    //            logger.debug("Unexpected exception on closing JDBC Connection", ex);}}public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {if (con == null) {return;}doCloseConnection(con, dataSource);}public static void doCloseConnection(Connection con, DataSource dataSource) throws SQLException {con.close();}
    }

    涉及连接的多个接口类,包括ConnectionHandler、ConnectionHolder, 以及实现类SimpleConnectionHandler。

    public interface ConnectionHandler {Connection getConnection();default void releaseConnection(Connection con) {}}public class ConnectionHolder {private ConnectionHandler connectionHandler;private Connection currentConnection;public ConnectionHolder(ConnectionHandler connectionHandler) {this.connectionHandler = connectionHandler;}public ConnectionHolder(Connection connection) {this.connectionHandler = new SimpleConnectionHandler(connection);}public ConnectionHandler getConnectionHandler() {return connectionHandler;}protected boolean hasConnection() {return this.connectionHandler != null;}protected void setConnection(Connection connection) {if (null != this.currentConnection) {if (null != this.connectionHandler) {this.connectionHandler.releaseConnection(this.currentConnection);}this.currentConnection = null;}if (null != connection) {this.connectionHandler = new SimpleConnectionHandler(connection);} else {this.connectionHandler = null;}}protected Connection getConnection() {Assert.notNull(this.connectionHandler, "Active connection is required.");if (null == this.currentConnection) {this.currentConnection = this.connectionHandler.getConnection();}return this.currentConnection;}}public class SimpleConnectionHandler implements ConnectionHandler {private final Connection connection;public SimpleConnectionHandler(Connection connection) {Assert.notNull(connection, "Connection must not be null");this.connection = connection;}@Overridepublic Connection getConnection() {return this.connection;}}
  2. 核心类 JdbcTemplate内部完成核心方法

    public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {private <T> T execute(StatementCallback<T> action, boolean closeResources) {Connection con = DataSourceUtils.getConnection(obtainDataSource());Statement stmt = null;try {stmt = con.createStatement();applyStatementSettings(stmt);return action.doInStatement(stmt);} catch (SQLException e) {String sql = getSql(action);JdbcUtils.closeStatement(stmt);stmt = null;throw translateException("ConnectionCallback", sql, e);} finally {if (closeResources) {JdbcUtils.closeStatement(stmt);}}}private <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, boolean closeResources) {Assert.notNull(psc, "PreparedStatementCreator must not be null");Assert.notNull(action, "Callback object must not be null");Connection con = DataSourceUtils.getConnection(obtainDataSource());PreparedStatement ps = null;try {ps = psc.createPreparedStatement(con);applyStatementSettings(ps);T result = action.doInPreparedStatement(ps);return result;} catch (SQLException ex) {String sql = getSql(psc);psc = null;JdbcUtils.closeStatement(ps);ps = null;DataSourceUtils.releaseConnection(con, getDataSource());con = null;throw translateException("PreparedStatementCallback", sql, ex);} finally {if (closeResources) {JdbcUtils.closeStatement(ps);DataSourceUtils.releaseConnection(con, getDataSource());}}}public <T> T query(PreparedStatementCreator psc, final PreparedStatementSetter pss, final ResultSetExtractor<T> rse) {Assert.notNull(rse, "ResultSetExtractor must not be null");return execute(psc, new PreparedStatementCallback<T>() {@Overridepublic T doInPreparedStatement(PreparedStatement ps) throws SQLException {ResultSet rs = null;try {if (pss != null) {pss.setValues(ps);}rs = ps.executeQuery();return rse.extractData(rs);} finally {JdbcUtils.closeResultSet(rs);}}}, true);}......
    }
    
  3. JdbcOperations 数据库交互操作接口.

    1. StatementCallback 会话回调接口,用于执行任意的JDBC Statement操作
    2. RowMapper 行处理接口,用于将结果集的每一行映射到Java对象
    3. ResultSetExtractor 结果集处理接口,用于从整个ResultSet中提取数据。
    4. PreparedStatementSetter 预编译接口,用于设置PreparedStatement的参数值。
    5. RowMapperResultSetExtractor 自定义接口或类,用于结合RowMapper和ResultSetExtractor的功能来处理结果集。
    6. RawMapper -> ColumnRawMapper 、 SingleColumnRawMapper.
      • RawMapper原始映射器接口或类的泛称,用于处理结果集的原始列数据。
      • ColumnRawMapper列原始映射器,用于将结果集的特定列映射到某个类型。
      • SingleColumnRawMapper单列原始映射器,用于将只返回一列数据的查询结果映射到某个类型。
    public interface JdbcOperations {<T> T execute(StatementCallback<T> action);void execute(String sql);//---------------------------------------------------------------------// query//---------------------------------------------------------------------<T> T query(String sql, ResultSetExtractor<T> res);<T> T query(String sql, Object[] args, ResultSetExtractor<T> rse);<T> List<T> query(String sql, RowMapper<T> rowMapper);<T> List<T> query(String sql, Object[] args, RowMapper<T> rowMapper);<T> T query(String sql, PreparedStatementSetter pss, ResultSetExtractor<T> rse);//---------------------------------------------------------------------// queryForList//---------------------------------------------------------------------List<Map<String, Object>> queryForList(String sql);/*** 查询数据库表中某一个字段*/<T> List<T> queryForList(String sql, Class<T> elementType);<T> List<T> queryForList(String sql, Class<T> elementType, Object... args);List<Map<String, Object>> queryForList(String sql, Object... args);//---------------------------------------------------------------------// queryForObject//---------------------------------------------------------------------<T> T queryForObject(String sql, RowMapper<T> rowMapper);<T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper);/*** 查询数据库表中 某一条记录的 某一个字段*/<T> T queryForObject(String sql, Class<T> requiredType);//---------------------------------------------------------------------// queryForMap//---------------------------------------------------------------------Map<String, Object> queryForMap(String sql);Map<String, Object> queryForMap(String sql, Object... args);}
    

测试

事先准备

mysql数据库,配置好连接信息, 建表语句。(也可以后续执行ApiTest#executeSqlTest 完成建表 )

#创建数据库
CREATE DATABASE mybatis;#创建用户表
USE mybatis;CREATE TABLE user (`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',`username` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '用户名',PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

属性配置文件

spring.xml

  1. 配置数据库源连接信息,注册jdbcTemplate bean。

  2. 我本地的mysql版本是8.0.33,对应的mysql-connector-java也是 8.0.33,留意pom.xml文件,加上该依赖

  3. &amp; 是为了转义&符号,不加&amp;allowPublicKeyRetrieval=true,会报java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed
    错误,这个异常通常出现在尝试使用JDBC连接到MySQL数据库时,特别是当使用SSL连接到MySQL 8.0或更高版本时。这个异常的原因是JDBC驱动程序默认不允许从服务器检索公钥,这是出于安全考虑,以防止中间人攻击(MITM)。
    
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="dataSource"class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClass" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl"value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;allowPublicKeyRetrieval=true"/><property name="username" value="root"/><property name="password" value="123456"/></bean><bean id="jdbcTemplate"class="cn.suwg.springframework.jdbc.support.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean></beans>

测试用例

public class ApiTest {private JdbcTemplate jdbcTemplate;@Beforepublic void init() {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");jdbcTemplate = applicationContext.getBean(JdbcTemplate.class);}@Testpublic void executeSqlTest() {jdbcTemplate.execute("CREATE TABLE user (\n" +"  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',\n" +"  `username` VARCHAR(100) NOT NULL DEFAULT '' COMMENT '用户名',\n" +"  PRIMARY KEY (id)\n" +") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';");}/*** 插入数据.*/@Testpublic void executeInsertSqlTest() {//插入语句jdbcTemplate.execute("INSERT INTO user (username) values ('小苏');");}@Testpublic void queryForListTest() {List<Map<String, Object>> allResult = jdbcTemplate.queryForList("select * from user");for (int i = 0; i < allResult.size(); i++) {System.out.printf("第%d行数据", i + 1);Map<String, Object> objectMap = allResult.get(i);System.out.println(objectMap);}}@Testpublic void queryListWithColumnClassTypeTest() {List<String> allResult = jdbcTemplate.queryForList("select username from user", String.class);for (int i = 0; i < allResult.size(); i++) {System.out.printf("第%d行数据", i + 1);String username = allResult.get(i);System.out.println(username);}}@Testpublic void queryListWithColumnClassTypeWithArgTest() {List<String> allResult = jdbcTemplate.queryForList("select username from user where id=?", String.class, 1);for (int i = 0; i < allResult.size(); i++) {System.out.printf("第%d行数据", i + 1);String username = allResult.get(i);System.out.println(username);}}@Testpublic void queryListWithArgTest() {List<Map<String, Object>> allResult = jdbcTemplate.queryForList("select * from user where id=?", 1);for (int i = 0; i < allResult.size(); i++) {System.out.printf("第%d行数据", i + 1);Map<String, Object> row = allResult.get(i);System.out.println(row);}}@Testpublic void queryObjectTest() {String username = jdbcTemplate.queryForObject("select username from user where id=1", String.class);System.out.println(username);}@Testpublic void queryMapTest() {Map<String, Object> row = jdbcTemplate.queryForMap("select * from user where id=1");System.out.println(row);}@Testpublic void queryMapWithArgTest() {Map<String, Object> row = jdbcTemplate.queryForMap("select * from user where id=?", 1);System.out.println(row);}
}

测试结果:

  1. queryForListTest

    image-20241109211659989

  2. queryListWithColumnClassTypeTest

    image-20241109211708345

  3. queryListWithColumnClassTypeWithArgTest

    image-20241109211721806

  4. queryListWithArgTest

    image-20241109211741083

  5. queryObjectTest

    image-20241109211751744

  6. queryMapTest

    image-20241109211759547

  7. queryMapWithArgTest

    image-20241109211806267

  • 从测试结果中可以看到,可以正常与数据库进行交互,创建表、插入数据,查询表数据、查询表中某列的数据、根据条件查询表的数据等功能。

总结

  • 在本章节中,我们深入探讨了JDBC(Java Database Connectivity)的功能整合,特别是如何通过Spring框架中的JdbcTemplate来简化JDBC编程。我们详细分析了JDBC的核心组件、关键特性和用法,并展示了如何通过JdbcTemplate来执行数据库操作,包括查询、更新处理等。
  • 通过本节的学习,我们可以借鉴这些代码的结构和风格,提高自己的编码水平。可以帮助我们后续再遇到查询数据库遇到的问题时,可以更快排查定位问题。

参考书籍:《手写Spring渐进式源码实践》

书籍源代码:https://github.com/fuzhengwei/small-spring

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

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

相关文章

【Python】轻松实现机器翻译:Transformers库使用教程

轻松实现机器翻译&#xff1a;Transformers库使用教程 近年来&#xff0c;机器翻译技术飞速发展&#xff0c;从传统的基于规则的翻译到统计机器翻译&#xff0c;再到如今流行的神经网络翻译模型&#xff0c;尤其是基于Transformer架构的模型&#xff0c;翻译效果已经有了质的飞…

Linux awk命令详解-参数-选项-内置变量-内置函数-脚本(多图、多示例)

文章目录 awk基础结构说明与示例参数与内置变量常用参数内置变量其他参数内置变量 简单示例理解option简单参数NR与FNR-v ARGC ARGV参数 执行脚本if elsefor循环关联数组指定匹配pattern 使用正则指定分隔符理解pattern正则与逻辑算术 printfif else for whileBEGIN ENDnext(跳…

RHCE的学习(12)

第九章 Ubuntu 什么是Ubuntu 概述 Ubuntu&#xff08;乌班图&#xff09;属于Debian系列&#xff0c;Debian是社区类Linux的典范&#xff0c;是迄今为止最遵循GNU规范的Linux系统。 Debian最早由Ian Murdock于1993年创建&#xff0c;分为三个版本分支&#xff08;branch&…

可视化建模与UML《顺序图实验报告》

旷野的规则是永不回头。 一、实验目的&#xff1a; 1、熟悉顺序图的构件事物。 2、熟悉发送者与接受者的关系 3、熟练掌握描绘顺序图 4、加深对顺序图的理解和应用能力 二、实验环境&#xff1a; window7 | 10 | 11 EA15 三、实验内容&#xff1a; 据如下描述绘制顺序图&…

30-手动准备地图包

map包遵循特定的文件夹结构&#xff0c;并且必须包含描述该结构的.json文件。我们的自动地图导入过程自动创建这个.json文件&#xff0c;但您也可以选择自己准备它。包括您自己的.json文件将覆盖传递给make import命令的任何参数。 标准地图 为标准地图创建文件夹结构 1.…

汽车免拆诊断案例 | 2017款凯迪拉克XT5车组合仪表上的指针均失灵

故障现象 一辆2017款凯迪拉克XT5车&#xff0c;搭载LTG 发动机&#xff0c;累计行驶里程约为17.2万km。车主反映&#xff0c;组合仪表上的发动机转速表、车速表、燃油表及发动机冷却液温度表的指针均不指示&#xff0c;但发动机起动及运转正常&#xff0c;且车辆行驶正常。 故…

docker镜像文件导出导入

1. 导出容器&#xff08;包含内部服务&#xff09;为镜像文件&#xff08;docker commit方法&#xff09; 原理&#xff1a;docker commit命令允许你将一个容器的当前状态保存为一个新的镜像。这个新镜像将包含容器内所有的文件系统更改&#xff0c;包括安装的软件、配置文件等…

数据结构:顺序表(动态顺序表)

专栏说明&#xff1a;本专栏用于数据结构复习&#xff0c;文章中出现的代码由C语言实现&#xff0c;在专栏中会涉及到部分OJ题目&#xff0c;如对你学习有所帮助&#xff0c;可以点赞鼓励一下博主喔&#x1f493; 博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;数…

Golang--网络编程

1、概念 网络编程&#xff1a;把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统&#xff0c;从而使众多的计算机可以方便地互相传递信息、共享数据、软件、数据信息等资源。 客户端&#xff08;Client&#xff09; 客户端是请求服务…

软件设计师中级 第9章 数据库技术基础

9.1 基本概念 9.1.1 数据库的三级模式结构 数据库系统有三级模式结构&#xff0c;一个数据库可以由多个外模式&#xff0c;只能有一个内模式。 视图对应外模式、基本表对应模式&#xff08;概念模式&#xff09;、存储文件对应内模式。 外模式 也称子模式&#xff08;Subsch…

Rust项目结构

文章目录 一、module模块1.二进制文件的cargo项目2.库的cargo项目模块中使用crate关键字模块中使用super模块中结构体的访问规则模块中枚举的访问规则模块中use关键字不同模块定义了相同类型冲突解决办法使用pub use导出本模块的函数给外面模块引入外部依赖模块与子模块 小结3.…

Java-字符串常量池

在Java程序中&#xff0c;类似于&#xff1a;1&#xff0c; 2&#xff0c; 3&#xff0c;3.14&#xff0c;“hello”等字面类型的常量经常频繁使用&#xff0c;为了使程序的运行速度更快、 更节省内存&#xff0c;Java为8种基本数据类型和String类都提供了常量池。 1.为什么要…

【Python爬虫实战】深入解锁 DrissionPage:ChromiumPage 自动化网页操作指南

&#x1f308;个人主页&#xff1a;易辰君-CSDN博客 &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html ​ 目录 前言 一、ChromiumPage基础操作 &#xff08;一&#xff09;初始化Drission 和 ChromiumPage 对象 &#xff0…

无人机之姿态融合算法篇

无人机的姿态融合算法是无人机飞行控制中的核心技术之一&#xff0c;它通过将来自不同传感器的数据进行融合&#xff0c;以实现更加精确、可靠的姿态检测。 一、传感器选择与数据预处理 无人机姿态融合算法通常依赖于多种传感器&#xff0c;包括加速度计、陀螺仪、磁力计等。这…

基于SSM的图书馆座位预约系统+lw示例参考

#1.项目介绍 系统角色&#xff1a;管理员、普通用户功能模块&#xff1a;管理员&#xff08;用户管理、座位管理、座位分类管理、图书馆管理、预约信息管理、退座管理、系统管理等&#xff09;、普通用户&#xff08;信息查看、图书馆管理、个人中心、座位预约等&#xff09;技…

企业IT架构转型之道:阿里巴巴中台战略思想与架构实战感想

文章目录 第一章&#xff1a;数据库水平扩展第二章&#xff1a;中台战略第三章&#xff1a;阿里分布式服务架构HSF&#xff08;high speed Framework&#xff09;、早期Dubbo第四章&#xff1a;共享服务中心建设原则第五章&#xff1a;数据拆分实现数据库能力线性扩展第六章&am…

鸿蒙的进击之路

1. 题记&#xff1a; 为什么要写鸿蒙&#xff0c;因为她是华为的&#xff0c;为什么是华为就要写&#xff0c;因为华为背负了国人太多太多的包袱&#xff0c;或点赞或抨击。 我是强烈支持华为的&#xff0c;但我会客观公正地去评价华为的产品&#xff0c;就比如这篇博文&#…

【CTFN】基于耦合翻译融合网络的多模态情感分析的层次学习

同样用了翻译模块的论文->MTMSA 代码地址->github地址 abstract 多模态情感分析是一个具有挑战性的研究领域&#xff0c;涉及多个异构模态的融合。主要的挑战是在多模式融合过程中出现一些缺失的模式。然而&#xff0c;现有的技术需要所有的模态作为输入&#xff0c;因…

Go的环境搭建以及GoLand安装教程

目录 一、开发环境Golang安装 二、配置环境变量 三、GoLand安装 四、Go 语言的 Hello World 一、开发环境Golang安装 官方网址&#xff1a; The Go Programming Language 1. 首先进入官网&#xff0c;点击Download&#xff0c;选择版本并进行下载&#xff1a; ​ ​ 2. …

Spring IoC DI

1. IoC 1.1 容器 容器是用来容纳某种物品的&#xff08;基本&#xff09;装置。——来自&#xff1a;百度百科 生活中的水杯&#xff0c;垃圾桶&#xff0c;冰箱等等&#xff0c;都是容器 代码中的容器&#xff0c;如&#xff1a;List/Map -> 数据存储容器&#xff1b;T…