《手写Spring渐进式源码实践》实践笔记(第十八章 JDBC功能整合)
文章目录
- 第十八章 JDBC功能整合
- 背景
- 技术背景
- JDBC
- JdbcTemplate
- 关键特性
- 用法示例
- 业务背景
- 目标
- 设计
- 实现
- 代码结构
- 类图
- 实现步骤
- 测试
- 事先准备
- 属性配置文件
- 测试用例
- 测试结果:
- 总结
第十八章 JDBC功能整合
背景
技术背景
JDBC
JDBC(Java Database Connectivity)是一个Java API,用于连接和执行查询在数据库中。它提供了一种标准的方法,允许Java程序
连接到各种关系型数据库
,执行SQL语句,并处理结果
。JDBC是一个强大的工具,它为Java应用程序提供了与数据库交互的能力,无论是进行数据检索还是更新。通过使用JDBC,开发者可以编写可移植的代码,这些代码可以在不同的数据库系统之间运行,而无需对代码进行大量修改。
以下是JDBC的一些关键点介绍:
- 数据库连接:
- JDBC使用
DriverManager
类来管理数据库连接。通过传递数据库URL、用户名和密码,可以获取到一个Connection
对象,该对象代表与特定数据库的连接。
- JDBC使用
- 驱动程序:
- JDBC驱动程序是一个允许Java应用程序与数据库进行交互的软件组件。JDBC驱动程序可以是类型1(原生方法)、类型2(基于Java的独立驱动程序)、类型3(纯Java驱动程序,使用JDBC网络协议)、类型4(JDBC驱动程序,使用数据库的薄客户端)。
- Statement和PreparedStatement:
Statement
对象用于执行静态SQL语句,并返回它所生成的结果。PreparedStatement
是Statement
的子接口,它允许预编译SQL语句,可以提高性能并防止SQL注入攻击。
- 执行SQL语句:
- 通过
Statement
或PreparedStatement
对象,可以执行各种SQL语句,包括查询(SELECT)、更新(UPDATE、DELETE)、插入(INSERT)和DDL(CREATE、DROP等)语句。
- 通过
- 处理结果:
- 查询数据库后,可以通过
ResultSet
对象处理返回的数据。ResultSet
提供了一种方式来遍历查询结果集中的数据。
- 查询数据库后,可以通过
- 事务处理:
- JDBC支持事务处理,默认情况下,每个
Statement
执行的SQL语句都是自动提交的。可以通过Connection
对象来设置自动提交模式,并使用commit()
和rollback()
方法来管理事务。
- JDBC支持事务处理,默认情况下,每个
- 批处理:
- JDBC提供了批处理功能,允许一次执行多个SQL语句,这可以减少网络往返次数,提高性能。
- 元数据:
DatabaseMetaData
接口提供了关于数据库的整体元数据信息,如表的结构、存储过程、支持的SQL语法等。
- 关闭资源:
- 为了释放数据库资源,应该在使用完毕后关闭
ResultSet
、Statement
和Connection
对象。
- 为了释放数据库资源,应该在使用完毕后关闭
- 异常处理:
- JDBC操作可能会抛出
SQLException
,因此需要适当的异常处理机制来确保程序的健壮性。
- JDBC操作可能会抛出
JdbcTemplate
JdbcTemplate
是 Spring 框架中提供的一个用于简化 JDBC 编程的模板类。它处理了资源的创建和释放,并且提供了执行 SQL 语句和查询的便捷方法,从而减少了编写 JDBC 代码时常见的样板代码。
以下是 JdbcTemplate
的一些关键特性和用法:
关键特性
-
简化资源管理:
JdbcTemplate
管理数据库连接,确保在每次执行后都正确关闭连接,从而避免了资源泄漏。 -
异常处理:它将 JDBC 的
SQLException
转换为 Spring 的DataAccessException
,这使得异常处理更加一致和易于管理。 -
便捷的方法:提供了多种便捷方法来执行 SQL 语句,包括
update
(用于执行插入、更新、删除等)、query
(用于执行查询)以及queryForObject
、queryForMap
、queryForList
等。 -
参数化查询:支持使用
PreparedStatement
来执行参数化查询,从而防止 SQL 注入攻击。 -
结果集处理:提供了将结果集映射到 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
执行了一个查询操作和一个更新操作,并输出了相应的结果。
业务背景
-
日常开发过程中,离不开和数据库的交互。JDBC提供了Java应用程序提供与数据库交互的能力,无论是进行数据检索还是更新。
-
JDBC交互的套路操作有:
-
配置数据库账号、密码、连接信息等参数
-
打开数据库连接
-
根据业务需求编写sql语句
-
预编译并执行sql语句
-
处理执行结果
-
处理抛出的异常
-
处理事务
-
关闭数据库连接
-
-
为了方便Spring框架与数据库的交互,我们需要将上述过程进行抽象化,实现jdbcTemplate模板类, 来执行jdbc交互的大部分通用步骤,形成spring-jdbc模块。spring-jdbc接收参数信息、JdbcTemplate接收业务需求sql进行处理并返回结果,应用返回结果数据。
目标
基于当前实现的 Spring 框架,实现jdbcTempate模板类,完成spring对jdbc调用的封装。
设计
为了方便Spring框架与数据库的交互,我们需要将JDBC交互的过程进行抽象化,实现jdbcTemplate模板类, 来执行jdbc交互的大部分通用步骤。整体设计结构如下图:
-
首先定义好JdbcTemplate类需要支持的操作,包括:解析数据源参数、获取数据源、获取连接、预编译执行sql、处理执行结果、处理异常、关闭连接。
-
通过JdbcTemplate类封装了和JDBC的交互细节,用户只需要通过调用jdbcTemplate方法,就可以很方便的完成数据库交互。
实现
代码结构

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

- 在整个类图中,通过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
- 用于将结果集每行数据转换为需要的类型
实现步骤
-
数据源连接类,
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;}}
-
核心类 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);}...... }
-
JdbcOperations 数据库交互操作接口.
- StatementCallback 会话回调接口,用于执行任意的JDBC Statement操作
- RowMapper 行处理接口,用于将结果集的每一行映射到Java对象
- ResultSetExtractor 结果集处理接口,用于从整个ResultSet中提取数据。
- PreparedStatementSetter 预编译接口,用于设置PreparedStatement的参数值。
- RowMapperResultSetExtractor 自定义接口或类,用于结合RowMapper和ResultSetExtractor的功能来处理结果集。
- 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
-
配置数据库源连接信息,注册jdbcTemplate bean。
-
我本地的mysql版本是8.0.33,对应的mysql-connector-java也是 8.0.33,留意pom.xml文件,加上该依赖
-
& 是为了转义&符号,不加&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&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);}
}
测试结果:
-
queryForListTest
-
queryListWithColumnClassTypeTest
-
queryListWithColumnClassTypeWithArgTest
-
queryListWithArgTest
-
queryObjectTest
-
queryMapTest
-
queryMapWithArgTest
- 从测试结果中可以看到,可以正常与数据库进行交互,创建表、插入数据,查询表数据、查询表中某列的数据、根据条件查询表的数据等功能。
总结
- 在本章节中,我们深入探讨了JDBC(Java Database Connectivity)的功能整合,特别是如何通过Spring框架中的
JdbcTemplate
来简化JDBC编程。我们详细分析了JDBC的核心组件、关键特性和用法,并展示了如何通过JdbcTemplate
来执行数据库操作,包括查询、更新处理等。 - 通过本节的学习,我们可以借鉴这些代码的结构和风格,提高自己的编码水平。可以帮助我们后续再遇到查询数据库遇到的问题时,可以更快排查定位问题。
参考书籍:《手写Spring渐进式源码实践》
书籍源代码:https://github.com/fuzhengwei/small-spring
相关文章:

《手写Spring渐进式源码实践》实践笔记(第十八章 JDBC功能整合)
文章目录 第十八章 JDBC功能整合背景技术背景JDBC JdbcTemplate关键特性 用法示例业务背景 目标设计实现代码结构类图实现步骤 测试事先准备属性配置文件测试用例测试结果: 总结 第十八章 JDBC功能整合 背景 技术背景 JDBC JDBC(Java Database Conne…...

边缘计算在智能交通系统中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 引言 边缘计算概述 定义与原…...
HTML5+css3(浮动,浮动的相关属性,float,解决浮动的塌陷问题,clear,overflow,给父亲盒子加高度,伪元素)
浮动的相关属性 以下使浮动的常用属性值: float: 设置浮动 以下属性: left : 设置左浮动 right : 设置右浮动 none :不浮动,默认值clear 清除浮动 清除前面兄弟元素浮动元素的响应 以下属性: left &…...

【C++ 滑动窗口】2134. 最少交换次数来组合所有的 1 II
本文涉及的基础知识点 C算法:滑动窗口及双指针总结 LeetCode2134. 最少交换次数来组合所有的 1 II 交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。 环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。 给你一个 二…...
使用 PyTorch 实现并测试 AlexNet 模型,并使用 TensorRT 进行推理加速
本篇文章详细介绍了如何使用 PyTorch 实现经典卷积神经网络 AlexNet,并利用 Fashion-MNIST 数据集进行训练与测试。在训练完成后,通过 TensorRT 进行推理加速,以提升模型的推理效率。 本文全部代码链接:全部代码下载 环境配置 为了保证代码在 GPU 环境下顺利运行,我们将…...
Python 数据可视化详解教程
Python 数据可视化详解教程 数据可视化是数据分析中不可或缺的一部分,它通过图形化的方式展示数据,帮助我们更直观地理解和分析数据。Python 作为一种强大的编程语言,拥有丰富的数据可视化库,如 Matplotlib、Seaborn、Plotly 和 …...
springboot集成opencv开源计算机视觉库
最近项目需要用到opencv,网上看到很多资料都是下载安装并且引入jar包与dll文件,感觉很麻烦,不是我想要的,于是花时间折腾了下,不需要任何安装与引入jar包与dll文件,简单方便,快速上手。 先说说…...

CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳
2024年11月9日至10日,以“湾区聚力 开源启智”为主题的2024年中国计算机学会中国开源大会(CCF ChinaOSC)将在深圳召开。大会将汇聚国内外学术界、顶尖科技企业、科研机构及开源社区的精英力量,共同探索人工智能技术和人类智慧的无…...

2024年11月8日上海帆软用户大会
2024年11月8日上海帆软用户大会 2024年11月8日,上海成功举办了帆软用户大会,主题为“数字聚力,绽放新机”。大会汇聚了众多行业专家和企业代表,共同探讨数字化转型和商业智能领域的最新趋势和实践。 大会亮点: 专家…...
信息泄露漏洞一文速通
文章目录 信息泄露漏洞一文速通敏感信息の概念敏感信息の分类企业敏感信息用户敏感信息站点敏感信息 如何挖掘信息泄露漏洞?信息泄露风险清单(checklist)未授权访问类文件与数据泄露开发与调试信息泄露公共配置文件泄露其他敏感信息泄露点 威…...
Android 启动时应用的安装解析过程《二》
上一篇内容说到InitAppsHelper这个类的initSystemApps函数,只说了一下几个重要参数的来源还没展开,这里继续,有兴趣的可以看链接: Android 启动时应用的安装解析过程《一》 一、系统应用的扫描安装 /*** Install apps from system dirs.*/Gu…...
智谱AI:ChatGLM强大的生成式语言模型
目录 智谱AI:ChatGLM强大的生成式语言模型 一、ChatGLM的定义与特点 二、ChatGLM的应用场景 三、举例说明 四、注意事项 智谱AI:ChatGLM强大的生成式语言模型 它通过对话的方式能够生成自然流畅的文本,这一特性使其在多个领域都有广泛的应用潜力,特别是在智能对话和智能…...
git tag
已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。 要查看仓库中的所有标签 gi…...

Golang--反射
1、概念 反射可以做什么? 反射可以在运行时动态获取变量的各种信息,比如变量的类型,类别等信息如果是结构体变量,还可以获取到结构体本身的信息(包括结构体的字段、方法)通过反射,可以修改变量的值,可以调用关联的方法…...

ABAP:SET CURSOR FIELD设置鼠标焦点
SET CURSOR FIELD <字段名>:设置鼠标焦点到该字段 SET CURSOR 设置到鼠标焦点列还是行 SET CURSOR LINE 设置鼠标焦点到行 GET CURSOR field <字段名> :这个相对应的获取鼠标焦点得到的字段...

【专题】2024年全球生物医药交易报告汇总PDF洞察(附原数据表)
原文链接:https://tecdat.cn/?p38191 在当今复杂多变的全球经济环境下,医药行业正面临着诸多挑战与机遇。2024 年,医药行业的发展态势备受关注。 一方面,全球生物医药交易活跃,2021 - 2023 年的交易中,已…...

LabVIEW气体检测系统
随着工业化进程的加速,环境污染问题愈加严峻,尤其是有害气体的排放对人类生存环境构成了严重威胁。为了更好地监测这些有害气体,开发一个高效、准确且易于操作的气体检测系统显得尤为重要。LabVIEW软件开发的气体检测系统,采用激光…...
LeetCode78. 子集(2024秋季每日一题 58)
给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出:[[],[1],[2],[1,2],[3…...

推荐一款功能强大的视频修复软件:Apeaksoft Video Fixer
Apeaksoft Video Fixer是一款功能强大的视频修复软件,专门用于修复损坏、不可播放、卡顿、画面失真、黑屏等视频问题。只需提供一个准确且有效的样本视频作为参考,该软件就能将受损视频修复到与样本视频相同的质量。该软件目前支持MP4、MOV、3GP等格式的…...

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

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
大模型真的像人一样“思考”和“理解”吗?
Yann LeCun 新研究的核心探讨:大语言模型(LLM)的“理解”和“思考”方式与人类认知的根本差异。 核心问题:大模型真的像人一样“思考”和“理解”吗? 人类的思考方式: 你的大脑是个超级整理师。面对海量信…...
【Java】Ajax 技术详解
文章目录 1. Filter 过滤器1.1 Filter 概述1.2 Filter 快速入门开发步骤:1.3 Filter 执行流程1.4 Filter 拦截路径配置1.5 过滤器链2. Listener 监听器2.1 Listener 概述2.2 ServletContextListener3. Ajax 技术3.1 Ajax 概述3.2 Ajax 快速入门服务端实现:客户端实现:4. Axi…...

python可视化:俄乌战争时间线关键节点与深层原因
俄乌战争时间线可视化分析:关键节点与深层原因 俄乌战争是21世纪欧洲最具影响力的地缘政治冲突之一,自2022年2月爆发以来已持续超过3年。 本文将通过Python可视化工具,系统分析这场战争的时间线、关键节点及其背后的深层原因,全面…...

Tableau for mac 驱动
Tableau 驱动程序安装指南 对于希望在 Mac OS 上使用 Tableau 进行数据分析的用户来说,确保正确安装相应的驱动程序至关重要。Tableau 支持多种数据库连接方式,并提供官方文档指导如何设置这些连接。 安装适用于 Mac 的 JDBC 或 ODBC 驱动程序 为了使…...