Spring框架学习笔记(五):JdbcTemplate 和 声明式事务

基本介绍:通过 Spring 框架可以配置数据源,从而完成对数据表的操作。JdbcTemplate 是 Spring 提供的访问数据库的技术。将 JDBC 的常用操作封装为模板方法

1 JdbcTemplate 使用前需进行如下配置

1.1 在maven项目的pom文件加入以下依赖
<dependencies><!--加入c3p0数据源包--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency><!--加入mysql连接--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.31</version></dependency><!--加入spring新增的依赖 spring-jdbc,这个依赖中有JdbcTemplate--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.8</version></dependency><!--加入spring开发的基本包--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.8</version></dependency><!--加入spring开发切面编程需要的包--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.8</version></dependency>
</dependencies>

1.2 创建配置文件 resources/jdbc.properties

#配置用户名
jdbc.userName=root
#密码
jdbc.password=123456
jdbc.driverClass=com.mysql.cj.jdbc.Driver
#指定要连接的数据库,这里连接spring数据库
jdbc.url=jdbc:mysql://localhost:3306/spring

1.3 创建配置文件 resources/JdbcTemplate_ioc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!--引入外部的jdbc.properties配置文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--配置数据源对象-DataSource--><bean class="com.mchange.v2.c3p0.ComboPooledDataSource" id="dataSource"><property name="user" value="${jdbc.userName}"/><property name="password" value="${jdbc.password}"/><property name="driverClass" value="${jdbc.driverClass}"/><property name="jdbcUrl" value="${jdbc.url}"/></bean><!--配置JdbcTemplate对象--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><!--给jdbcTemplate对象配置dataSource属性--><property name="dataSource" ref="dataSource"/></bean>
</beans>

接下来就可以开始使用JdbcTemplate对象来操作数据库了!

2  JdbcTemplate对象常用操作

为成功演示以下操作,需提前进行如下准备

执行如下sql语句

-- 创建数据库
CREATE DATABASE spring;
USE spring
-- 创建表 monster
CREATE TABLE monster(
id INT PRIMARY KEY, `name` VARCHAR(64) NOT NULL DEFAULT '',
skill VARCHAR(64) NOT NULL DEFAULT '' )CHARSET=utf8mb4
INSERT INTO monster VALUES(100, '青牛怪', '吐火');
INSERT INTO monster VALUES(200, '黄袍怪', '吐烟');
INSERT INTO monster VALUES(300, '蜘蛛怪', '吐丝');

创建Monster.java

package com.spring.bean;public class Monster {private Integer monsterId;private String name;private String skill;//全参构造器public Monster(Integer monsterId, String name, String skill) {this.monsterId = monsterId;this.name = name;this.skill = skill;}//无参构造器一定要写,Spring反射创建对象时,需要使用public Monster() {}public Integer getMonsterId() {return monsterId;}public void setMonsterId(Integer monsterId) {this.monsterId = monsterId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSkill() {return skill;}public void setSkill(String skill) {this.skill = skill;}@Overridepublic String toString() {return "Monster{" +"monsterId=" + monsterId +", name='" + name + '\'' +", skill='" + skill + '\'' +'}';}
}

2.1 添加单条数据

2.1.3 方式1:使用 void execute(final String sql) 方法

//测试通过JdbcTemplate对象完成添加数据
@Test
public void addDataByJdbcTemplate(){//获取到容器ApplicationContext ioc = new ClassPathXmlApplicationContext("jdbcTemplate_ioc.xml");JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//添加方式1String sql = "INSERT INTO monster VALUES(400, '红孩儿', '枪法')";jdbcTemplate.execute(sql);
}

2.1.3 方式2:使用 int update(String sql, @Nullable Object... args) 方法

    //测试通过JdbcTemplate对象完成添加数据@Testpublic void addDataByJdbcTemplate(){//获取到容器ApplicationContext ioc = new ClassPathXmlApplicationContext("jdbcTemplate_ioc.xml");JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//添加方式2String sql = "INSERT INTO monster VALUES(?, ?, ?)";int affected = jdbcTemplate.update(sql, 500, "红孩儿2", "枪法2");System.out.println("add ok affected = " + affected);}

2.2 修改数据

方法:public int update(String sql, @Nullable Object... args)

//测试通过JdbcTemplate对象完成修改数据
@Test
public void updateDataByJdbcTemplate(){//获取到容器ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//获取JdbcTemplate对象JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//组织sqlString sql = "UPDATE monster SET skill = ? WHERE id = ?";int affected = jdbcTemplate.update(sql, "美人计", 300);System.out.println("update ok affected = " + affected);
}

2.3 批量添加数据

方法:public int[] batchUpdate(String sql, List<Object[]> batchArgs)

//测试通过JdbcTemplate对象完成批量添加数据
@Test
public void addBatchDataByJdbcTemplate(){//获取到容器ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//获取JdbcTemplate对象JdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);String sql = "INSERT INTO monster VALUES(?, ?, ?)";List<Object[]> batchArgs = new ArrayList<>();batchArgs.add(new Object[]{600, "红孩儿3", "枪法3"});batchArgs.add(new Object[]{700, "红孩儿4", "枪法4"});batchArgs.add(new Object[]{800, "红孩儿5", "枪法5"});jdbcTemplate.batchUpdate(sql,batchArgs);System.out.println("batch add ok...");
}

2.4 将单条查询数据封装到对象

方法:public <T> T queryForObject(String sql, RowMapper<T> rowMapper, Object... args)

//查询id=100的monster并封装到Monster实体对象
@Test
public void selectDataByJdbcTemplate() {ApplicationContext ioc = new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//得到JdbcTemplate beanJdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//组织SQL//通过BeanPropertyRowMapper获取,rowmapper 是一个接口,可以将查询的结果,封装到你指定的Monster对象中.//1. 确定API : queryForObject()//public <T> T queryForObject(String sql, RowMapper<T> rowMapper, @Nullable Object... args)//2.准备参数String sql = "SELECT id AS monsterId, `NAME`, skill FROM monster WHERE id = ?";//使用RowMapper 接口来对返回的数据,进行一个封装-》底层使用的反射->setter//这里有一个细节: 你查询的记录的表的字段需要和 Monster的对象字段名保持一致RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);//jdbcTemplateMonster monster = jdbcTemplate.queryForObject(sql, rowMapper, 100);System.out.println("monster= " + monster);System.out.println("查询ok");
}

2.5 封装多条查询数据

方法:public <T> T query(String sql, RowMapper<T> rowMapper, Object... args)

//查询id>=200的monster并封装到Monster实体对象
/*** 查询多条记录*/
@Test
public void selectMulDataByJdbcTemplate() {ApplicationContext ioc =new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//得到JdbcTemplate beanJdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//组织SQL//通过BeanPropertyRowMapper获取rowmapper 是一个接口,可以将查询的结果,封装到你指定的Monster对象中.//1.    确定API//public <T> T query(String sql, RowMapper<T> rowMapper, Object... args){}//2. 组织参数String sql = "SELECT id AS monsterId, `NAME`, skill FROM monster WHERE id >= ?";RowMapper<Monster> rowMapper = new BeanPropertyRowMapper<>(Monster.class);//3. 调用List<Monster> monsterList = jdbcTemplate.query(sql, rowMapper, 100);for (Monster monster : monsterList) {System.out.println("monster= " + monster);}
}

2.6 查询返回结果只有一行一列的值

方法:public <T> T queryForObject(String sql, Class<T> requiredType)

//查询返回结果只有一行一列的值,比如查询id=100的怪物名
/*** 查询返回结果只有一行一列的值*/
@Test
public void selectScalarByJdbcTemplate() {ApplicationContext ioc =new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//得到JdbcTemplate beanJdbcTemplate jdbcTemplate = ioc.getBean(JdbcTemplate.class);//1. 确定API//public <T> T queryForObject(String sql, Class<T> requiredType)//2. 提供参数String sql = "SELECT NAME FROM monster WHERE id = 100";//Class<T> requiredType 表示你返回的单行单列的数据类型String name =jdbcTemplate.queryForObject(sql, String.class);System.out.println("返回name= " + name);
}

2.7 使用具名参数完成操作

resources/JdbcTemplate_ioc.xml配置文件中增加如下配置

<!--配置NameParameterJdbcTemplate,支持具名参数-->
<bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"id="namedParameterJdbcTemplate"><!--这里需要使用构造器关联数据源--><constructor-arg name="dataSource" ref="dataSource"/>
</bean>

方法:public int update(String sql, Map<String, ?> paramMap)

/*** 使用Map传入具名参数完成操作,比如添加*/
@Test
public void testDataByNamedParameterJdbcTemplate() {ApplicationContext ioc =new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//得到NamedParameterJdbcTemplate beanNamedParameterJdbcTemplate namedParameterJdbcTemplate =ioc.getBean(NamedParameterJdbcTemplate.class);//1. 确定使用API//public int update(String sql, Map<String, ?> paramMap)//2. 准备参数 [:my_id, :name, :skill] 要求按照规定的名字来设置参数String sql = "INSERT INTO monster VALUES(:id, :name, :skill)";Map<String, Object> paramMap = new HashMap<>();//给paramMap填写数据paramMap.put("id", 900);paramMap.put("name", "蚂蚁精");paramMap.put("skill", "喜欢打洞");//3. 调用int affected = namedParameterJdbcTemplate.update(sql, paramMap);System.out.println("add ok affected=" + affected);
}

2.8 使用sqlparametersoruce 来封装具名参数

方法:public int update(String sql, SqlParameterSource paramSource)

//使用sqlparametersoruce 来封装具名参数,还是添加一个Monster 狐狸精
@Test
public void operDataBySqlparametersoruce() {ApplicationContext ioc =new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");//得到NamedParameterJdbcTemplate beanNamedParameterJdbcTemplate namedParameterJdbcTemplate =ioc.getBean(NamedParameterJdbcTemplate.class);//确定API//public int update(String sql, SqlParameterSource paramSource)//public BeanPropertySqlParameterSource(Object object)//准备参数String sql = "INSERT INTO monster VALUES(:monsterId, :name, :skill)";Monster monster = new Monster(1000, "大象精", "搬运木头");SqlParameterSource sqlParameterSource =new BeanPropertySqlParameterSource(monster);//调用int affected =namedParameterJdbcTemplate.update(sql, sqlParameterSource);System.out.println("add ok affected= " + affected);
}

2.9 Dao 对象中使用 JdbcTemplate 完成对数据的操作

创建 MonsterDao.java

package com.spring.dao;import com.spring.bean.Monster;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;public class MonsterDao {private JdbcTemplate jdbcTemplate;//完成保存任务public void save(Monster monster){//组织sqlString sql = "INSERT INTO monster VALUES(?,?,?)";jdbcTemplate.update(sql, monster.getMonsterId(), monster.getName(), monster.getSkill());}public JdbcTemplate getJdbcTemplate() {return jdbcTemplate;}public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}
}

resources/JdbcTemplate_ioc.xml配置文件中增加如下配置

<!--配置monsterDao对象-->
<bean class="com.spring.dao.MonsterDao" id="monsterDao"><property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>

编写测试代码:

//测试MonsterDAO
@Test
public void monsterDaoSave() {ApplicationContext ioc =new ClassPathXmlApplicationContext("JdbcTemplate_ioc.xml");MonsterDao monsterDao = ioc.getBean(MonsterDao.class);Monster monster = new Monster(1100, "小鸭精", "吃鱼");monsterDao.save(monster);System.out.println("MonsterDAO保存 ok ..");
}

3 声明式事务

3.1 声明式事务的基本使用

(1)在xml文件中加入以下配置

<!--配置事务管理器-对象
1. DataSourceTransactionManager 这个对象是进行事务管理-debug源码
2. 一定要配置数据源属性,这样指定该事务管理器 是对哪个数据源进行事务控制
-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager"><property name="dataSource" ref="dataSource"/>
</bean><!--配置启动基于注解的声明式事务管理功能-->
<tx:annotation-driven transaction-manager="transactionManager"/>

(2)在方法上添加注解@Transaction ,即可将该方法作为一个事务来处理(前提是该方法所在的类被注入到了容器中)

/*** @Transactional 注解解读* 1. 使用@Transactional 可以进行声明式事务控制* 2. 即将标识的方法中的,对数据库的操作作为一个事务管理* 3. @Transactional 底层使用的仍然是AOP机制* 4. 底层是使用动态代理对象来调用buyGoodsByTx* 5. 在执行buyGoodsByTx() 方法 先调用 事务管理器的 doBegin() , 调用 buyGoodsByTx()* 如果执行没有发生异常,则调用 事务管理器的 doCommit(), 如果发生异常 调用事务管理器的 doRollback()进行回调*/
@Transactional
public void buyGoodsByTx(int userId, int goodsId, int amount) {//输出购买的相关信息System.out.println("用户购买信息 userId=" + userId+ " goodsId=" + goodsId + " 购买数量=" + amount);//1.得到商品的价格Float price = goodsDao.queryPriceById(userId);//2. 减少用户的余额goodsDao.updateBalance(userId, price * amount);//3. 减少库存量goodsDao.updateAmount(goodsId, amount);System.out.println("用户购买成功~");
}

3.2 事务的传播机制

当有多个事务处理并存时,可以使用事务的传播机制去控制,比如用户去购买两次商品(使用不同的方法), 每个方法都是一个事务

(1)事务传播机制种类

  • REQUIRED REQUIRED_NEW 传播机制示意图

  • 事务的传播机制的设置方法

  • REQUIRES_NEW REQUIRED 在处理事务的策略 

(1)如果设置为 REQUIRES_NEW
buyGoods2 如果错误,不会影响到 buyGoods() 反之亦然,即它们的事务是独立的 .
(2) 如果设置为 REQUIRED
buyGoods2 buyGoods 是一个整体,只要有方法的事务错误,那么两个方法都不
会执行成功

3.3 事务隔离级别

3.3.1 事务隔离级别种类(事务相关知识点这篇有详细介绍mysql基础知识汇总)

 3.3.2 事务隔离级别的设置

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.DEFAULT)
public void buyGoodsByTx2(int userId, int goodsId, int amount) {

在默认情况下 声明式事务的隔离级别是 REPEATABLE_READ . 我们将buyGoodsByTxISOLATION的隔离级别设置为 Isolation.READ_COMMITTED ,表示只要是提交的数据,在当前事务是可以读取到最新数据

@Transactional(isolation = Isolation.READ_COMMITTED)
public void buyGoodsByTxISOLATION() {

3.4 事务的超时回滚

介绍:如果一个事务执行的时间超过某个时间限制,就让该事务回滚。

设置方式如下:

timeout = 2 表示 buyGoods如果执行时间超过了2秒 , 该事务就进行回滚. 如果没有设置 timeout, 默认是 -1,表示使用事务的默认超时时间, 或者不支持

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

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

相关文章

最新区块链论文录用资讯CCF B—DASFAA 2024 共3篇

Conference&#xff1a;International Conference on Database Systems for Advanced Applications (DASFAA) CCF level&#xff1a;CCF B Categories&#xff1a;数据库&#xff0f;数据挖掘&#xff0f;内容检索 Year&#xff1a;2024 Conference time&#xff1a;July …

认识K8s集群的声明式资源管理方法

前言 Kubernetes 集群的声明式资源管理方法是当今云原生领域中的核心概念之一&#xff0c;使得容器化应用程序的部署和管理变得更加高效和可靠。本文将认识了解 Kubernetes 中声明式管理的相关理念、实际应用以及优势。 目录 一、管理方法介绍 1. 概述 2. 语法格式 2.1 管…

Qt 配置Eigen矩阵库 - 并简单测试

Qt 配置Eigen矩阵库 - 并简单测试 引言一、在Qt中配置Eigen二、低通Demo源码三、参考链接以及其他 引言 Eigen是一个开源的C模板库&#xff0c;提供了线性代数和矩阵运算的功能。它被设计为一个高性能、可扩展和易用的库&#xff0c;可以用于科学计算、机器学习和计算机图形学等…

dubbo复习:(4) 和springboot 整合时,客户端负载均衡的配置

需要在DubboReference注解指定loadbalance属性。示例如下&#xff1a; package cn.edu.tju.service;import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Ser…

使用NuScenes数据集生成ROS Bag文件:深度学习与机器人操作的桥梁

在自动驾驶、机器人导航及环境感知的研究中&#xff0c;高质量的数据集是推动算法发展的关键。NuScenes数据集作为一项开源的多模态自动驾驶数据集&#xff0c;提供了丰富的雷达、激光雷达&#xff08;LiDAR&#xff09;、摄像头等多种传感器数据&#xff0c;是进行多传感器融合…

Discuz!X3.4论坛网站公安备案号怎样放到网站底部?

Discuz&#xff01;网站的工信部备案号都知道在后台——全局——站点信息——网站备案信息代码填写&#xff0c;那公安备案号要添加在哪里呢&#xff1f;并没有看到公安备案号填写栏&#xff0c;今天驰网飞飞和你分享 1&#xff09;工信部备案号和公安备案号统一填写到网站备案…

服务器感染了. rmallox勒索病毒,如何确保数据文件完整恢复?

导言&#xff1a; 近年来&#xff0c;随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。其中&#xff0c;勒索病毒作为一种严重的网络威胁&#xff0c;对个人和企业数据造成了巨大的威胁。本文将重点介绍.rmallox勒索病毒的特点、传播途径以及应对策略&#xff0c;旨…

压力测试JMeter

压力测试JMeter 1 下载JMeter1.1 测试计划1.2 JMeter Address Already in use 错误解决1.3 java 内存模型1.4 jconsole与jvisualvm1.5 优化方向1.6 Nginx动静分离 1 下载JMeter 官网地址&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 运行apache-jmeter-5.6.3\…

firebase如何自定义上传日志

我们可以很轻松的得到2个代码&#xff1a; Firebase.crashlytics.log(str) Firebase.crashlytics.recordException(ex)这就是firebase提供的自定义日志和excption上传的方法。 但是如果你认为log函数调用后&#xff0c;直接就能查看到日志就错了。 我们在这个page是找不到日志…

如何找出真正的交易信号?Anzo Capital昂首资本总结7个

匕首是一种新兴的价格走势形态&#xff0c;虽然不常见&#xff0c;但具有较高的统计可靠性。它通常预示着趋势的持续发展。该模式涉及到同时参考两个不同的时间周期进行交易&#xff0c;一个是短期&#xff0c;另一个是长期&#xff0c;比如一周时间框架与一天时间框架、一天时…

字母的大小写转换

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;字符串对象提供了lower()方法和upper()方法进行字母的大小写转换&#xff0c;即可用于将大写字母转换为小写字母或者将小写字…

Windows下PostgreSQL数据库的备份与恢复

文章目录 一、备份1.找到PostgreSQL的安装目录下的"bin"目录2.在windows的命令窗口里&#xff0c;使用pg_dump进行备份1.打开命令窗口2.使用pg_dump将数据库备份下来 二、恢复1.找到PostgreSQL的安装目录下的"bin"目录2.在windows的命令窗口里&#xff0c;…

FTP介绍

FTP 1、FTP—文件传输协议 文件传输协议&#xff08;File Transfer Protocol&#xff0c;FTP&#xff09;是用于在网络上进行文件传输的一套标准协议&#xff0c;它工作在 OSI 模型的第七层&#xff0c; TCP 模型的第四层&#xff0c; 即应用层&#xff0c; 使用 TCP 传输&…

利润而不是损失:谁信任你的游戏本地化

中国游戏市场巨大且前景广阔。这尤其适用于移动游戏&#xff1a;Statista预测&#xff0c;2024年。它的收入将达到346.6亿美元。然而&#xff0c;这种巨大的财务潜力也有其反面&#xff1a;游戏进入市场的次数越多&#xff0c;它们就越难以相互争夺玩家的注意力。此外&#xff…

信息学奥赛初赛天天练-15-阅读程序-深入解析二进制原码、反码、补码,位运算技巧,以及lowbit的神奇应用

更多资源请关注纽扣编程微信公众号 1 2021 CSP-J 阅读程序1 阅读程序&#xff08;程序输入不超过数组或字符串定义的范围&#xff1b;判断题正确填 √&#xff0c;错误填&#xff1b;除特 殊说明外&#xff0c;判断题 1.5 分&#xff0c;选择题 3 分&#xff09; 源码 #in…

DNSlog环境搭建

阿里云域名公网VPS地址 购买阿里云域名后设置“自定义DNSHOST” DNS服务器填写ns1和ns2 如&#xff1a;ns1.aaa.com IP地址填写你的VPS地址 如&#xff1a;1.1.1.1 填写解析记录&#xff0c;一个A记录、一个NS记录 NS记录就是*.域名指向记录值ns1.域名 如&#xff1a;*.aaa…

【已解决】使用token登录机制,token获取不到,blog_list.html界面加载不出来

Bug产生 今天使用token完成用户登录信息的存储的时候被卡了大半天。 因为登录的功能写的已经很多了&#xff0c;所以今天就没有写一点验一点&#xff0c;而是在写完获取博客列表功功能&#xff0c;验证完它的后端后&#xff0c;了解完令牌的基本使用以及Jwt的基本使用方式——…

【二叉树】:LeetCode:100.相同的数(分治)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;初阶初阶结构刷题 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 1.问题描述&#xff1a; 2.问题分析&#xff1a; 二叉树是区分结构的&#xff0c;即左右子树是不一…

Vanna使用ollama分析本地MySQL数据库

上一章节中已经实现了vanna的本地运行&#xff0c;但是大模型和数据库都还是远程的&#xff0c;因为也就没办法去训练&#xff0c;这节一起来实现vanna分析本地mysql数据库&#xff0c;因为要使用本地大模型&#xff0c;所以开始之前需要给本地安装好大模型&#xff0c;我这里用…

通过Wirtinger流进行相位恢复:理论与算法

文章目录 1. 简介2. 算法描述2.1 初始化(Initialization)2.2 迭代更新(Iterative Updates)2.3 学习率调整&#xff08;Learning Rate Adjustment&#xff09; 3. 代码实现3.1 一维信号测试 &#xff08;Gaussian model&#xff09;3.2 一维信号测试 &#xff08;Coded diffract…