使用 jdbc 技术升级水果库存系统(优化版本)
- 抽取执行更新方法
- 抽取查询方法 —— ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();//元数据,结果集的结构数据
- 抽取查询方法 —— 解析结果集封装成实体对象
- 提取 获取连接 和 释放资源 的方法
- 将数据库配置信息转移到配置文件
<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies>
package com.csdn.fruit.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @NoArgsConstructor @AllArgsConstructor public class Fruit implements Serializable {private Integer fid;private String fname;private Integer price;private Integer fcount;private String remark;public Fruit(String fname, Integer price, Integer fcount, String remark) {this.fname = fname;this.price = price;this.fcount = fcount;this.remark = remark;}@Overridepublic String toString() {return fname + "\t\t" + price + "\t\t" + fcount + "\t\t" + remark;} }
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql:///fruitdb jdbc.user=root jdbc.pwd=123456
package com.csdn.mymvc.dao; import com.csdn.mymvc.util.ClassUtil; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Properties; public abstract class BaseDao<T> {private String DRIVER;private String URL;private String USER;private String PWD;private String entityClassName;public BaseDao() {// this 是谁? this代表的是 FruitDaoImpl 的实例对象,因为 BaseDao是抽象类,不能直接创建对象,所以 new 的是它的子类对象 FruitDaoImpl// this.getClass() 获取的是 FruitDaoImpl 的Class对象// getGenericSuperclass() 获取到的是:BaseDao<Fruit>// Type 是顶层接口,表示所有的类型。它有一个子接口:ParameterizedTypeParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();// Actual:实际的// getActualTypeArguments() 获取实际的类型参数Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();Type actualTypeArgument = actualTypeArguments[0];// System.out.println(actualTypeArgument.getTypeName());//com.csdn.fruit.pojo.FruitentityClassName = actualTypeArgument.getTypeName();loadJdbcProperties();}//加载jdbc.properties文件private void loadJdbcProperties() {try {InputStream inputStream = getClass().getClassLoader().getResourceAsStream("jdbc.properties");Properties properties = new Properties();properties.load(inputStream);DRIVER = properties.getProperty("jdbc.driver", "com.mysql.cj.jdbc.Driver");URL = properties.getProperty("jdbc.url", "jdbc:mysql:///fruitdb");USER = properties.getProperty("jdbc.user", "root");PWD = properties.getProperty("jdbc.pwd", "123456");} catch (IOException e) {throw new RuntimeException(e);}}private Connection getConn() {try {Class.forName(DRIVER);return DriverManager.getConnection(URL, USER, PWD);} catch (ClassNotFoundException | SQLException e) {throw new RuntimeException(e);}}private void close(Connection conn, PreparedStatement psmt, ResultSet rs) {try {if (rs != null) {rs.close();}if (psmt != null) {psmt.close();}if (conn != null && !conn.isClosed()) {conn.close();}} catch (SQLException e) {throw new RuntimeException(e);}}//抽取执行更新方法//执行更新,返回影响行数protected int executeUpdate(String sql, Object... params) {PreparedStatement psmt = null;Connection conn = null;try {conn = getConn();psmt = conn.prepareStatement(sql);setParams(psmt, params);return psmt.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);} finally {close(conn, psmt, null);}}//设置参数private void setParams(PreparedStatement psmt, Object... params) throws SQLException {if (params != null && params.length > 0) {for (int i = 0; i < params.length; i++) {psmt.setObject(i + 1, params[i]);}}}//执行查询,返回集合protected List<T> executeQuery(String sql, Object... params) {List<T> list = new ArrayList<>();Connection conn = null;PreparedStatement psmt = null;ResultSet rs = null;try {conn = getConn();psmt = conn.prepareStatement(sql);setParams(psmt, params);rs = psmt.executeQuery();ResultSetMetaData rsmd = rs.getMetaData();//元数据,结果集的结构数据while (rs.next()) {//T t = new T(); T仅仅是一个符号,所以不能 newT t = (T) ClassUtil.createInstance(entityClassName);int columnCount = rsmd.getColumnCount();//获取结果集的列的数据//jdbc中都是从 1 开始,所以要把 i 改成 从 1 开始for (int i = 1; i <= columnCount; i++) {//假设循环 5 次,得到 5 个值,应该对应的是一个对象的 5 个属性的值String columnName = rsmd.getColumnLabel(i);Object columnValue = rs.getObject(i);//给 t 这个对象的 columnName 属性赋 columnValue 值ClassUtil.setProperty(t, columnName, columnValue);}list.add(t);}return list;} catch (SQLException e) {throw new RuntimeException(e);} finally {close(conn, psmt, rs);}}protected T load(String sql, Object... params) {Connection conn = null;PreparedStatement psmt = null;ResultSet rs = null;try {conn = getConn();psmt = conn.prepareStatement(sql);setParams(psmt, params);rs = psmt.executeQuery();ResultSetMetaData rsmd = rs.getMetaData();//元数据,结果集的结构数据if (rs.next()) {//T t = new T(); T仅仅是一个符号,所以不能 newT t = (T) ClassUtil.createInstance(entityClassName);int columnCount = rsmd.getColumnCount();//获取结果集的列的数据//jdbc中都是从 1 开始,所以要把 i 改成 从 1 开始for (int i = 1; i <= columnCount; i++) {//假设循环 5 次,得到 5 个值,应该对应的是一个对象的 5 个属性的值String columnName = rsmd.getColumnLabel(i);Object columnValue = rs.getObject(i);//给 t 这个对象的 columnName 属性赋 columnValue 值ClassUtil.setProperty(t, columnName, columnValue);}return t;}} catch (SQLException e) {throw new RuntimeException(e);} finally {close(conn, psmt, rs);}return null;} }
package com.csdn.mymvc.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class ClassUtil {public static Object createInstance(String entityClassName) {try {return Class.forName(entityClassName).getDeclaredConstructor().newInstance();} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException |ClassNotFoundException e) {throw new RuntimeException(e);}}public static void setProperty(Object instance, String propertyName, Object propertyValue) {Class<?> aClass = instance.getClass();try {Field field = aClass.getDeclaredField(propertyName);field.setAccessible(true);field.set(instance, propertyValue);} catch (NoSuchFieldException | IllegalAccessException e) {throw new RuntimeException(e);}} }
package com.csdn.fruit.dao; import com.csdn.fruit.pojo.Fruit; import java.util.List; //dao :Data Access Object 数据访问对象 //接口设计 public interface FruitDao {void addFruit(Fruit fruit);void delFruit(String fname);void updateFruit(Fruit fruit);List<Fruit> getFruitList();Fruit getFruitByFname(String fname); }
package com.csdn.fruit.dao.impl; import com.csdn.fruit.dao.FruitDao; import com.csdn.fruit.pojo.Fruit; import com.csdn.mymvc.dao.BaseDao; import java.util.List; public class FruitDaoImpl extends BaseDao<Fruit> implements FruitDao {@Overridepublic void addFruit(Fruit fruit) {String sql = "insert into t_fruit values (0,?,?,?,?)";super.executeUpdate(sql, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());}@Overridepublic void delFruit(String fname) {String sql = "delete from t_fruit where fname=?";super.executeUpdate(sql, fname);}@Overridepublic void updateFruit(Fruit fruit) {String sql = "update t_fruit set fcount=? where fname = ?";super.executeUpdate(sql, fruit.getFcount(), fruit.getFname());}@Overridepublic List<Fruit> getFruitList() {return super.executeQuery("select * from t_fruit");}@Overridepublic Fruit getFruitByFname(String fname) {return load("select * from t_fruit where fname = ?", fname);} }
package com.csdn.fruit.view; import com.csdn.fruit.dao.FruitDao; import com.csdn.fruit.dao.impl.FruitDaoImpl; import com.csdn.fruit.pojo.Fruit; import java.util.List; import java.util.Scanner; public class Menu {Scanner input = new Scanner(System.in);private FruitDao fruitDao = new FruitDaoImpl();//显示主菜单public int showMainMenu() {System.out.println("================欢迎使用水果库存系统===================");System.out.println("1.显示库存列表");System.out.println("2.添加库存记录");System.out.println("3.查看特定库存");System.out.println("4.水果下架");System.out.println("5.退出");System.out.println("====================================================");System.out.print("请选择:");return input.nextInt();}//显示库存列表public void showFruitList() {List<Fruit> fruitList = fruitDao.getFruitList();System.out.println("----------------------------------------------------");System.out.println("名称\t\t单价\t\t库存\t\t备注");if (fruitList == null || fruitList.size() <= 0) {System.out.println("对不起,库存为空!");} else {/* fruitList.forEach(new Consumer<Fruit>() {@Overridepublic void accept(Fruit fruit) {System.out.println(fruit);}});*/// fruitList.forEach(fruit -> System.out.println(fruit));fruitList.forEach(System.out::println);}System.out.println("----------------------------------------------------");}//添加库存记录public void addFruit() {System.out.print("请输入水果名称:");String fname = input.next();Fruit fruit = fruitDao.getFruitByFname(fname);if (fruit == null) {System.out.print("请输入水果单价:");Integer price = input.nextInt();System.out.print("请输入水果库存:");Integer fcount = input.nextInt();System.out.print("请输入水果备注:");String remark = input.next();fruit = new Fruit(fname, price, fcount, remark);fruitDao.addFruit(fruit);} else {System.out.print("请输入追加的库存量:");Integer fcount = input.nextInt();fruit.setFcount(fruit.getFcount() + fcount);fruitDao.updateFruit(fruit);}System.out.println("添加成功!");}//查看特定库存记录public void showFruitInfo() {System.out.print("请输入水果名称:");String fname = input.next();Fruit fruit = fruitDao.getFruitByFname(fname);if (fruit == null) {System.out.println("对不起,没有找到对应的库存记录!");} else {System.out.println("----------------------------------------------------");System.out.println("名称\t\t单价\t\t库存\t\t备注");System.out.println(fruit);System.out.println("----------------------------------------------------");}}//水果下架public void delFruit() {System.out.print("请输入水果名称:");String fname = input.next();Fruit fruit = fruitDao.getFruitByFname(fname);if (fruit == null) {System.out.println("对不起,没有找到需要下架的库存记录!");} else {System.out.print("是否确认下架?(Y/N)");String confirm = input.next();if ("y".equalsIgnoreCase(confirm)) {fruitDao.delFruit(fname);}}}//退出public boolean exit() {System.out.print("是否确认退出?(Y/N)");String confirm = input.next();boolean flag= !"y".equalsIgnoreCase(confirm);return flag;} }
package com.csdn.fruit.view; public class Client {public static void main(String[] args) {Menu m = new Menu();boolean flag = true;while (flag) {int slt = m.showMainMenu();switch (slt) {case 1:m.showFruitList();break;case 2:m.addFruit();break;case 3:m.showFruitInfo();break;case 4:m.delFruit();break;case 5://方法设计时是否需要返回值,依据是:是否在调用的地方需要留下一些值用于再运算flag = m.exit();break;default:System.out.println("你不按套路出牌!");break;}}System.out.println("谢谢使用!再见!");} }
package com.csdn.dao.impl; import com.csdn.fruit.dao.FruitDao; import com.csdn.fruit.dao.impl.FruitDaoImpl; import com.csdn.fruit.pojo.Fruit; import org.junit.Test; import java.util.List; public class FruitDaoImplTest {private FruitDao fruitDao = new FruitDaoImpl();@Testpublic void testAddFruit() {Fruit fruit = new Fruit("香蕉", 7, 77, "波罗蜜是一种神奇的水果!");fruitDao.addFruit(fruit);}@Testpublic void testDelFruit() {fruitDao.delFruit("哈密瓜");}@Testpublic void testUpdateFruit() {Fruit fruit = new Fruit("波罗蜜", 5, 1000, "好吃");fruitDao.updateFruit(fruit);}@Testpublic void testGetFruitList() {List<Fruit> fruitList = fruitDao.getFruitList();fruitList.stream().forEach(System.out::println);}@Testpublic void testGetFruitByFname() {Fruit fruit = fruitDao.getFruitByFname("波罗蜜");System.out.println(fruit);}/*// this 是谁? this代表的是 FruitDaoImpl 的实例对象,因为 BaseDao是抽象类,不能直接创建对象,所以 new 的是它的子类对象 FruitDaoImpl// this.getClass() 获取的是 FruitDaoImpl 的Class对象// getGenericSuperclass() 获取到的是:BaseDao<Fruit>// Type 是顶层接口,表示所有的类型。它有一个子接口:ParameterizedTypeParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();// Actual:实际的// getActualTypeArguments() 获取实际的类型参数Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();Type actualTypeArgument = actualTypeArguments[0];// System.out.println(actualTypeArgument.getTypeName());//com.csdn.fruit.pojo.FruitentityClassName = actualTypeArgument.getTypeName();loadJdbcProperties(); */@Testpublic void testActualTypeArgument() {//这个方法是用来测试 actualTypeArgument 实际返回的参数} }
相关文章:

使用 jdbc 技术升级水果库存系统(优化版本)
抽取执行更新方法抽取查询方法 —— ResultSetMetaData ResultSetMetaData rsmd rs.getMetaData();//元数据,结果集的结构数据 抽取查询方法 —— 解析结果集封装成实体对象提取 获取连接 和 释放资源 的方法将数据库配置信息转移到配置文件 <dependencies><depend…...

网络协议--广播和多播
12.1 引言 在第1章中我们提到有三种IP地址:单播地址、广播地址和多播地址。本章将更详细地介绍广播和多播。 广播和多播仅应用于UDP,它们对需将报文同时传往多个接收者的应用来说十分重要。TCP是一个面向连接的协议,它意味着分别运行于两主…...
python爬虫入门(三)正则表达式
开源中国提供的正则表达式测试工具 http://tool.oschina.net/regex/,输入待匹配的文本,然后选择常用的正则表达式,就可以得出相应的匹配结果了 常用的匹配规则如下 模 式描 述\w匹配字母、数字及下划线\W匹配不是字母、数字及下划线的…...
fabric.js介绍
fabric.js是可以简化canvas编写的js库,提供canvas缺少的对象模型,包含动画、数据序列化和反序列化的等高级功能的js库,开源项目,在GitHub有很多人贡献。 官网:Fabric.js Javascript Canvas Library (fabricjs.com) 文档…...

YOLOv5源码中的参数超详细解析(3)— 训练部分(train.py)| 模型训练调参
前言:Hello大家好,我是小哥谈。YOLOv5项目代码中,train.py是用于模型训练的代码,是YOLOv5中最为核心的代码之一,而代码中的训练参数则是核心中的核心,只有学会了各种训练参数的真正含义,才能使用YOLOv5进行最基本的训练。🌈 前期回顾: YOLOv5源码中的参数超详细解析…...

Linux高性能编程学习-TCP/IP协议族
一、TCP/IP协议族结构与主要协议 分层:数据链路层、网络层、传输层、应用层 1. 数据链路层 功能:实现网卡驱动程序,处理数据在不同物理介质的传输 协议: ARP:将目标机器的IP地址转成MAC地址RARP:将MAC地…...

用爬虫代码爬取高音质音频示例
目录 一、准备工作 1、安装Python和相关库 2、确定目标网站和数据结构 二、编写爬虫代码 1、导入库 2、设置代理IP 3、发送HTTP请求并解析HTML页面 4、查找音频文件链接 5、提取音频文件名和下载链接 6、下载音频文件 三、完整代码示例 四、注意事项 1、遵守法律法…...

深度学习与计算机视觉(一)
文章目录 计算机视觉与图像处理的区别人工神经元感知机 - 分类任务Sigmoid神经元/对数几率回归对数损失/交叉熵损失函数梯度下降法- 极小化对数损失函数线性神经元/线性回归均方差损失函数-线性回归常用损失函数使用梯度下降法训练线性回归模型线性分类器多分类器的决策面 soft…...

【vector题解】杨辉三角 | 删除有序数组中的重复项 | 只出现一次的数字Ⅱ
杨辉三角 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1…...

金字塔切分注意力模块PSA学习笔记 (附代码)
已有研究表明:将注意力模块嵌入到现有CNN中可以带来显著的性能提升。比如,SENet、BAM、CBAM、ECANet、GCNet、FcaNet等注意力机制均带来了可观的性能提升。但是,目前仍然存在两个具有挑战性的问题需要解决。一是如何有效地获取和利用不同尺度…...

Jenkins自动化测试
学习 Jenkins 自动化测试的系列文章 Robot Framework 概念Robot Framework 安装Pycharm Robot Framework 环境搭建Robot Framework 介绍Jenkins 自动化测试 1. Robot Framework 概念 Robot Framework是一个基于Python的,可扩展的关键字驱动的自动化测试框架。 它…...

python 字典dict和列表list的读取速度问题, range合并
嗨喽,大家好呀~这里是爱看美女的茜茜呐 python 字典和列表的读取速度问题 最近在进行基因组数据处理的时候,需要读取较大数据(2.7G)存入字典中, 然后对被处理数据进行字典key值的匹配,在被处理文件中每次…...

测试用例的设计方法(全):等价类划分方法
一.方法简介 1.定义 是把所有可能的输入数据,即程序的输入域划分成若干部分(子集),然后从每一个子集中选取少数具有代表性的数据作为测试用例。该方法是一种重要的,常用的黑盒测试用例设计方法。 2.划分等价类: 等价类是指某个输入域的…...

Office技巧(持续更新)(Word、Excel、PPT、PowerPoint、连续引用、标题、模板、论文)
1. Word 1.1 标题设置为多级列表 选住一级标题,之后进行“定义新的多级列表” 1.2 图片和表的题注自动排序 正常插入题注后就可以了。如果一级标题是 “汉字序号”,那么需要对题注进行修改: 从原来的 图 { STYLEREF 1 \s }-{ SEQ 图 \* A…...

Java实现ORM第一个api-FindAll
经过几天的业余开发,今天终于到ORM对业务api本身的实现了,首先实现第一个查询的api 老的C#定义如下 因为Java的泛型不纯,所以无法用只带泛型的方式实现api,对查询类的api做了调整,第一个参数要求传入实体对象 首先…...

HFSS笔记——求解器和求解分析
文章目录 1、求解器2、求解类型3、自适应网格剖分4、求解频率选择4.1 求解设置项的含义4.2 扫频类型 1、求解器 自从ANSYS将HFSS收购后,其所有的求解器都集成在一起了,点击Project,会显示所有的求解器类型。 其中, HFSS design&…...

jenkins配置gitlab凭据
下载Credentials Binding插件(默认是已经安装了) 在凭据配置里添加凭据类型 点击保存 Username with password: 用户名和密码 SSH Username with private 在凭据管理里面添加gitlab账号和密码 点击全局 点击添加凭据(版本不同…...

0基础学习PyFlink——用户自定义函数之UDTF
大纲 表值函数完整代码 在《0基础学习PyFlink——用户自定义函数之UDF》中,我们讲解了UDF。本节我们将讲解表值函数——UDTF 表值函数 我们对比下UDF和UDTF def udf(f: Union[Callable, ScalarFunction, Type] None,input_types: Union[List[DataType], DataTy…...

【Java 进阶篇】Java Request 原理详解
在网络应用开发中,HTTP请求是一项常见而关键的任务。当我们使用Java编写网络应用时,了解HTTP请求的工作原理变得至关重要。本文将详细介绍Java中HTTP请求的原理,包括请求的结构、发送请求的方法以及处理请求的过程。 HTTP请求的基本结构 HT…...

13 结构性模式-装饰器模式
1 装饰器模式介绍 在软件设计中,装饰器模式是一种用于替代继承的技术,它通过一种无须定义子类的方式给对象动态的增加职责,使用对象之间的关联关系取代类之间的继承关系. 2 装饰器模式原理 //抽象构件类 public abstract class Component{public abstract void operation(); }…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...