Maven
Maven
1.什么是Maven
官方网站 https://maven.apache.org/
Maven是一款服务于Java平台的自动化构建工具,它可以帮助我们更方便的对项目进行构建、管理项目jar包
,包括: bulid 项目,切换 jar 版本,添加 jar, 删除 jar 包等
1.1 Maven下载和安装
-
第 1 种方式: 直接使用 idea 自带的 Maven
-
第 2 种方式: 自己下载 Maven 软件, 安装、配置并使用.
-
下载地址 https://archive.apache.org/dist/maven/maven-3/
安装步骤
- 直接解 maven 安装到指定目录
- 目录结构说明
- maven 使用需要依赖 jdk ,因此事先要保证安装了 jdk1.8 以上
- 配置环境变量 MAVEN_HOME
- 配置环境变量 PATH, 增加 Maven 的路径, (如果有多个 Maven 的 Path, 可以上移, 提高优先级)
- 测试是否安装 maven 成功.
1.2 Maven 工作原理图
- 在 maven 项目的 pom.xml, 可以配置项目依赖的 jar(指定坐标即可)
- maven 根据配置, 到中央仓库/私服 去获取 jar,下载到本地仓库
- maven 项目, 会引用本地仓库的 jar ,完成项目开发
- 在 maven 项目构建生命周期中,每个阶段的执行都有相应的插件完成
- 各个插件执行过程中,会附带输出内容,比如 jar/war/xml/源码
- 程序员可以使用 maven 默认的插件,也可以自定义插件,完成定制任务.
Maven 项目统一的开发结构分析:
2.Maven 相关概念
2.1仓库:存储项目需要的 jar 包
- 几乎所有的 jar 包都保存在中央仓库 . 地址: https://mvnrepository.com/
- 本地仓库:在使用 maven 时,会将需要的 jar 下载到本地,保存在指定目录下,称为本地仓库(如图)
- 私服: 开发团队搭建的存储资源的仓库,可以个性化仓库(比如只供团队使用的 jar), 同时提升下载速度
- 我们个人开发时,可以直接从中央仓库下,如果想提升下载速度,可以设置镜像仓库
2.2 坐标
作用: 资源的唯一标识,定位 Maven 仓库中资源的位置
坐标构成
- groupld(组织 id): 定义当前 Maven 项目隶属组织名称(例如∶com.spring)
- artifactId(项目 ID): 定义当前 Maven 项目名称
- version(版本号): 定义当前项目版本号
- 如何获取 jar 坐标
- 比如 mysql jar
3.Maven构建指令
3.1 完成编译
- 编译指令
mvn compile
-
编程成功,会自动创建 target 目录,并生成对应的.class 文件(如图)
-
细节说明: 第一次速度慢,需要下载相关 jar,后面就快了.
3.2完成测试
- 测试指令
mvn test
-
测试指令执行完毕,会生成 Test 源文件的 class , 还会输出测试结果
-
细节说明: 第一次速度慢,需要完成一些初始化工作,后面就快了
3.3 完成打包
- 打包指令
mvn package
- 打包后,在 target 目录生成对应的 打包文件 jar
3.4 完成安装
- 执行 install 指令,能完成 maven 项目的安装,会把打包得到的 jar, 提交到本地仓库
- 当把 maven-project01-1.0-SNAPSHOT.jar 提交到本地仓库后,该 jar 也可以被其他 maven 项目使用了,非常方便
3.5完成清理
-
执行如下指令,完成 maven 项目的清理,会清除生成的 target 目录
mvn clean
3.6小结 Maven 构建指令
● 说明: Maven 构建命令使用 mvn 开头,后面添加功能参数,可以一次执行多个命令,使
用空格分隔
mvn compile #编译
mvn clean #清理
mvn test #测试
mvn package #打包
mvn install #安装
4.IDEA创建 Maven Web 工程
- 需求说明/图解
-
创建成功的 maven web 项目结构
-
创建的 pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!--1. 前面三个 groupId , artifactid 和 version 就是该 maven 项目坐标2. package 是打包方式,默认是 jar , 这里是 war(因为这是 web 项目)--><groupId>com.llp</groupId><artifactId>maven-javaWeb</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><name>maven-javaWeb Maven Webapp</name><url>http://www.example.com</url><!--maven项目的属性,根据实际情况可以修改--><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!--创建maven项目默认引入的jar--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies><!--默认引入的 maven 插件, 前面说过 mvn 的各种指令 compile/install/test 等都是由插件完成的 --><build><finalName>maven-javaWeb</finalName><pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --><plugins><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --><plugin><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.0</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version></plugin><plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin></plugins></pluginManagement></build>
</project>
- 配置 Tomcat 服务器&运行
- 为 maven web 项目配置 tomcat
5.Maven依赖管理
5.1依赖配置
一句话: 依赖指当前项目运行需要的 jar,一个项目可以设置多个依赖
● 依赖的举例
<!--
1. 这里就是引入项目需要的 jar 包, 类似传统的 import jar 的作用
2. 在 dependencies 标签内,可以指定多个需要依赖的 jar/导入的 jar
3. 引入的 jar 包需要一个完整的 jar 包坐标,从 mvn 仓库查询即可得到--><dependencies><!-- 引入的一个具体的依赖 jar, 包括一个完整的依赖坐标 --><dependency><!-- 依赖的 gruopid: 组织名 --><groupId>junit</groupId><!-- 依赖的项目名 --><artifactId>junit</artifactId><!-- 依赖的版本 --><version>4.12</version><scope>test</scope></dependency></dependencies>
5.2依赖传递
直接依赖: 在当前项目中通过依赖配置建立的依赖关系
比如,在项目的pom.xml文件中,引入mysql8.0.27,这时我们就说项目直接依赖了mysql8.0.27
<!--引入mysql依赖-->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.27</version>
</dependency>
5.3间接依赖
间接依赖: 当前项目直接依赖资源(比如 m1), 而 m1 又依赖资源(m2),我们就说 当前项目间接依赖资源(m2)
比如,项目A引入了一个mysql8.0.27的jar,而项目B有引入了A项目的jar,这样就形成了间接依赖
5.4依赖冲突
路径优先
-
路径优先∶当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高
-
示意图说明:
- 项目 A 依赖情况
-
如果 1 度资源有 junit 4.1 , 而 2 度资源有 junit4.2
-
根据路径优先原则, 项目 A 生效的是 junit4.1
声明优先
- 声明优先∶当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的
- 示意图说明:
特殊优先
- 特殊优先∶当同级配置了相同资源的不同版本,后配置的覆盖先配置的(要尽量避免这种没有意义的冲突)
5.5可选依赖
可选依赖:可选依赖指对外隐藏当前所依赖的资源 - 不透明
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><!--optional:默认是false,表示不隐藏optional:设置为true,表示隐藏,其他模块就没办法使用--><optional>true</optional><scope>test</scope></dependency>
5.6 排除依赖
一句话: 排除依赖指主动断开依赖的资源, 被排除的资源无需指定版本- 不需要
<dependencies><dependency><groupId>com.llp</groupId><artifactId>maven-project-2</artifactId><version>1.0-SNAPSHOT</version><!--1.指定要排除的依赖2.可以排除多个,在exclusions下添加多个exclusion即可--><exclusions><exclusion><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></exclusion></exclusions></dependency>
</dependencies>
5.7可选依赖和排除依赖区别
一句话: 隐藏依赖是不让其他项目来引用(我不给), 排除依赖是主动不要引入的某个资源(我不要)
5.8依赖范围
一句话: 依赖的 jar 默认情况可以在任何地方使用, 通过 scope 标签设定其作用范围
● 作用范围说明
- 主程序范围有效(src/main 文件夹范围内)
- 测试程序范围有效(src/test 文件夹范围内)
- 是否参与打包(package 指令范围内)
- compile(默认,在主程序、测试代码、打包都有效)
● 作用范围一览图
- 某个引入的 jar 包作用范围是程序员根据,业务的实际需要来设置的,不要认为是固定的。
- 比如 log4j jar 包,在主程序,测试代码,打包都是需要的, 因此作用范围应当设置为complie
- junit 只是测试代码需要,因此作用范围设置为 test 合适,但是如果程序员认为在主程序和打包就是要 junit, 仍然可以设置为默认 compile
- 比如 servlet-api 是 tomcat 自己带的,当把程序打包放到生产环境时,用生产环境tomcat 的 servlet-api 即可,所以设置为 provided 合适,这样就放在 servlet-api 版本冲突.
- 比如 jdbc, 是第三方的 jar , 打包放在生产环境,就应当在自己的包提供 jdbc 驱动包,否则程序会因为少驱动包,运行失败
6.Maven 项目构建生命周期
一句话: Maven 构建生命周期描述的是一次构建过程经历了多少个事件
6.1生命周期的 3 大阶段
- clean∶清理工作
- default∶核心工作,例如编译,测试,打包,部署等
- site∶产生报告,发布站点等
6.2 生命周期是分阶段执行的
一句话: 项目构建生命周期分很多阶段,并不是每次都完整执行,而是根据用户的要求
来执行的【比如你执行 compile, 那么就执行到 complie 这个阶段,如果你执行 install, 则会
执行 compile->test->package->install】
7.maven 插件
7.1介绍
-
插件与生命周期内的某个阶段绑定,在执行到对应生命周期时, 由对应插件来完成任务/功能.
-
maven 插件很多,先看一张图:
- 通过插件可以自定义其他功能
7.2 文档
文档: http://maven.apache.org/plugins/index.html
7.3自定义插件-应用实例
需求: 在 pom.xml 加入自定义插件,能够在对 maven_D 项目 打包时,能输出主程序和测试程序的源码
● 完成步骤
- 当前 package 只会得到项目的 jar
- 修改 D:\java_projects\maven_D\pom.xml, 加入 maven 插件 并配置(注意: 加入自定义插件后,可能会爆红,重启项目即可.)
<!-- 在build时, 自定义插件 -->
<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>2.2.1</version><executions><execution><goals><!-- 对主程序输出源码打包 --><goal>jar</goal><!-- 对测试程序输出源码打包 --><goal>test-jar</goal></goals><!-- 指定执行阶段 --><phase>generate-test-resources</phase></execution></executions></plugin></plugins>
</build>
- 观察一下 maven 项目管理器
- 再次执行 maven-D 的 intall 操作, 会得到两个新的 jar ,分别包含了主程序和测试程序的源码。(测试时,需要保证 src/main/… 和 src/test/… 两个目录下有 java 源代码,否则不会生成源码 jar)
7.4maven 插件-maven 构建生命周期关系图
- 在 maven 项目构建生命周期中,每个阶段的执行都有相应的插件完成
- 各个插件执行过程中,会附带输出内容,比如 jar/war/xml/源码
- 程序员可以使用 maven 默认的插件,也可以自定义插件,完成定制任务.
- 自定义插件引入成功, 是可以看到
相关文章:
Maven
Maven 1.什么是Maven 官方网站 https://maven.apache.org/ Maven是一款服务于Java平台的自动化构建工具,它可以帮助我们更方便的对项目进行构建、管理项目jar包 ,包括: bulid 项目,切换 jar 版本,添加 jar, 删除 jar 包等 1.…...
1947抓住那头牛(队列 广度优先搜索)
目录 题目描述 解析 解题思路 代码部分 代码部分 运行结果 看看len数组中各个位置的标记值 为什么这样做一定是最短路径: 题目描述 农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<N<100000)&…...
基于linux5.15.5的IMX 参考手册 ---21
基于linux5.15.5的IMX 参考手册 — 21 10.5.2高清多媒体接口(HDMI)和显示端口(DP)概述 10.5.2.1测试名称 •mxc_cec_test.out 10.5.2.1.1位置 /unit_tests/HDMI/ 10.5.2.1.2功能 验证HDMI CEC功能并向HDMI接收器发送断电命令。 1…...
Android Dalvik虚拟机 堆初始化流程
前言 上篇文章介绍了dalvik虚拟机启动流程,在dalvik虚拟机启动时调用了dvmGcStartup来启动堆。 本文介绍我们在日常开发使用Java时的堆创建流程。 Dalvik堆介绍 Dalvik虚拟机中,堆是由heap[0] Active堆和heap[1] Zygote堆两部分组成的。其中ÿ…...
0讲(补)——开发前必备基本常识
前言 专栏内容持续补充更新,目前正在进行优惠活动 目录 前言 一、函数的声明和定义 二、预编译 三、串口打印中的printf函数的使用...
JS学习笔记
1.WebAPIs简介导读Web APIs 和JS 基础关联性JS 基础阶段以及 Web APIs 阶段JS基础学习 ECMAScript 基础语法为后面作铺垫,Web APIs 是JS 的应用,大量使用JS基础语法做交互效果①JS 基础阶段我们学习的是ECMAScript 标准规定的基本语法要求同学们掌握JS 基…...
linux005之用户、组管理
linux用户管理简介: 任何使用linux系统的用户,都必须使用一个合法的账号和密码,账号和密码一般都是超级管理员创建,当然普通用户也可以创建用户,前提是必须拥有创建用户权限。 root是linux系统中默认创建的超级用户 创…...
列线图工具_Nomogram
定义 列线图是一种相对传统的分析方法,用于展示自变量和因变量的线性关系,及其特征的重要程度。 现在用SHAP,和机器学习库中的 Feature importance 工具可以实现类似甚至更好效果。不过很多传统的研究领域比较认这种方法。 列线图工具建立在…...
【C++】类和对象(一)
目录一、面向过程和面向对象初步认识二、类的引入三、类的定义四、类的访问限定符及封装4.1、访问限定符4.2、封装五、类的作用域六、类的实例化七、类对象的大小八、this指针8.1、this指针的引出8.2、this指针的特性8.3、C语言和C实现Stack的对比一、面向过程和面向对象初步认…...
Python获取搜索引擎结果
前言 想快速获取各个高校的博士招生网站,于是通过python先获取出有可能包含高校博士招生网站的URL,然后通过人为筛选得到了想要的招生网站(注意,并非直接爬取,是间接获取的)。 整理了一份网站名单&#x…...
2.4.8 PCIe——物理逻辑层——REFCLK
一、概述 pcie的参考时钟由板级输入,提供给IP内PHY层的PLL使用,由PLL产生core_clk和pipe_clk。 二、REFCLK产生方式 Serdes 所用时钟由 PHY 模块内的PLL生成,PLL的参考时钟可以由common clock(外部背板提供)、separ…...
树莓派4B arm64 搭建 docker+drone+gitea
树莓派4B arm64 搭建 dockerdronegitea 记录时间: 2023年02月10日 树莓派烧录 如何用树莓派搭建一台永久运行的个人服务器? https://mp.weixin.qq.com/s?__bizMzI5NjA0ODkwNA&mid2651847658&idx1&sn267a1257b43d4a76f2a081ed157b77f9&chksmf7b11…...
Java的JDBC编程
目录 1. 打开IDEA,新建Project 2. 引入依赖 (1)下载驱动包 (2)将驱动包导入Project 3. 编写代码 (1)创建数据源 (2)让代码和数据库服务器建立联系 (3&…...
CSS:块格式化上下文(BFC)
块格式化上下文是块级盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。 块格式化上下文(BFC)的创建 满足以下条件将创建块格式化上下文: 根元素()浮动元素(float 值不为 none)绝对定位元素…...
paddle表情识别部署
表情识别模块1.环境部署1.1同样采用fastDeploy库1.2相关模型2.封装成静态库2.1参考[百度Paddle中PP-Mattingv2的部署并将之封装并调用一个C静态库](https://blog.csdn.net/weixin_43564060/article/details/128882099)2.2项目依赖添加2.3生成成功3.test3.1创建emotion_test项目…...
Python-第五天 Python函数
Python-第五天 Python函数一、函数介绍1. 什么事函数二、函数的定义1.函数的定义:2.案例三、函数的参数1.函数的传入参数2.案例升级四、函数的返回值1.什么是返回值2.返回值的语法3.None类型4.None类型的应用场景五、函数说明文档1.函数的说明文档2.在PyCharm中查看…...
【Python学习笔记】28.Python3 错误和异常
前言 作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。 Python3 错误和异常 Python 有两种错误很容易辨认:语法错误和异常。 Python assert…...
SQLServer 迁移到 MySQL 工具对比
我之所以会写这篇对比文章,是因为公司新产品研发真实经历过这个痛苦过程(传统基于 SQL Server开发的C/S 产品转为 MySQL云产品)。首次需要数据转换是测试环节,当时为了快速验证新研发云产品性能与结果准确性(算法类&am…...
分析finebi5.x仪表板组件获取数据过程(数据是数据集或者sql的)
首先仪表板的公共连接类似:http://localhost:37799/webroot/decision/link/Bo6B 当我们访问这个连接时,会来到FineLinkAction的getShareReport方法。 public String getShareReport(HttpServletRequest req, HttpServletResponse res, @FinePathVariable("linkId"…...
设计模式--适配器模式 Adapter Pattern
设计模式--适配器模式 Adapter Pattern适配器模式 Adapter Pattern1.1 基本介绍1.2 工作原理类适配器模式对象适配器模式接口适配器模式小结适配器模式 Adapter Pattern 1.1 基本介绍 (1)适配器模式将某个类的接口转换成为客户端期望的另一个接口表示&…...
PVE虚拟机篇-rest api
rest api官方介绍 Proxmox VE API rest api文档 rest api文档 rest api token 调用pve rest api ,有两种认证方式 Ticket Cookie Ticket Cookie的方式是最为推荐的,获取的方式为,通过post请求,发送用户名和密码到pve的server端获取tok…...
2022-2025学年面向中小学生的白名单全国性竞赛活动清单及官网地址链接
**资料来源:爬虫爬取。** 教育部办公厅 工业和信息化部办公厅关于公布 首批特色化示范性软件学院名单的通知 教育部办公厅 工业和信息化部办公厅关于公布首批特色化示范性软件学院名单的通知 - 中华人民共和国教育部政府门户网站 教育部办公厅关于2022-2025学年面向中小学生…...
Python 高级编程之生成器与协程进阶(五)
文章目录一、概述二、生成器1)生成器和迭代器的区别2)生成器创建方式1、通过生成器函数创建2、通过生成器表达式创建3)生成器表达式4)yield关键字5)生成器函数6)return 和 yield 异同7)yield的使…...
Django框架之视图和URL
视图和URL 站点管理页面做好了, 接下来就要做公共访问的页面了.对于Django的设计框架MVT. 用户在URL中请求的是视图.视图接收请求后进行处理.并将处理的结果返回给请求者.使用视图时需要进行两步操作 1.定义视图2.配置URLconf 1. 定义视图 视图就是一个Python函数,…...
Python 的Tkinter包系列之七:好例子补充2
Python 的Tkinter包系列之七:好例子补充2 英汉字典(使用文本文件记录英语单词和解释)、简单的通信录(使用SQLite数据库记录人员信息) 一、tkinter编写英汉字典 先看效果图: 词典文件是一个文本文件&…...
每日一练-等差数列
等差数列🍀题目描述🌿解题思路🌸Python源码📧Summary📆Date: 2023年2月10日 🎬Author: 小 y 同 学 📃Classify: 蓝桥杯每日一练 🔖Language: Python 🍀题目描述 题意 …...
使用动态参数构建CUDA图
文章目录使用动态参数构建CUDA图使用显式 API 调用构建 CUDA 图使用流捕获构建 CUDA 图组合方法执行结果总结使用动态参数构建CUDA图 自从在 CUDA 10 以来,CUDA Graphs 已被用于各种应用程序。 上图将一组 CUDA 内核和其他 CUDA 操作组合在一起,并使用指…...
在Fortran中调用Python教程
前言Python是机器学习领域不断增长的通用语言。拥有一些非常棒的工具包,比如scikit-learn,tensorflow和pytorch。气候模式通常是使用Fortran实现的。那么我们应该将基于Python的机器学习迁移到Fortran模型中吗?数据科学领域可能会利用HTTP AP…...
04-PS人像磨皮方法
1.高斯模糊磨皮 这种方法的原理就是建立一个将原图高斯模糊后图层, 然后用蒙版加画笔或者历史画笔工具将需要磨皮的地方涂抹出来, 通过图层透明度, 画笔流量等参数来控制磨皮程度 1.新建图层(命名为了高斯模糊磨皮), 混合模式设置为正常, 然后选择高斯模糊, 模糊数值设置到看…...
nginx反向代理+负载均衡上传webshell重难点+apache漏洞
nginx反向代理 nginx 负载均衡 负载均衡的策略 1、轮询:nginx默认就是轮询其权重都默认为1,服务器处理请求的顺序:ABABABABAB… upstream mysvr { server 192.168.137.131; server 192.168.137.136; }2、weight:跟据配置…...
为wordpress配置邮箱服务/semester at sea
一、课程介绍 HTTPS是互联网 Web 大势所趋,各大网站都已陆续部署了 HTTPS 。 全站HTTPS时代,加密用户与网站间的交互访问,在客户端浏览器和Web服务器之间建立安全加密通道,一般情况下,由于HTTP协议的安全性࿰…...
网站制作公司哪家专业/湖南seo公司
引言 虽然现在基本上都是使用一些封装好的框架中的样式标签,但是,最基本的东西还是应该牢牢掌握的。 文档流 文档流(normal flow,也被称为“普通流”),指的是就是元素排版布局过程中,元素会自…...
茂名企业建站程序/公关团队
php实现 句子逆序(需求才是最好的老师) 一、总结 一句话总结:需求才是最好的老师。 1、str_split()和explode()的区别? explode — 使用一个字符串分割另一个字符串 3 $arrexplode(" ",$str); str_split — 将字符串转换…...
企业进行网站建设的方式有( )/线下推广方式
另一个例子,表明使用正确的布局管理器,HTML标签中包裹的文本将自动包装到可用空间...在此处输入图片说明public class TestHTMLLabel {public static void main(String[] args) {new TestHTMLLabel();}public TestHTMLLabel() {EventQueue.invokeLater(n…...
品牌商城网站建设/搜索引擎哪个最好用
git的使用1.git的安装2.github中新建一个仓库3.本地操作3.1 新建并初始化文件夹3.2 Git Bash终端操作3.2.1 鼠标右键**Git Bash Here**打开Bash终端3.2.2 把github中新建的仓库clone到本地文件夹下3.2.3 切换分支3.2.4 把本地项目或文件拷贝到test文件夹下3.2.5 使用bash终端将…...
wordpress导航加title/模板建站公司
在开始编写ORM模块之前,我们需要先对db_helper进行重构,因为ORM最终生成的sql是需要转给db_helper来执行的,所以拥有一个功能完善、健壮的数据库操作类是非常必要的。 这是项目原db_helper.py代码 #!/usr/bin/env python # codingutf-8import…...