GDPU Java 天码行空15 数据库编程

一、实验目的

1、 了解数据库的基础知识。
2、 掌握MySQL的下载、安装与配置。
3、 掌握MySQL可视化工具的使用。
4、 了解SQL语言。
5、 掌握JDBC中的API,并能进行简单的数据库操作。

二、实验内容

1、 安装MySQL

👨‍🏫 视频教程

2、建表 + 写数据

建立数据库productDB,再建立product表,然后按照下表输入记录,可以使用SQL语句或可视化工具实现。
在这里插入图片描述
SQL 脚本

USE productDB;
create table `product` (
	`pID` varchar (765),
	`pName` varchar (765),
	`pPrice` double ,
	`pNumber` int (11)
); 
insert into `product` (`pID`, `pName`, `pPrice`, `pNumber`) values('1001','A','30','88');
insert into `product` (`pID`, `pName`, `pPrice`, `pNumber`) values('1002','B','18','85');
insert into `product` (`pID`, `pName`, `pPrice`, `pNumber`) values('1003','C','25','68');
insert into `product` (`pID`, `pName`, `pPrice`, `pNumber`) values('1004','D','19','92');

3、Java 查询数据库

编程实现使用PreparedStatement查询product表中的所有记录,并将每一条记录保存到一个类Product的对象中,再将对象保存到ArrayList中,并打印ArrayList中的数据。

① 导入数据库驱动

在这里插入图片描述

② 编写代码

需要修改自己的数据库地址、用户名、密码

MySQLDemo.java

import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

class Product implements Serializable
{
	private static final long serialVersionUID = 1L;
	private String pId;
	private String pName;
	private double pPrice;
	private Integer pNumber;

	public String getpId()
	{
		return pId;
	}

	public void setpId(String pId)
	{
		this.pId = pId;
	}

	public String getpName()
	{
		return pName;
	}

	public void setpName(String pName)
	{
		this.pName = pName;
	}

	public double getpPrice()
	{
		return pPrice;
	}

	public void setpPrice(double pPrice)
	{
		this.pPrice = pPrice;
	}

	public Integer getpNumber()
	{
		return pNumber;
	}

	public void setpNumber(Integer pNumber)
	{
		this.pNumber = pNumber;
	}

	public static long getSerialversionuid()
	{
		return serialVersionUID;
	}

	@Override
	public String toString()
	{
		return "Product [pId=" + pId + ", pName=" + pName + ", pPrice=" + pPrice + ", pNumber=" + pNumber + "]";
	}

}

public class MySQLDemo
{
	public static void main(String[] args)
	{
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		List<Product> productList = new ArrayList<>();

		try
		{
			// 加载数据库驱动
			Class.forName("com.mysql.jdbc.Driver");
			// TODO:建立数据库连接(这个 url 需要更改个人数据库的信息)
			conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/productDB", "你的用户名", "你的密码");

			// 创建PreparedStatement查询所有记录
			String sql = "SELECT * FROM product";
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();

			// 遍历结果集,创建Product对象并添加到列表中
			while (rs.next())
			{
				Product product = new Product();
				product.setpId(rs.getString("pID"));
				product.setpName(rs.getString("pName"));
				product.setpPrice(rs.getDouble("pPrice"));
				product.setpNumber(rs.getInt("pNumber"));
				productList.add(product);
			}
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			// 关闭资源
			try
			{
				if (rs != null)
					rs.close();
				if (pstmt != null)
					pstmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException se)
			{
				se.printStackTrace();
			}
		}

		// 打印ArrayList中的数据
		for (Product product : productList)
		{
			System.out.println(product);
		}
	}
}

运行结果
在这里插入图片描述

4、 编程实现插入记录

pID=1005,pName=E,pPrice=60,pNumber=65

需要修改自己的数据库地址、用户名、密码

💖 InsertProduct.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class InsertProduct
{
	public static void main(String[] args)
	{
		// 数据库连接信息
		String url = "jdbc:mysql://127.0.0.1:3306/productDB"; // TODO:你的数据库URL
		String user = "root"; // TODO:你的数据库用户名
		String password = ""; // TODO:你的数据库密码

		// SQL插入语句
		String insertSQL = "INSERT INTO product (pID, pName, pPrice, pNumber) VALUES (?, ?, ?, ?)";

		// 使用try-with-resources自动关闭资源
		try (Connection conn = DriverManager.getConnection(url, user, password);
				PreparedStatement pstmt = conn.prepareStatement(insertSQL))
		{

			// 设置插入数据
			pstmt.setString(1, "1005"); // pID
			pstmt.setString(2, "E"); // pName
			pstmt.setDouble(3, 60); // pPrice
			pstmt.setInt(4, 65); // pNumber

			// 执行插入操作
			int rowsAffected = pstmt.executeUpdate();
			System.out.println("插入了 " + rowsAffected + " 行数据。");
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}

✨ 运行结果

在这里插入图片描述

5、 Java程序中使用事务,模拟实现银行转账功能

① 新建 account

USE productDB;
create table `account` (
	`account_id` varchar (765),
	`balance` double 
); 
insert into `account` (`account_id`, `balance`) values('1','1000');
insert into `account` (`account_id`, `balance`) values('2','0');

② 编写转账代码

需要修改自己的数据库地址、用户名、密码

💖 BankTransfer.java

import java.sql.*;

public class BankTransfer
{
	public static void main(String[] args)
	{
		// 数据库连接信息
		String url = "jdbc:mysql://120.78.6.196:3306/productDB"; // 数据库URL
		String user = "root"; // 数据库用户名
		String password = "20080808"; // 数据库密码
		Connection conn = null;
		PreparedStatement pstmt = null;

		try
		{
			// 加载数据库驱动
			Class.forName("com.mysql.jdbc.Driver");
			// 建立数据库连接
			conn = DriverManager.getConnection(url, user, password);

			// 关闭自动提交
			conn.setAutoCommit(false);

			transfer(conn, pstmt, false);
			transfer(conn, pstmt, true);
			// 提交事务

		} catch (Exception e)
		{
			try
			{
				if (conn != null)
				{
					System.out.println("转账异常,事务回滚!");
					conn.rollback(); // 回滚事务
					queryBalance(conn);
				}
			} catch (SQLException se)
			{
				se.printStackTrace();
			}
			e.printStackTrace();
		} finally
		{
			try
			{
				if (pstmt != null)
					pstmt.close();
				if (conn != null)
					conn.close();
			} catch (SQLException se)
			{
				se.printStackTrace();
			}
		}
	}

	private static void transfer(Connection conn, PreparedStatement pstmt, boolean isException) throws SQLException
	{
		System.out.println("转账开始...");
		queryBalance(conn);
		// 1. 先扣减A的100
		String transferSQL = "UPDATE account SET balance = balance - ? WHERE account_id = ?";
		pstmt = conn.prepareStatement(transferSQL);
		pstmt.setDouble(1, 100); // 转出金额
		pstmt.setInt(2, 1); // 转出账户ID
		pstmt.executeUpdate();

		// 模拟转账延迟或异常
		if (isException)
		{
			int a = 1 / 0;
		}

		// 2. 再增加B的100
		String depositSQL = "UPDATE account SET balance = balance + ? WHERE account_id = ?";
		pstmt = conn.prepareStatement(depositSQL);
		pstmt.setDouble(1, 100); // 转入金额
		pstmt.setInt(2, 2); // 转入账户ID
		pstmt.executeUpdate();
		conn.commit();
		System.out.println("转账成功");
		queryBalance(conn);
		System.out.println("转账结束\n");
	}

	private static void queryBalance(Connection conn) throws SQLException
	{
		// 查询A账户余额
		double balanceA_before = queryBalanceById(conn, 1);
		System.out.println("A账户余额: " + balanceA_before);

		// 查询B账户余额
		double balanceB_before = queryBalanceById(conn, 2);
		System.out.println("B账户余额: " + balanceB_before);
	}
		private static double queryBalanceById(Connection conn, int accountId) throws SQLException
	{
		String balanceQuery = "SELECT balance FROM account WHERE account_id = ?";
		try (PreparedStatement pstmt = conn.prepareStatement(balanceQuery))
		{
			pstmt.setInt(1, accountId);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
			{
				return rs.getDouble("balance");
			}
		}
		return 0.0; // 如果没有找到账户,返回0
	}
}

运行结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

私有云和多云管理平台 | Cloudpods v3.11.4 正式发布

本次 3.11.4 更新亮点为&#xff1a;系统镜像引入社区镜像&#xff0c;用户可以一键导入各主流开源操作系统镜像&#xff0c;方便用户上手使用。持续迭代共享 LVM&#xff0c;支持快照&#xff0c;主备机等特性&#xff0c;修复迁移删除镜像缓存等 BUG。 功能优化 【费用】费…

linux动态调试 dev_dbg

动态调试使用方法 打开内核动态调试开关&#xff0c;make menuconfig选中CONFIG_DYNAMIC_DEBUG以及CONFIG_DEBUG_FS Linux启动后&#xff0c;使用命令行挂载上dbgfs 1. mkdir /mnt/dbg 2. mount -t debugfs none /mnt/dbg 1.控制某个文件所有dev_dbg()&#xff0c; echo -n &q…

mongodb总概

一、mongodb概述 mongodb是最流行的nosql数据库&#xff0c;由C语言编写。其功能非常丰富&#xff0c;包括: 面向集合文档的存储:适合存储Bson(json的扩展)形式的数据;格式自由&#xff0c;数据格式不固定&#xff0c;生产环境下修改结构都可以不影响程序运行;强大的查询语句…

MSPM0l1306——配置滴答定时器

我们配置好了滴答定时器之后&#xff0c;还要手动编写滴答定时器的中断服务函数&#xff0c;因为我们开启的滴答定时器的中断&#xff0c;当滴答定时器的计数值从我们设置的值减到0时&#xff0c;就会触发一次中断&#xff0c;触发中断就会执行中断服务函数。各个中断的中断服务…

144、二叉树的前序递归遍历

题解&#xff1a; 递归书写三要素&#xff1a; 1&#xff09;确定递归函数的参数和返回值。要确定每次递归所要用到的参数以及需要返回的值 2&#xff09;确定终止条件。操作系统也是用栈的方式实现递归&#xff0c;那么如果不写终止条件或者终止条件写的不对&#xff0c;都…

Here Doucument

一、Here Document概述 1.概念 使用I/0重定向的方式将命令列表提供给交互式程序 标准输入的一种替代品 2.语法格式 命令 <<标记 标记 3.注意事项 标记可以使用任意合法字符&#xff08;通常为EOF&#xff09; 结尾的标记一定要顶格写&#xff0c;前面不能有任何字符…

【iOS】内存泄漏检查及原因分析

目录 为什么要检测内存泄漏&#xff1f;什么是内存泄漏&#xff1f;内存泄漏排查方法1. 使用Zombie Objects2. 静态分析3. 动态分析方法定位修改Leaks界面分析Call Tree的四个选项&#xff1a; 内存泄漏原因分析1. Leaked Memory&#xff1a;应用程序未引用的、不能再次使用或释…

Java数据结构准备工作---常用类

文章目录 前言1.包装类1.1.包装类基本知识1.2.包装类的用途1.3.装箱和拆箱1.3.1.装箱&#xff1a;1.3.2.拆箱 1.4 包装类的缓存问题 2.时间处理类2.1.Date 时间类(java.util.Date)2.2.DateFormat 类和 SimpleDateFormat 类2.3.Calendar 日历类 3.其他常用类3.1.Math类3.2.Rando…

嵌入式中C语言经典的面试题分享

#error的作用是什么? #error 指令让预处理器发出一条错误信息,并且会中断编译过程。下面我们从Linux代码中抽取出来一小段代码并做修改得到示例代码: 这段示例代码很简单,当RX_BUF_IDX宏的值不为0~3时,在预处理阶段就会通过 #error 指令输出一条错误提示信息: "…

Python 很好用的爬虫框架:Scrapy:

了解Scrapy 爬虫框架的工作流程&#xff1a; 在scrapy中&#xff0c; 具体工作流程是这样的&#xff1a; 首先第一步 当爬虫引擎<engine>启动后&#xff0c; 引擎会到 spider 中获取 start_url<起始url> 然后将其封装为一个request对象&#xff0c; 交给调度器<…

文心一言 VS 讯飞星火 VS chatgpt (277)-- 算法导论20.3 4题

四、如果调用 vEB-TREE-INSERT 来插入一个已包含在 vEB 树中的元素&#xff0c;会出现什么情况&#xff1f;如果调用 vEB-TREE-DELETE 来删除一个不包含在 vEB 树中的元素&#xff0c;会出现什么情况&#xff1f;解释这些函数为什么有相应的运行状况&#xff1f;怎样修改 vEB 树…

【手推公式】如何求SDE的解(附录B)

【手推公式】如何求SDE的解&#xff08;附录B&#xff09; 核心思路&#xff1a;不直接求VE和VP的SDE的解xt&#xff0c;而是求xt的期望和方差&#xff0c;从而写出x0到xt的条件分布形式&#xff08;附录B&#xff09; 论文&#xff1a;Score-Based Generative Modeling throug…

【SpringBoot + Vue 尚庭公寓实战】根据类型查询标签列表接口实现(五)

【SpringBoot Vue 尚庭公寓实战】根据类型查询标签列表接口实现&#xff08;五&#xff09; 文章目录 【SpringBoot Vue 尚庭公寓实战】根据类型查询标签列表接口实现&#xff08;五&#xff09;1、查看接口2、进行开发 1、查看接口 启动项目 访问&#xff1a;http://localho…

快排(快速排序)的递归与非递归实现(文末附完整代码)

快排有几种不同的写法&#xff0c;下面一一来介绍并实现。其中又分为递归和非递归的写法&#xff0c;但大体思路相同&#xff0c;只是代码实现略有不同。(注&#xff1a;文章中的完整代码中&#xff0c;Swap()函数均省略未写&#xff0c;记得自己补充) 递归写法 递归的写法类…

手写kNN算法的实现-用欧几里德空间来度量距离

kNN的算法思路&#xff1a;找K个离预测点最近的点&#xff0c;然后让它们进行投票决定预测点的类型。 step 1: kNN存储样本点的特征数据和标签数据step 2: 计算预测点到所有样本点的距离&#xff0c;关于这个距离&#xff0c;我们用欧几里德距离来度量&#xff08;其实还有很多…

LangChain4j实战

基础 LangChain4j模型适配: Provider Native Image Sync Completion Streaming Completion Embedding Image Generation Scoring Function Calling OpenAI ✅ ✅ ✅ ✅ ✅ ✅ Azure OpenAI ✅ ✅ ✅ ✅ ✅ Hugging Face ✅ ✅ Amazon Bedrock ✅ ✅…

UltraScale+系列模块化仪器,可以同时用作控制器、算法加速器和高速数字信号处理器

基于 XCZU7EG / XCZU4EG / XCZU2EG • 灵活的模块组合 • 易于嵌入的紧凑型外观结构 • 高性能的 ARM Cortex 处理器 • 成熟的 FPGA 可编程逻辑 &#xff0c;基于 IP 核的软件库 基于 Xilinx Zynq UltraScaleMPSoC 的 FPGA 技术&#xff0c;采用 Xilinx Zynq UltraScale&a…

陆面生态水文模拟与多源遥感数据同化技术

原文链接&#xff1a;陆面生态水文模拟与多源遥感数据同化技术 了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用;熟悉模 型的发展历程&#xff0c;常见模型及各自特点;理解Noah-MP模型的原理&#xff0c;掌握Noah-MP 模型在单 站和区域的模拟、模拟结果的…

华为坤灵路由器配置SSH

配置SSH服务器的管理网口IP地址。 <HUAWEI> system-view [HUAWEI] sysname SSH Server [SSH Server] interface meth 0/0/0 [SSH Server-MEth0/0/0] ip address 10.248.103.194 255.255.255.0 [SSH Server-MEth0/0/0] quit 在SSH服务器端生成本地密钥对。 [SSH Server…

C语言:定义和使用结构体变量

定义和使用结构体变量 介绍基础用法1.定义结构体2. 声明结构体变量3. 初始化和访问结构体成员4. 使用指针访问结构体成员5. 使用结构体数组 高级用法6. 嵌套结构体7. 匿名结构体8. 结构体和动态内存分配9. 结构体作为函数参数按值传递按引用传递 介绍 在C语言中&#xff0c;结…