BCSP Java 开发之 Java 数据库编程 MySQL

BCSP Java 开发之 Java 数据库编程 MySQL
一、关系型数据库设计
1.1 数据库设计的重要性及定义
1.1.1 数据库设计的重要性
实际开发过程中,当存储量较大时,表的数量较多时,表的关系就会比较复杂。
此时就要有限考虑数据库的设计,并通 数据库三大范式 检验设计的合理性
1、失败的数据库设计造成的后果
- 程序运行阶段会出现操作异常
- 修改数据时会比较复杂
- 导致数据冗余
- 表与表之间的关系会变的比较复杂
- 影响程序性能,甚至造成程序崩溃
2、优秀的数据库设计带来的好处
- 降低应用程序开发的难度
- 具有高效的查询效率
- 具有良好的扩展性
1.1.2 数据库设计的定义
- 根据用户的需求,在数据库管理系统上,设计数据库的结构和建立数据的过程
- 建立数据库及其应用系统的技术,是信息系统开发和建设中的核心技术
- 数据库设计主要包含 :需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库的实施和数据库的运行和维护。
1.1.3 数据库设计:需求分析
- 软件生存周期中的一个重要环节
- 分析系统在功能上需要“实现什么”,而不是考虑如何去“实现”
- 将客户提出的要求进行分析以及整理
- 对功能性需求的补充,软件需求分析的内容中还应该包括一些非功能需求
- 设计限制条件,通常是对一些设计或实现方案的约束说明
1.1.4 数据库设计:概念模型 E-R 图
数据库需求分析阶段,了解系统需要实现的业务功能。
此时需要进一步的进入概要设计阶段,为了更加形象直观的体现数据库设计意图
数据库设计也有类似的图形化展示工具 E-R图 实体-练习图
通过一些具有特定含义的图形符号,提供图形化展示实体、属性和联系的方法
1、实体
- E-R 图当中,使用矩形表示实体
- 实体相当于数据表
2、属性
- E-R 图中,椭圆形表示实体的属性
- 属性与实体之间使用实线相连
- 表示此属性归属于哪个实体
- 属性就相当于数据表中的字段
3、联系
- 联系指在需求分析阶段标识的实体之间的关系,使用菱形表示
- 表示两个实体中属性的关系
- 类属于表中的主外键关系
示例

4、实体间的映射关系
-
绘制 E-R 图时,需要表现出实体之间的映射关系
-
即一个实体关联其他实体的个数
-
映射关系也成为了映射基数
-
三种映射关系
- 一对一联系:A 中的一个实体最多与 B 中的一个实体关联
- 一对多联系:A 中的一个实体可以与 B 中的任意数量实体关联,B 中的一个实体最多与 A 中的一个实体关联
- 多对多联系:A 中的一个实体可以与 B 中的任意数量实体关联,反之亦然
-
在绘制 E-R 图时,通过在连接线上分别添加数字表示映射关系 (一用1表示,多用 N 表示)
1.1.5 物理模型:数据库模型图
-
绘制完 E-R 图后,应当对数据局库进行详细的设计,数据库的详细设计,采用数据库模型图来实现
-
将 E-R 图转为数据库党总的多张表,并标识各表的主外键关系
-
通过图形化的方式,显示数据库存储的信息,信息的数据类型,以及各表之间的关系
-
Navicat 在设计好数据库后,可以一键生成数据库模型图
1.2 数据库规范设计
在设计数据库的过程中,如果开发者缺乏在设计阶段对数据库评价的手段,导致数据库设计的不合理
则会导致系统性能低下甚至不稳定
1.2.1 常见数据库设计问题
数据库设计问题大部分是数据冗余引起的
下方是一张存在大量数据冗余的数据表

这种数据冗余的数据表,对于查询来说很方便,只需要一次简单的查询即可,但是当对于数据库的更新操作 (增、删、改) 时,就会导致数据的更新异常
- 插入异常
- 当在表中增加一条数据时,假设医生想要录入 “凝血五项”,但只录入了一个 “凝血”,这明显是一个不规范的检查名称
- 当出现这样的情况时,就会导致数据库中记录的内容越来越不一致
- 不利于系统维护和管理
- 删除异常
- 如果要删除表中的 “尿常规” 检查,因为表中只存在一条 “尿常规” 检查记录,则当这条记录被删除时,数据库当中就再也找不到这条检查记录了
- 也就是说,数据库层面医院则不能再做这项检查
二、Navicat 安装及 MySQL 的安装与卸载
2.1 MySQL 压缩包安装教程
2.1.1 下载链接
官方 https://downloads.mysql.com/archives/community/
度盘 https://pan.baidu.com/s/1fuGdLIDXx2-2b5mEdqEh3g?pwd=xzsr
2.1.2 安装 MySQL
注意选择版本号为5.7.40
下载完后我们会得到一个以 MySQL 开头命名的压缩包,我们需要把这个压缩包解压到本地
这里可以把 MySQL 文件名后面的-winx64删除掉(度盘下载的压缩包我已经删除过了)
推荐将文件解压到 C 盘的 Program Files 文件下,即解压路径为C:\\Program Files\\mysql-5.7.40
2.1.3 添加配置文件
在C:\\Program Files\\mysql-5.7.40文件夹内新建一个文本文档,【强制】命名为:my.ini
注意开启显示文件拓展名设置

如果在度盘下载的压缩包,我在压缩包中已经写入过
my.ini文件,只需要注意自己的安装路径是否和配置文件内路径一致即可
使用记事本方法打开my.ini文件,将下面的配置文件粘贴进去
[mysqld]
#设置3306端口
port = 3306
# 设置mysql的安装目录
basedir=C:\\Program Files\\mysql-5.7.40
# 设置mysql数据库的数据的存放目录
datadir=C:\\Program Files\\mysql-5.7.40\\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
#跳过密码
skip-grant-tables
basedir:就是mysql的安装路径
datadir:只需要把
\\data前面的路径替换即可文本里的代码前面是没有数字的
2.1.4 配置环境变量
- 右键此电脑
- 属性

- 高级系统设置

- 环境变量
- 下方系统变量,找到
Path双击进入 - 新建系统变量,变量值为 mysql 安装
bin目录(实际路径以自己安装时设置为准) 
C:\\Program Files\\mysql-5.7.40\\bin

- 配置好后,保存退出
- 按下
Win + R然后通过管理员身份打开cmd - 输入
mysql --version查看环境是否配置成功

2.1.5 安装 MySQL 服务
- 按下键盘
Win + R打开运行输入cmd以管理员身份运行 - cd 到 mysql 文件的 bin 目录中
cd /d C:\\Program Files\\mysql-5.7.40\\bin
- 输入
mysqld -install命令安装 MySQL 服务 - 继续输入
mysqld --initialize-insecure初始化 data 目录 - 输入
net start mysql启动 MySQL 服务 - 成功启动后,输入
mysql -uroot登录 MySQL - 成功登录之后,输入下面代码
update mysql.user set authentication_string=password('root') where user='root' and Host = 'localhost';

- 这里的
root就是登录密码,账户名也是root或者你可以把密码改成自己喜欢的 - 再输入
flush privileges;刷新一下权限 - 最后输入
exit退出 MySQL 即可
2.1.6 删除配置文件代码
退出后回到my.ini配置文件中,用#注释掉或者直接删除掉最后一行代码skip-grant-tables然后保存退出
到这里就已经成功下载并配置好了 MySQL
2.1.7 验证 MySQL 配置
-
命令行先输入
net stop mysql关闭 MySQL 服务 -
在输入
net start mysql开启 MySQL 服务 -
这里报错的请自己到服务中手动打开 MySQL 服务后重新尝试
-
登录数据库
mysql -uroot -proot
mysql -u账户名 -p密码
注意密码前后不能有空格

最后可以输入一个查询版本信息的SQl语句玩一下:
select version(),user();代码后面有分号
2.2 MySQL 安装器安装教程
2.2.1 下载链接
官方 https://downloads.mysql.com/archives/installer/
度盘 https://pan.baidu.com/s/1fuGdLIDXx2-2b5mEdqEh3g?pwd=xzsr
2.2.2 安装 MySQL
注意选择版本号为5.7.40
下载完后我们会得到一个以 MySQL 开头命名的msi安装器,直接双击运行安装
- 提示是否更新,点击
NO即可 
- 勾选下方
Custom自定义安装 
- 左边找到
MySQL Server 5.7.40 - X64点击箭头添加到右边 
- 点击
Execute执行安装即可 
- 这个界面保持默认状态

- 设置
MySQL登录密码(默认设置为root) 
- 这里的
MySQL57就是服务器名称,点击Next下一步 
- 安装完毕

2.2.3 配置环境变量
- 右键此电脑
- 属性

- 高级系统设置

- 环境变量
- 下方系统变量,找到
Path双击进入 - 新建系统变量,变量值为 mysql 安装
bin目录(实际路径以自己安装时设置为准) 
C:\\Program Files\\MySQL\\MySQL Server 5.7\\bin
- 配置好后,保存退出
- 按下
Win + R然后通过管理员身份打开cmd - 输入
mysql --version查看环境是否配置成功

2.2.4 验证 MySQL 配置
- 再次通过按下
Win + R打开cmd窗口 - 输入账号密码
mysql -uroot -proot(-u后的root为管理员账号,-p后的root为之前设置的MySQL登录密码,没有空格直接跟密码) 
最后可以输入一个查询版本信息的SQl语句玩一下:
select version(),user();代码后面有分号
2.3 MySQL 卸载教程
2.3.1 压缩包卸载
压缩包安装方式安装的MySQL,卸载就直接删除掉解压后的MySQL文件夹即可,然后删除配置的 MySQL 环境变量
2.3.2 安装器卸载
- 按下
Win + R打开cmd窗口输入services.msc打开服务 
- 找到MySQL停止服务

- 打开控制面板


- 这里的两个软件都要卸载掉

到这里只是卸载了MySQL软件,MySQL还有许多文件并没有删掉,如果不删除干净,会影响后续安装导致安装失败。
- 删除MySQL在电脑硬盘上物理位置上的所有文件
C:\\Program Files (x86)\\MySQL内所有文件
C:\\ProgramData\\MySQL内所有文件,该文件是默认隐藏的,设置显示后即可见
C:\\Documents and Settings\\All Users\\Application Data\\MySQL内所有文件
到这里也只是删掉了MySQL所有残余文件,还需要删除MySQL的注册表信息
- 按下
Win + R打开cmd窗口输入regedit打开注册表 
- 删除以下三项内所有信息(可直接粘贴至地址栏)

HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/Eventlog/Application/MySQLHKEY_LOCAL_MACHINE/SYSTEM/ControlSet002/Services/Eventlog/Application/MySQLHKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Application/MySQL- 到此MySQL算是彻底卸载完毕
2.4 MySQL管理工具 Navicate / SqlYog 安装
2.4.1 下载链接
Navicate官网 https://www.navicat.com/en/products
SqlYog官网 https://sqlyog.en.softonic.com/
度盘 https://pan.baidu.com/s/1fuGdLIDXx2-2b5mEdqEh3g?pwd=xzsr

Navicat Premium 是一款功能强大的、可支持多连接的数据库管理工具
Navicate / SqlYog 涉及版权无法分享,加封面联系方式获取软件
2.4.2 使用 Navicat 连接 MySQL


2.4.3 使用 Navicat 创建数据库
通过操作向导创建数据库


- 字符集要选择
utf8点击 SQL 预览可以查看建库语句

通过SQL语句创建数据库


2.4.4 SqlYog 使用
SqlYog 与 Navicate 操作同理
三、MySQL 入门
3.1 MySQL 简介

MySQL 是一款流行的开源数据库,也是一个关系型数据库管理系统
在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一
3.1.1 发展历史
-
由瑞典 MySQL AB 公司开发
-
2008年, MySQL AB公司被SUN公司收购
-
2009年,SUN公司被Oracle公司收购
3.1.2 优势
-
运行速度快
-
使用成本低
-
容易使用
-
可移植性强
-
适用用户广
3.1.3 MySQL 安装
官网 https://downloads.mysql.com/archives/community/
安装教程 https://blog.csdn.net/qq_62283694/article/details/128853617
推荐使用 MySQL5.7
3.2 命令行连接 MySQL
首先检查是否启动服务
电脑按下Win + R 输入 cmd打开 DOS 窗口
2.2.1 启动服务命令
net start mysql
2.2.2 停止服务命令
net stop mysql
2.2.3 登录数据库命令
mysql –h服务器主机地址 –u用户名 –p密码
–h服务器主机地址本机登录可以省略

3.3 Navicat 数据库管理工具
3.3.1 Navicat Premium
Navicat Premium是一款功能强大的、可支持多连接的数据库管理工具

允许在单一程序中同时连接多达7种数据库
-
MySQL
-
MariaDB
-
MongoDB
-
SQL Server
-
SQLite
-
Oracle
-
PostgreSQL
官网 https://www.navicat.com/en/products
推荐使用:Navicat Premium 16
四、MySQL 初体验
4.1 SQL语言
4.1.1 SQL 语言概念
- SQL 用于对数据库的操作和查询
- SQL 的范围包括数据插入、查询、更新和删除,数据库模式创建和修改,以及数据访问控制
4.1.2 SQL 语言由四个部分组成
| SQL语言 | 作用 |
|---|---|
| DDL(数据定义语言) | 用于创建或删除数据库对象 |
| DML(数据操作语言) | 用于插入,修改和删除表中的数据 |
| DQL(数据查询语言) | 用于数据查询,指 SELECT 语句 |
| DCL(数据控制语言) | 用于控制数据库组件的存取许可、存取权限等 |
4.2 检查 MySQL 服务
4.2.1 检查 MySql 服务是否被启动
执行 MySql 的任何操作,都需要保证 MySql的服务处于启动状态
-
MySql 服务启动步骤
1、使用 Win 键 + R键调出"运行"对话框
2、输入 services .msc 打开 “服务” 窗口
3、找到 MySql 服务,右键,点击启动
- 使用命令行连接 MySql
1、在命令行窗口中,可使用以下语法格式连接数据库
mysql -h 服务器主机地址 -u 用户名 -p 密码
2、如果连接本机的 mysql,可以不输入服务器主机地址,如下
mysql -u 用户名 -p
3、然后再次输入密码,即可连接
4、使用命令 \\p 即可断开连接 mysql
5、除了使用 命令行窗口链接 MySql,也可以数据库管理工具来连接
登陆数据库后,可以通过输入命令操作 MySql
SQL 语句不区分大小写
- 查看 MySql 版本信息及当前用户 语法
SELECT VERSION(),USER();
运行效果

4.3 DDL 语言
4.3.1 操作数据库
- 创建数据库 语法
CREATE DATABASE 数据库名
- 查询现有的所有数据库 语法
SHOW DATABASES;
- 选择数据库 语法
在操作数据之前,需要先选定表所在的数据库,选择对某个数据库的表进行操作。
USE 数据库名
- 删除数据库 语法
DROP DATABASE 数据库名;
4.3.2 数据类型
在创建表之前,需要确定数据表的字段及每个字段的数据类型
MySQL 当中常用的的有数值类型、字符串类型和日期类型
1、数值类型
- MySQL 中常用的数值类型
| 数据类型 | 字节数 | 取值范围 |
|---|---|---|
| TINYINT[(M)] | 1 字节 | 有符号值:-27~-27 无符号值:0~28-1 |
| SMALLINT[(M)] | 2 字节 | 有符号值:-215~215-1 无符号值:0~216-1 |
| MEDIUMINT[(M)] | 3 字节 | 有符号值:-223~223-1 无符号值:0~224-1 |
| INT[(M)] | 4 字节 | 有符号值:-231~231-1 无符号值:0~2432-1 |
| FLOAT[(M,D)] | 4 字节 | 有符号值:-3.402823466E+38~-1.175494351E-38 无符号值:1.175494351E-3.402823466E+38 |
| DOUBLE[(M,D)] | 8 字节 | 有符号值:-1.7976931348623157E+308~-2.2250738585072014E-308 无符号值:2.225073858072014E-308~1.7976931348623157E+308 |
| DECIMAL[(M[,D])] | M+2字节 | M:最大精度位数即总位数,M 的取值范围是1~16,默认值为 10 D:最小位精度位数,D 的取值范围为 0~30 该类型可能的取值范围与 DOUBLE 相同,但有效取值范围有 M、D决定 例如,类型为 DECIMAL(5,2) ,能够存储具有五位数字和两位小数的任何值的字段 取值范围是 -999.99~999.99 |
-
M 代表需要显示的数字的位数
-
若数据位数大于数据本身的显示宽度,只要不超过该类型取值范围,则以是实际位数显示
-
TINYINT、SMALLINT、MEDIUMINT、INT 都为整数类型
-
FLOAT、DOUBLE 为浮点数类型
-
DECIMAL 为定数类型
-
当对精度要求较高时,一般使用 DECIMAL 类型
-
表中的值都包含有符号值和无符号值,其中,有符号数可以为负数
2、字符串类型
- MySQL 常用的字符串类型
| 数据类型 | 字节数 | 说明 |
|---|---|---|
| CHAR[(M)] | M 字节 | 固定长度字符串 M 为 0~255 的整数 |
| VARCHAR[(M)] | 可变长度 | 可变长度字符串 M 为 0~65535 的整数 |
| TINYTEXT | 0~255 | 微型文本 |
| TEXT | 0~65535 | 文本 |
- VARCHAT 类型长度是可变的,当数据超过用户固定的范围,将会自动增长,为节约空间
- TINYTEXT 和 TEXT 类型通常用来存储文章内容等纯文本信息
3、日期类型
- MySQL 中常用的日期类型
| 数据类型 | 格式 | 取值范围 |
|---|---|---|
| DATE | YYYY-MM-DD | 1000-01-04~9999-12-31 |
| DATETIME | YYYY-MM-DD hh:mm:ss | 1000-01-01 00:00:00~9999-12-31 23:59:59 |
| TIME | hh:mm:ss | -838:59:59~838:59:59 |
| TIMESTAMP | YYYYMMDDHHMMSS | 1970 年某时刻~2038 年某时刻,精度为 1 秒 |
| YEAR | YYYY 格式的年份 | 1901~2155 |
- 在 MySQL 5.7版本中,如果需要设置某字段默认值为系统当前时间,可指定字段类型为 TIMESTAMP ,当字段未插入数据时,默认为当前时间
4.3.2 操作数据表
在选择数据库之后,可以使用 SQL 语句创建数据表
1、创建数据表 语法
CREATE TABLE [IF NOT EXISTS] 表名(字段1 数据类型 [字段属性 | 约束] [索引] [字段备注],字段2 数据类型 [字段属性 | 约束] [索引] [字段备注],......字段n 数据类型 [字段属性 | 约束] [索引] [字段备注]
)[表类型] [表字符集] [表备注];
- 表的字段也称之为列
- 在创建数据表时,字段之间使用 , 分隔,最后一个字段不需要使用逗号
- MySql 的注释方式有单行和多行两种
- 单行注释 : #…
- 多行注释 : /* … */
2、字段的约束和属性
| 字段约束和属性 | 关键字 | 说明 |
|---|---|---|
| 主键约束 | PRIMARY KEY(PK) | 设置该字段为表的主键,同时保证字段的唯一性和非空 |
| 外键约束 | FOREIGN KEY(FK) | 用于在两表之间建立关系,需要指定引用主表的哪一字段,作为外键的字段要求在主表中为主键 |
| 自动增长 | AUTO_INCREMENT | (1)使用该列为自增字段,默认每条自增1 (2)通常用于设置主键,且为整数类型 (3)可设置1初始值和步长 |
| 非空约束 | NOT NULL | 保证字段不能为空 |
| 默认约束 | DEFAULT | 保证字段总会有值,即没有插入值,也会有默认值 |
| 唯一约束 | UNIQUE KEY(UK) | 设置字段的值是唯一的。不可重复 |
3、查看数据表结构 语法
describe 数据表名
4、 删除表
删除当前数据库中的数据表
删除表 语法
DROP TABLE [IF EXISTS] 表名;
4.4 修改数据表结构
4.4.1 修改数据表的表名
- 修改数据表的表名 语法
ALTER TABLE 旧表名 RENAME [TO] 新表名;
- [TO] 为可选,使用与否不影响效果
- 此语句只修改表的名称,不会修改表的结构
4.4.2 修改数据表的字段
- 修改表中的字段包含字段名和数据类型
- 修改数据表字段 语法
ALTER TABLE 表名 CHANGE 原字段名 新字段名 数据类型 [属性];
- 若不需要修改数据类型,则与原类型保持一致,不可为空
- 若修改时未添加属性,则修改后的字段无任何属性约束
4.4.3 给数据表添加字段
- 向已有的数据表添加字段
- 给数据表添加字段 语法
ALTER TABLE 表名 ADD 字段名 数据类型 [属性];
4.4.4 删除数据表的字段
- 删除数据表当中的某个已有字段
- 删除数据表的字段 语法
ALTER TABLE 表名 DROP 字段名
4.4.5 添加主外键约束
- 添加主键约束 语法
ALTER TABLE 表名 ADD CONSTRAINT 主键名 PRIMARY KEY 表名(主键字段)
- 添加外键约束 语法
ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (外键字段) REFERENCES 关联表名(关联字段)
4.5 MySQL 存储引擎
4.5.1 MySQL 存储引擎概述
- 存储引擎负责MySQL中的数据的存储和提取,是与文件打交道的子系统,它是根据MySQL提供的文件访问层抽象接口定制的一种文件访问机制,这种机制就叫作存储引擎
- MySQL中的数据用各种不同的技术存储在文件(或者内存)中。
- 存储引擎制定了表的存储类型,即如何存储和索引数据、是否至此事务等
- 存储引擎也决定了表在计算机中的存储方式
4.5.2 常用的数据库引擎
- 不同的业务场景对存储引擎的需求不同,一般根据他们的功能选择合适的存储引擎
- InnoDB 和 MyISAM 存储引擎功能
| 功能 | InnoDB | MyISAM |
|---|---|---|
| 事务处理 | 支持 | 不支持 |
| 外键约束 | 支持 | 不支持 |
| 表空间大小 | 较大 | 较小 |
| 数据行锁定 | 支持 | 不支持 |
- InnoDB 存储引擎
- 事务型数据库首选引擎(事务后面会讲到)
- 支持具有提交、回滚和崩溃恢复能力的事务控制
- 在需要大量执行插入、更新操作,或者需要使用事务保证数据完整性的场景下,选择 InnoDB
- MyISAM 存储引擎
- 该存储引擎不支持事务,也不支持外键约束
- 访问速度比较快
- 当不需要事务处理,且以访问为主的应,适合使用该引擎
五、SQL 高级(DML)
5.1 DML 语言
DML 语句:执行 增、删、改、语句
5.1.1 插入数据语句
使用 INSERT 语句向数据表中插入数据
- 插入单行数据 语法
INSERT INTO 表名 [(字段名列表)] VALUES (值列表);
- 字段名列表时可选项,若省略,则依次插入所有字段
- 值列表必须和字段名列表的数量相同,且数据类型一致
- 多个字段名和多个值之间使用逗号隔开
- 插入多行数据 语法
INSERT INTO 表名 [(字段名列表)] VALUES(值列表1),(值列表2),...,(值列表n);
- 将查询结果插入新列表 语法1
INSERT INTO 表名(字段1,字段2,...) SELECT 字段1,字段2,... FROM 原表;
- 将查询结果插入新列表 语法2
SELECT 字段1,字段2,... INTO 新表 FROM 原表;
- 将查询的数据插入到新创建的表中 语法
CREATE TABLE 新表(SELECT 字段1,字段2,... FROM 原表)
5.1.2 更新数据语句
使用 UPDATE 语句更新数据表中的数据
- 更新数据语句 语法
UPDATE 表名 SET 字段1=值1,字段2=值2,...,字段n=值n [WHERE 条件]
5.1.3 删除数据语句
从数据表中删除数据可以使用 DELETE 语句 或 TRUNCATE 语句
- 使用 DELETE 语句删除数据 语法
DELETE FROM 表名 [WHERE 条件]
- 使用 TRUNCATE 语句清除整个表 语法
TRUNCATE TABLE 表名
- 该语句可清空表内的所有数据
六、SQL 高级(DQL)
6.1 基础查询
6.1.1 基础查询 语句
- 数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果给客户端。
- 查询返回的结果集是一张虚拟表。
- 查询关键字:SELECT
SELECT * FROM 表
SELECT 列名1,列名2 FROM 表
- * 表示所有列,也可以使用列名表示,用 , 分隔
- SELECT 要查询的列名称
- FROM 表名称
6.1.2 AS 别名
- 在查询中,所显示的虚拟表中的列名一般为英文,为了方便区分,我们可以使用列的别名
- 使用关键字 AS 给列命名
- 语法格式如下
SELECT 列名1 AS '别名' FROM 表
6.2 增强查询
6.2.1 增强查询语句
在基础查询的基础上,对查询添加一些属性,让查询数据更为精准
回顾数据查询语句 (SELECT 语句) 语法如下
SELECT *或<字段名列表> FROM <表名或视图> [WHERE <查询条件>] [GROUP BY <分组的字段名>] [HAVING <条件>] [ORDER BY <排序的字段名>] [ASC 或 DESC] [LIMIT [位置偏移量,]行数];
- WHERE 子句为可选项,如果选择该选项,则将限定查询条件,查询结果必须满足此查询条件
- GROUP BY 子句表明查询出来的数据按指定字段进行分组
- HAVING 子句用于筛选组
- ORDER BY 子句指定按什么顺序显示查询出来的数据,需要指定排序字段。默认按照升序排列,也可以通过代码指定 升序(ASC)或 降序(DESC)
- LIMIT 来指定查询结果返回条数
- 位置偏移量表示结果从结果集的第几条数据开始选取(记录的偏移位置从0开始开始计算,表示第一条记录,第二条记录的偏移位置是1,以此类推)
- 行数指以偏移位置为起点,选取记录的条数
6.3 运算符
MySQL 的运算符主要有:算术运算符、比较运算符、逻辑运算符、位运算符
6.3.1 算术运算符
- 常用的算术运算符
| 运算符 | 作用 |
|---|---|
| + | 加法 |
| - | 减法 |
| * | 乘法 |
| / 或 DIV | 除法 |
| % 或 MOD | 取余 |
在除法运算和模(取余)运算中,如果除数为0,将是非法除数,返回结果为NULL
6.3.2 比较运算符
- SELECT 语句中的条件语句经常要使用比较运算符。通过这些比较运算符,可以判断表中的哪些记录是符合条件的。比较结果为真,则返回 1,为假则返回 0,比较结果不确定则返回 NULL。
- 常用的比较运算符
| 符号 | 描述 | 备注 |
|---|---|---|
| = | 等于 | |
| <>, != | 不等于 | |
| > | 大于 | |
| < | 小于 | |
| <= | 小于等于 | |
| >= | 大于等于 | |
| BETWEEN | 在两值之间 | >=min&&<=max |
| NOT BETWEEN | 不在两值之间 | |
| IN | 在集合中 | |
| NOT IN | 不在集合中 | |
| <=> | 严格比较两个NULL值是否相等 | 两个操作码均为NULL时,其所得值为1;而当一个操作码为NULL时,其所得值为0 |
| LIKE | 模糊匹配 | |
| REGEXP 或 RLIKE | 正则式匹配 | |
| IS NULL | 为空 | |
| IS NOT NULL | 不为空 |
6.3.3 逻辑运算符
- 逻辑运算符用来判断表达式的真假。如果表达式是真,结果返回 1。如果表达式是假,结果返回 0。
- 常用的逻辑运算符
| 运算符号 | 作用 | 示例 |
|---|---|---|
| NOT 或 ! | 逻辑非 | |
| AND | 逻辑与 | |
| OR | 逻辑或 | 当A、B中只要有一个或者两个都为1时,结果为1,否则为0 |
| XOR | 逻辑异或 | 当A、B两个不同时结果为1,否则为0 |
6.3.4 位运算符
- 位运算符是在二进制数上进行计算的运算符。位运算会先将操作数变成二进制数,进行位运算。然后再将计算结果从二进制数变回十进制数
- 常用的位运算符
| 运算符号 | 作用 | 说明 |
|---|---|---|
| & | 按位与 | 参与&运算的两个二进制位都为 1 时,结果就为 1,否则为 0 |
| | | 按位或 | 参与` |
| ^ | 按位异或 | 参与^运算的两个二进制位不同时,结果为 1,相同时,结果为 0 |
| ~ | 取反 | 按位取反(~)运算符将给定的值的二进制数逐位进行取反操作,即将1变为0,将0变为1 |
| << | 左移 | 位左移是按指定值的补码形式进行左移,左移指定位数之后,左边高位的数值被移出并丢弃,右边低位空出的位置用 0 补齐 |
| >> | 右移 | 位右移是按指定值的补码形式进行右移,右移指定位数之后,右边低位的数值被移出并丢弃,左边高位空出的位置用 0 补齐 |
6.3.5 运算符优先级
- 运算符的使用存在一定的优先级别
- 运算符优先级
| 优先级顺序 | 运算符 |
|---|---|
| 1 | := |
| 2 | ||,OR,XOR |
| 3 | &&,AND |
| 4 | NOT |
| 5 | BETWEEN,CASE,WHEN,THEN,ELSE |
| 6 | =,<=>,>,>=,<,<=,<>,!=,IS,LIKE,REGEXP,IN |
| 7 | | |
| 8 | & |
| 9 | <<,>> |
| 10 | -,+ |
| 11 | *,/,DIV,%,MOD |
| 12 | ^ |
| 13 | -(一元减号),~(一元比特反转) |
| 14 | ! |
- 最低优先级为: :=
- 最高优先级为: !、BINARY、 COLLATE。
6.4 条件查询
使用 WHERE 关键字来对查询的结果进行筛选
6.4.1 单条件查询
- 使用 WHERE 关键字,根据查询条件,来筛选数据
- 单条件查询 语法
WHERE 列名 FROM 表名 WHERE 列名 运算符 值
6.4.2 多条件查询
- 多条件可以对查询更加精确
- 多条件查询关键字
- AND:必须满足两边的条件才会查询出来
- OR:满足其中一个条件,并且不满足另一个条件时,前后要变化两次,才会被查询出来
- WHERE 子句中,使用AND、OR 可以把两个或多个过滤条件结合起来
- 多条件查询语句 语法
WHERE 列名 FROM 表名 WHERE 列名 运算符 值 AND 列名 运算符 值
WHERE 列名 FROM 表名 WHERE 列名 运算符 值 OR 列名 运算符 值
6.4.3 范围查询
- 使用关键字 BETWEEN AND
- BETWEEN AND:需要两个参数,起始值和最终值。如果查询的记录在这个范围内就被返回
- 语法格式如下
WHERE 列名 NOT BETWEEN 起始值 AND 最终值
- NOT:可选参数,表示取反
- 查询指定范围内所有值,包括起始值和最终值。
6.4.4 空值查询
- 使用关键字 IS NULL
- IS NULL关键字判断该列的值是否为空值,空值不是空字符串
- 语法格式如下
WHERE 列名 IS NOT NULL
- NOT:可选参数,表示取反
6.5 模糊查询
模糊查询一般使用关键字 LIKE 主要用于匹配列中的数据
6.5.1 通配符
- 一般在使用 LIKE 进行模糊查询时,与通配符一起结合使用
- 常用的通配符
| 通配符 | 描述 |
|---|---|
| % | 替代0或多个字符 |
| _ | 替代一个字符,字符长度不能为0 |
| […] | 字符列中任何单一字符 |
| [^…] | 不在字符列中任何单一字符 |
6.5.2 LIKE 模糊查询
- 模糊查询一般使用关键字 LIKE 主要用于匹配列中的数据
- 语法格式如下
where NOT LIKE 字符串
-
NOT:可选项,表示取反
-
字符串:用来匹配的字符串,可以是完整的字符串或者通配符
-
语法格式如下
WHERE 列1 LIKE '%123' #表示 列1的值结尾为123即可匹配
WHERE 列1 LIKE '123%' #表示 列1的值开头为123即可匹配
WHERE 列1 LIKE '%123%' #表示 列1的值包含为123即可匹配
WHERE 列1 LIKE '_123' #表示列1的值为 X123,X 表示任意字符
WHERE 列1 LIKE '[张李王]三' #将找出“张三”、“李三”、“王三”(而不是“张李王三”)
WHERE 列1 LIKE '[^张李王]三' #将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;
- 注意事项
- 匹配的字符串必须加单引号或者双引号。
- 默认情况下,LIKE关键字匹配字符串时候不区分大小写,可以在LIKE关键字后添加BINARY关键字来区分大小写。
- 如果查询内容中有通配符字符,就需要加转义字符 “\\”.
6.6 常用函数
基于已有数据进行数据的统计分析计算等需求
6.6.1 字符串函数
- 可以对字符串进行各种处理
- MySQL 中常用的字符串处理函数
| 函数名 | 函数说明 | 函数示例 |
|---|---|---|
| CONCAT(str1,str2,…,strn) | 将字符串 str1、str2、…、strn连接为一个完整的字符串 | SELECT CONCAT(‘L’,‘Q’,‘E’); 返回:LQE |
| LOWER(str) | 将字符穿 str 中所有字符变为小写 | SELECT LOWER(‘LqE’) 返回:lqe |
| UPPER(str) | 将字符串 str 中所有的字符变为大写 | SELECT UPPER(‘lQe’) 返回:LQE |
| SUBSTRING(str,num,len) | 返回字符串 str 的第 num个位置开始,长度为 len 的子字符串 | SELECT SUBSTRING(‘ABCDEFG’,3,4) 返回:CDEF |
| INSERT(str,pos,len,newstr) | 将字符串 str 从 pos 位置开始,将len 个字符长度的子串替换为字符串 newstr | SELECT INSERT(‘1234’,3,0,‘ABCDE’) 返回:12ABCDE34 |
6.6.2 日期函数
- 获取当前日期,对日期进行操作
- MySQL 中常用的日期函数
| 函数名 | 函数说明 | 示例 |
|---|---|---|
| CURDATE() | 获取当前日期 | SELECT CURDATE(); 返回:2023-03-11 |
| CURTIME() | 获取当前时间 | SELECT CURTIME(); 返回:01:54:30 |
| NOW() | 获取当前日期和时间 | SELECT NOW(); 返回:2023-03-11 01:55:12 |
| WEEK(date) | 返回参数 date 为一年中的第几周 | SELECT WEEK(NOW()); 返回: 10 |
| YEAR(date) | 返回参数 date 的年份 | SELECT YEAR(NOW()); 返回:2023 |
| HOUR(time) | 返回参数 time 的小时值 | SELECT HOUR(NOW()); 返回:1 |
| MINUTE(time) | 返回参数 time 的分钟值 | SELECT HOUR(NOW()); 返回:57 |
| DATEDIFF(date1,date2) | 返回参数 date1 和参数 date2 之间相隔的天数 | SELECT DATEDIFF(NOW(),‘2019-8-8’) 返回:1311 |
| ADDDATE(date,n) | 计算参数 date 在 n 天后的日期 | SELECT ADDDATE(NOW(),4); 返回:2023-3-15 01:58:36 |
6.6.3 聚合函数
- 对已有数据进行汇总,常见的有求和、平均值、最大值、最小值等
- MySQL 中常用的聚合函数
| 函数名 | 函数说明 |
|---|---|
| COUNT() | 返回某字段的行数 |
| MAX() | 返回某字段的最大值 |
| MIN() | 返回某字段的最小值 |
| SUM() | 返回某字段的和 |
| AVG | 返回某字段的平均值 |
6.6.4 数学函数
- 可以进行数值运算
- MySQL 中常见的数学函数
| 函数名 | 函数说明 | 示例 |
|---|---|---|
| CELL(x) | 返回大于或等于数值 x 的最小整数,向上取整 | SELECT CELL(2.1) 返回:3 |
| FLOOR(x) | 返回小于或等于数值 x 的最大整数,向下取整 | SELECT FLOOR(2.9) 返回:2 |
| RAND() | 返回 0~1 的随机数 | SELECT RANG(); 返回:0.15013303621684485 |
6.7 分组查询
6.7.1 GROUP BY
- GROUP BY 语句根据一个或多个列对结果集进行分组,一般和聚合函数一起使用
- GROUP BY 语法格式 如下
SELECT COUNT(*) FROM 表名 GROUP BY 分组的字段
- 分组字段:按照表中的某列值进行分组
- 分组可以按单个字段也可以按多个字段
6.7.2 HAVING
-
HAVING 语句对分组查询的结果进行条件限定,用来限制分组后的显示,符合条件表达式的结果将被显示
-
HAVING 语法格式 如下
SELECT COUNT(*) FROM 表名 GROUP BY 分组的字段 HAVING 条件表达式
6.8 排序查询
6.8.1 单字段排序
- ORDER BY 关键字用于对结果集进行升序或降序排序
- ORDER BY 关键字默认按升序对记录进行排序
- 也可以使用关键字对记录进行升序或降序:升序
ASC降序DESC - 单字段排序 语法格式如下
SELECT * FROM 表名 ORDER BY 进行排序的列 ASC|DESC
- 进行排序的列:按照表中哪列的值进行排序
6.8.2 多字段排序
-
ORDER BY 后面可以跟多个字段进行排序
-
多字段排序 语法格式如下
SELECT * FROM 表名 order by A1 asc , A2 desc
- 指的是用 A1 列升序,A2 列降序
- 排序的时候 前者先用A1升序排列,若有并列,则并列部分按A2降序
6.9 分页查询
6.9.1 单参数分页查询
-
当查询的数据有很多条时,通过真分页的方式,每次取出所需数据。对于不同的数据,实现分页有不同的方式
-
分页查询使用关键字 LIMIT
-
LIMIT出现在查询语句的最后,可以使用一个参数或两个参数来限制取出的数据。其中第一个参数代表偏移量:offset(可选参数),第二个参数代表取出的数据条数:rows
-
LIMIT 单参数用法
- 当指定一个参数时,默认省略了偏移量,即偏移量为0,从第一行数据开始取,一共取rows条
- 单参数语法格式
/* 查询前5条数据 */ SELECT * FROM 表名 LIMIT 5;
6.9.2 双参数分页查询
-
LIMIT 双参数用法
- 当指定两个参数时,需要注意偏移量的取值是从0开始的,此时可以有两种写法
- 双参数语法格式
/* 查询第1-10条数据 */ SELECT * FROM 表名 LIMIT 0,10; /* 查询第11-20条数据 */ SELECT * FROM 表名 LIMIT 10 OFFSET 10; /* 查询第21-30条数据 */ SELECT * FROM 表名 LIMIT 20 OFFSET 10; /* 查询第N页的十条数据 */ SELECT * FROM 表名 LIMIT (N-1)*10,10;- 以上参数可以用 , 分隔,也可以使用关键字 OFFSET 分隔
6.10 子查询
6.10.1 基本的子查询
- 子查询指一个查询语句嵌套在另一个查询语句内部的查询,内部的查询是外部查询的条件
- 当内查询的结果为单个值时,可以使用 = 号来接收这个值
- 语法格式如下
SELECT * FROM 表1 WHERE 列1=(Where 列2 FROM 表2)
4.1.1 IN 子查询
- 使用子查询,如果结果返回的多个值,而 子查询跟随在 比较运算符之后,就会导致报错,因为比较运算符只能匹配一个值,如下
- 在病人表中查询做过 ”尿常规“ 检查项目的病人
SELECT patientName FROM patient WHERE checkItemID=(SELECT checkItemID FROM prescription WHERE checkItemName='尿常规');
-
如果子查询的结果为多个值,就会导致代码报错
-
解决方案就是使用 IN 关键字,将 = 替换成 IN,如下
SELECT patientName FROM patient WHERE checkItemID IN (SELECT checkItemID FROM prescription WHERE checkItemName='尿常规');
4.1.2 NOT IN 子查询
- 匹配结果集以外数据的情况
- 与 IN 关键字类似,只是将 IN 查询结果以外的数据返回
4.2.1 EXISTS/NOT EXISTS 子查询
-
EXISTS 是一个布尔运算符返回true或false。 EXISTS 经常使用的在一个子查询,以测试一个“存在”状态
-
EXISTS 在 WHERE 子句中作为子查询时使用,若子查询中有数据,则 EXISTS 子查询为 true,其外层查询语句会被执行,反之,不会执行
-
EXISTS 语法
SELECT .... FROM 表名 WHERE EXISTS(子查询)
- EXISTS 子查询允许添加 NOT 关键字实现相反的操作
6.11 多表连接查
在查询数据时,需要查询数据关联的另一个表的那一列,需要从多个表中选择数据项的情况,就是多表查询
6.11.1 内连接查询
- 内连接查询一般使用关键字 INNER JOIN 连接的数据表 ON 匹配条件
- INNER JOIN 后面跟的是要连接的表
- ON后面的括号内设置条件,如果括号内的条件匹配,那么则返回连接的数据库的那一行记录
- 内连接查询 语法格式如下
Select 表1.值2,表2.值2 From 表1 INNER JOIN 表2 ON 表1.值1=表2.值1
6.11.2 外连接查询
- 外连接查询主要分为左右外连接查询
- 他与内连接查询类似,不同的时,如果主表或者从表中没有匹配的值,则会以null显示
- 左外连接查询:在查询时,如果主表查询的数据在从表中没有对应的数据,则从表的数据则会以null显示
- 右外连接查询:在查询时,如果主表查询的数据在从表中没有对应的数据,则主表的数据则会以null显示
- 左外连接关键字:LEFT JOIN 连接的数据表 ON 匹配条件
- 右外连接关键字 RIGHT JOIN 连接的数据表 ON 匹配条件
- 外连接语法格式如下
Select 表1.值2,表2.值2 From 表1 LEFT JOIN 表2 ON 表1.值1=表2.值1
Select 表1.值2,表2.值2 From 表1 RIGHT JOIN 表2 ON 表1.值1=表2.值1
6.12 查询语句的优先级
6.12.1 查询语句的优先级顺序
- 在执行查询时,使用的各种关键字存在一定的先后顺序
- 如果使用不当,则会报错
| 优先级顺序 | 关键字 |
|---|---|
| 1 | LIMIT |
| 2 | ORDER BY |
| 3 | HAVING |
| 4 | GROUP BY |
| 5 | WHERE |
| 6 | INNER JOIN |
| 7 | ON |
- ON 的优先级最高
- LIMIT 的优先级最低
七、存储过程
7.1 认识存储过程
7.1.1 存储过程简介
-
存储过程 是一组为了完成特定功能的 SQL 语句集合
-
经编译后保存在数据库中
-
通过指定存储过程的名字并给出参数的值
-
可带参数,也可返回结果
-
可包含数据操纵语句、变量、逻辑控制语句等
7.1.2 MySQL 存储过程的优缺点
存储过程的优点
- 减少网络流量 存储过程一般存储在数据库服务器上,应用程序不需要发送多个 SQL 语句,而只需要发送存储过程的名称和参数
- 提升执行速度 在 MySQL 中,对于存储过程只在创建时进行编译,然后将编译好的存储过程放在缓存中。若多次重复调用存储过程,则使用缓存中的编译版本
- 减少数据库连接次数 执行多条 SQL 语句,应用程序需要多次连接数据库,使用存储过程,应用程序只需要连接一次数据库
- 安全性高 数据库管理员可以对访问数据库存储过程的应用授予权限,而不提供基础数据表的访问权限
- 高复用性 存储过程是封装的一个特定的功能块,对于任何应用程序都是可复用的透明的
存储过程的缺点
- 内存增加 如果使用许多存储过程,则使用这些存储过程的每个连接的内存使用量将显着增加
- 移植性差
- 开发和维护存储过程并不容易
- 调试存储过程很困难
7.2 使用存储过程
7.2.1 创建和调用存储过程
创建存储过程
- 使用 CREATE PROCEDURE 语句创建存储过程
- 创建存储过程 语法
CREATE PROCEDURE 过程名([过程参数[,...]])[特性] #可选项,用于设置存储过程的行为存储过程体
- 存储过程的常用特性
| 特性 | 说明 |
|---|---|
| LANGUAGE SQL | 存储过程语音,默认为 SQL |
| CONTAINS SQL NO SQL READS SQL DATA MODIFIES SQL DATA |
存储过程要做哪类工作 默认为CONTAINS SQL |
| SQL SECURITY{DEFINER | INVOKER} | 用来指定存储过程的执行权限 默认值为 DEFINER DEFINER 使用创建者的权限执行 INVOKER 使用执行者的权限执行 |
| COMMENT ‘string’ | 存储过程的注释信息 |
示例 编写存储过程,输出病人总人数
DROP PROCEDURE IF EXISTS proc_patient_countPatient;
DELIMITER // #声明分隔符
CREATE PROCEDURE proc_patient_countPatient()
BEGIN #过程体开始
SELECT COUNT(*) FROM patient;
END // #过程体结束
DELIMITER ; #恢复默认分隔符
1、删除存储过程
- 在创建存储过程之前,应先判断存储过程是否存在,如果存在,则删除
- 删除存储过程 语法
DROP PROCEDURE 过程名
2、声明语句分隔符
- MySQL 中,默认使用 ; 作为分隔符,使用 DELIMITER 关键字可以改变分隔符
- 创建过程前,首先声明分隔符
- 将分隔符设置为 $$ 或 // 语法如下
DELIMITER $$
DELIMITER //
- 如果没有声明分隔符,编译器就会把存储过程当成 SQL 语句处理,会出现报错
- 存储过程最后,要把分隔符还原 语法如下
DELIMITER ;
3、定义存储过程的参数
- MySQL 中,存储过程的参数包括 3 种类型
- IN 输入参数。该参数的值必须在调用存储过程时指定,在存储过程中可以使用该参数,但他不能被返回
- OUT 输出参数。该参数可以再存储过程中发生改变并可以返回
- INOUT 输入输出参数.该参数的值在调用存储过程时指定,在存储过程中可以被改变和返回。
- 定义参数 语法
[IN|OUT|INOUT] 参数名 类型
- 示例
DELIMITER // #声明分隔符
CREATE PROCEDURE proc_patient_countPatient2(IN patientNum INT)
#省略......
DELIMITER ; #恢复默认分隔符
- 调用 存储过程时,调用out类型的参数,需要有一个会话变量接收
DELIMITER // #声明分隔符
CREATE PROCEDURE proc_patient_countPatient3(OUT patientNum INT)
SELECT COUNT(*) INTO patientNum FROM patient;
DELIMITER ; #恢复默认分隔符
#调用
ALL proc_patient_countPatient3(@patientNum);
- INTO 就是将查询的值给参数 patientNum
4、过程体的标识
- 在定义存储过程的过程体时,需要标识开始和结束。
- 定义过程体 语法
BEGIN ...... END 分隔符
- END 后面必须使用 DELIMITER 语句中设置的分隔符为结束
调用存储过程
- MySQL 中使用 CALL 关键字调用存储过程
- 调用存储过程 语法
CALL 存储过程名 (参数列表);
创建和调用存储过程 示例
- 编写存储过程,输出病人总人数
#如果存储过程存在,则删除
DROP PROCEDURE IF EXISTS proc_patient_countPatient;
DELIMITER // #声明分隔符
CREATE PROCEDURE proc_patient_countPatient()
BEGIN #过程体开始SELECT COUNT(*) FROM patient;
END // #过程体结束
DELIMITER ; #恢复默认分隔符#调用
CALL roc_patient_countPatient();
7.2.2 存储过程中的变量
-
类似 Java 与其他编程语言,定义存储过程时可以使用变量
-
声明变量 语法
DECLARE 变量名[,变量名...] 数据类型 [DEFAULT 值];
- 示例 声明交易时间变量 trade_time,并设置默认值为 2020-07-10 代码如下
DECLARE trade_time DATE DEFAULT '2020-07-10';
-
所有局部变量的声明一定要放在存储过程体的开始,必须在BEGIN后,否则会提示语法错误
-
声明变量后,可以给变量赋值
-
变量赋值 语法
SET 变量名=表达式值[,变量名=表达式...];
- 示例 设置变量 total 的值为100
set total=100;
7.2.3 MySQL 用户自定义变量
- MySQL 中变量包括 用户自定义变量 和 系统变量两种
- MySQL 用户自定义变量又包括 局部变量 和 会话变量
- 局部变量
- 一般用于 SQL 的语句块中,如存储过程中的 BEGIN 和 END 语句块中
- 作用于仅限于定义该变量的语句块内,语句块结束,变量释放
- 会话变量
- 也成为用户变量
- 服务器为每个客户端连接维护的变量,与MySQL客户端是绑定的
- 可以暂存值,并传递给同一连接中其他SQL语句进行使用
- 当默认DEFINER = CURRENT_USERMySQL客户端连接退出时,用户变量就会被释放
- 用户变量创建时,一般以“@”开头,形式为“@变量名”
7.2.4 设置用户权限
- 存储过程中,可用关键字 DEFINER 赋值语句规定对存储过程访问的安全控制
- 使用 DEFINER 和 SQL SECURITY 特性控制存储过程的执行 语法
DELIMITER //
CREATE [DEFINER={user|CURRENT_USER}]
PROCEDURE 存储过程名
[SQL SECURITY {DEFINER|INVOKER|....}]
BEGIN
....
END //
DELIMITER ;
- DEFINER 指定创建者用户
- SQL SECURITY 用以指定 定义者 (DFINER) 或 调用者 (INVOKER)
7.2.5 查看存储过程
对创建后的存储过程进行查看
1、查看存储过程的状态
- 查看以创建的存储过程 语法
SHOW PROCEDURE STATUS
- 查看指定的数据库中创建的存储过程 语法
SHOW PROCEDURE STATUS WHERE DB='数据库名'
- 也可以通过 LIKE 关键字匹配存储过程名称 语法如下
SHOW PROCEDURE STATUS LIKE '%patient%';
2、查看存储过程的创建代码
- 查看存储过程的代码 语法
SHOW CREATE PROCEDURE 存储过程名
5.2.6 修改存储过程
- 对已创建的存储过程进行修改
- 只能修改存储过程定义的特性 语法如下
ALTER PROCEDURE 存储过程名 [特性......];
- ALTER 关键字只能修改存储过程的属性
- 如果要修改存储过程中过程体的内容,需要先删除该存储过程,然后进行重新创建
7.2.7 删除存储过程
- 删除已有的存储过程 语法
DROP PROCEDURE 存储过程名
7.3 存储过程的控制语句
MySQL 提供的控制语句包括条件语句、循环语句、迭代语句
7.3.1 条件语句
MySQL 提供了两种控制语句,分别是 IF-ELSEIF-ELSE 条件语句和 CASE 条件语句
1、IF-ELSEIF-ELSE 条件语句
- IF-ELSEIF-ELSE 语法
IF 条件 THEN 语句列表[ELSEIF 条件 THEN 语句列表][ELSE 语句列表]
END IF;
- 如果 IF 后的条件为真,则执行 THEN 后的语句列表
2、CASE 条件语句
- MySQL 中的CASE 条件语句有两种写法
- 第一种 语法
CASEWHEN 条件 THEN 语句列表[WHEN 条件 THEN 语句列表][ELSE 语句列表]
END CASE;
- 第二种 语法
CASE 列名WHEN 条件 THEN 语句列表[WHEN 条件 THEN 语句列表][ELSE 语句列表]
END CASE;
- 在 CASE 语句中,如果条件为真,则相应的 SQL 语句列表会被执行
- 如果没有匹配条件,则会在 ELSE 子句里的语句列表被执行
- CASE 语句的两种写法可以实现相同的功能
- 如果做等值判断,使用第二种写法更加简洁
- 因为 CASE 后面有列名,功能上会有一些限制
7.3.2 循环语句
MySQL 语句提供多种循环语句,包括 WHILE 循环语句、LOOP 循环语句 和 REPEAT 循环语句
1、WHILE 循环语句
- WHILE 循环是最普遍使用的循环语句
- WHILE 循环 语法
[lable:] WHILE 条件 DO语句列表END WHILE [lable]
- 首先判断条件是否成立,若成立,则执行循环体
- label 及标号,用于区分不同的循环体,可以被省略
2、LOOP 循环
- LOOP 循环 语法
[lable:] LOOP语句列表
END LOOP [lable];
- LOOP 循环结构不需要判断初始条件,直接执行循环体
- 直到遇到 LEAVE 语句才退出循环
- LEAVE 语法
LEAVE lable;
3、REPEAT 循环语句
- REPEAT 循环 语法
[lable:] REPEAT语句列表
UNTLL 条件
END REPEAT [label]
- REPEAT 循环不需要初始条件就可以直接进入循环体
- REPEAT 循环有退出条件
- 每次循环一次后,判断 UNTLL 后的条件是否成立,如果成立,则跳出循环
7.3.3 迭代语句
- ITERATE 关键字可以嵌入 LOOP、WHILE、REPEAT 程序块中
- 执行 ITERATE 语句时,跳出本次循环,继续下一次循环
- ITERATE 语法
ITERATE lable;
- label 参数表示循环的标志,ITERATE 语句必须跟在循环标志前面
八、事务、视图、索引、备份和恢复
8.1 事务
8.1.1 事务介绍
- 事务 (Transaction) 将一些列数据操作捆绑成为一个整体统一管理的机制
- 多个操作作为一个整体向系统提交,要么都执行、要么都不执行
- 不可分割的工作逻辑单元
8.1.2 为什么需要事务
- 事务包含了一组操作,这些操作可以是一条SQL语句、一组SQL语句或整个程序。
- 如果其中一个操作不成功,这些操作都不会执行,前面执行的操作也会回滚原状态,用来保证数据的一致性和完整性。
- 例如,就像银行转账,张三给李四转账,只有当张三的钱转走了,并且李四账户的钱收到了之后才会事务提交,否则事务会回滚到转账前的状态,保证数据的一致性,保证数据不会出错。
8.1.3 事务的四大特性
事务是最哦为单个逻辑工作单元执行的一系列操作,必须遵循四个特性
原子性、一致性、隔离性、持久性
- 原子性
- 事务是一个完整的操作
- 事务的各步操作是不可分的(原子的)
- 要么一起执行完毕,要么都不执行
- 一致性
- 事务完成前,数据必须处于一致状态
- 隔离性
- 一个事务在完成之前对其他事务是不可见的
- 它不可以任何方式依赖或影响其他事务
- 持久性
- 一旦事务提交,不论系统是否故障,事务处理结果都是永久的
- 事务成功完成之后对于数据库的改变是永久性的
8.1.4 在 MySQL 中使用事务
-
默认设置下,每个 SQL 语句就是一个事务,即执行 SQL 语句后自动提交
-
实现事务主要有两种方式
- 使用 BEGIN 或 START TRANSACTION 开启一个事务
- 执行 SET autocommit=0 禁止当前会话自动提交
两种实现事务的语法格式如下
1、执行事务的 SQL 语句语法格式
- 使用 BEGIN 或 START TRANSACTION 开启一个事务
- 提交事务 语法
#开启事务
BEGIN ; 或 START TRANSACTION; #一组作为事务运行的 SQL 语句#提交事务COMMIT;
-
BEGIN 或 START TRANSACTION 标志着事务的起止点,其后的 SQL 语句不会被提交生效
-
当运行到 COMMIT 语句后,标志着一个事务被提交成功
-
自事务开始至提交语句之间执行的所有数据更新将被永久的保存在数据库文件中,并释放连接时占用的资源
-
回滚(撤销)事务 语法
#开启事务
BEGIN;或 START TRANSACTION;#一组作为事务运行的 SQL 语句#回滚事务ROLLBACK;
- 事务可以被重新提交,也可能因为执行某些语句不成功或其他异常情况而终止
- 为保证事务的一致性,要是有 ROLLBACK 语句清除自事务起始点至该语句所做的所有数据更新操作
2、设置自动提交关闭或开启
- MySQL 设置默认每条 SQL 语句就是一个事务,每执行一个 SQL 语句就会默认提交
- MySQL 允许修改默认设置 autocommit 的值,及一条 SQL 语句不会被默认提交
- 设置自动提交关闭或开启的语法
SET autocommit=0|1
- autocommit 的值为0时,表示关闭自动提交
- autocommit 的值为1时,表示开启自动提交
8.2 索引
8.2.1 索引简介
- 使有序的内容在查找时消耗的时间更少,效率更高
- 索引是对数据表中的一列值或多列值进行排列的一种结构
- 索引是创建在数据表对象上的,有一个字段或多个字段生产的键组成
8.2.2 索引的分类
- MySQL 中常用的索引
- 普通索引(INDEX)
- 唯一索引(UNIQUE)
- 主键索引(PRIMARY KEY)
- 全文索引(FULLTEXT)
- 普通索引
- MySQL 中的基本索引类型
- 该类索引对索引的数据没有任何限制
- 允许定义重复值或空值
- 唯一任务是加快对数据的访问速度
- 唯一索引
- 唯一索引不允许出现两行具有相同的索引值
- 现有数据中如果有重复的键值,则大多数数据库不允许创建唯一索引
- 主键索引
- 一种特殊的唯一索引
- 不允许有空值
- 创建数据表时,如果指定了主键,则会自动创建主键索引
- 全文索引
- 全文索引的作用是在定义索引的列上支持值的全文查找
- 允许全文索引列中有重复值和空值
- 全文索引只能在 CHAR、VARCHAR、TEXT 类型的列上创建
8.2.3 在 MySQL 中使用索引
1、创建索引
- 使用 CREATE INDEX 可以在已经存在的表上添加索引
- 添加索引语法
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX 索引名称 ON 表名(列名)
- UNIQUE、FULLTEXT、SPATIAL:分别表示唯一索引、全文索引、空间索引,为可选参数
2、查看索引
- 使用 SHOW INDEX 关键字可以查看已创建的索引
- 查看索引 语法
SHOW INDEX FORM 表名
3、删除索引
- 删除索引 语法
DROP INDEX 索引名 ON 表名
- 删除表时,该列的所有索引将同时被删除
- 删除表中的列时,若要删除的列为索引的组成部分,则该列也会从索引中被删除
- 如果组成索引的所有列被删除,则整个索引被删除
8.3 视图
8.3.1 需要视图的原因
- 不同身份的用户所查询的数据范围不同,只将用户需要的某些列展示给用户,不展示多余的列
- 使用视图,可以定制用户数据,聚焦特定的数据
- 也可以借助视图,对代码进行封装保存
8.3.2 视图的概念
1、视图是一张虚拟表
- 表示一张表的部分数据或多张表的综合数据
- 其结构和数据是建立在对表的查询基础上
2、视图中不存放数据
- 数据存放在视图所引用的原始表中
3、一个原始表,根据不同用户的不同需求,可以创建不同的视图
8.3.3 视图的好处
1、给开发人员带来好处
- 限制数据检索更容易
- 维护应用程序更方便
2、给数据库的最终用户带来的好处
- 结果更容易理解
- 获得数据更容易
8.3.4 在 MySQL 中使用视图
1、创建视图
- 创建视图 语法
CREATE VIEW 视图名 AS <SELECT 语句>;
- 视图名一般以 view_xxx 或 v_xxx 来命名
2、查询视图中的数据
- 查询已创建的视图中的数据 语法
SELECT * FROM 视图名
3、删除视图
- 与数据表一样,若将要创建的视图在数据库中已经存在,则先删除视图才能创建成功
- 删除视图 语法
DROP VIEW [IF EXISTS] 视图名;
4、使用视图的注意事项
- 每个视图可以使用多张表
- 与查询相识,一个视图可以嵌套另一个视图,但尽量不要超过 3 层
- 对视图数据进行添加、更新、删除操作实际上是直接操作引用表中的数据
8.4 数据库备份和恢复
8.4.1 数据库备份
1、使用 mysqldump 备份数据库
- 通过 mysqldump 命令可以将指定的数据库和数据表导出为 SQL 脚本
- 使用 mysqldump 备份数据库是在命令行中实现的 命令如下
mysqldump [options] database [table1.table2,...] > [path]/filename.sql
- options:连接数据库的参数,主要内容如下
- -u username:用户名
- -h host:登录用户的主机名称。若为本机,则省略
- -p password:登录密码
- database:需要备份的数据库
- table:需要备份的数据表,可指定多张表。若备份整个数据库,则省略
- filename.sql:备份文件的名称
- mysqldump 是 DOS 命令,无需进入 mysql 命令行
2、使用 Navicat 备份数据库
- 使用 Navicat 也可以导出数据库的备份脚本
- 选择要备份的数据库,右键之后选择 “转储 SQL 文件” --> “结构和数据…” 命令 即可导出
8.4.2 数据库恢复
1、使用 MySQL 命令导入数据
- 使用导出的 SQL 备份脚本,在需要恢复时通过 MySQL 命令对其进行导入操作
- 导入SQL 备份脚本 命令如下
mysql -u username -p dbname < filename.sql
- username:登录数据库系统的用户名
- dbname:导入目标数据库的数据库名
- filename.sql:数据库备份后的文件地址
2、使用 source 命令恢复数据、
- 可以在已连接数据库的状态下导入数据
- 使用 source 命令 语法如下
source filename;
- filename 为 SQL备份后的文件地址
3、使用 Navicat 的数据导入功能导入数据
- 也可以使用 Navicat 直接导入数据
- 右键选择要导入数据的数据库,执行 “运行 SQL 文件…” 命令,之后在打开的导入窗口,选择要运行的 SQL 文件,单机 “开始”,即可开始导入数据
九、JDBC
9.1 JDBC 介绍
JDBC (Java Database Connectivity,Java数据库连接)
9.1.1 使用 JDBC 的原因
- Java 通过 JDBC 技术实现对各种数据库的访问,充当 Java 应用程序与各种数据库之间进行对话的媒介
- 通过 JDBC 可以将程序中的数据持久的保存到数据库当中
- Sun 公司提供了 JDBC 的接口规范------JDBC API
9.1.2 JDBC 的工作原理
- JDBC 主要有 JDBC API、JDBC Driver Manager 和 JDBC 驱动组成
1、JDBC API
- JDBC API 提供了一套 Java 应用程序与各种数据库交互的标准接口
- 其中 Connection(连接)接口、Statement 接口、ResultSet(结果集)接口、preparedStatement 接口等都属于 JDBC 接口
2、JDBC Driver Manager
- JDBC Driver Manager 是 JDBC 体系结构的支柱
- 负责管理各种 JDBC 驱动
- JDBC Driver Manager 位于 JDK 的 java.sql 包中
3、JDBC 驱动
- JDBC 驱动不包含在 JDK中,由第三方中间厂商提供
- 负责连接各种数据库
9.1.3 JDBC API
- JDBC API 是 Java 应用与各种数据库交互的标准接口
- 主要功能是建立与数据库的连接,发送 SQL 语句,返回处理结果
- JDBC API 主要类/接口 的功能
| 类/接口 | 作用 |
|---|---|
| DriverManager 类 | 装载驱动程序,并为创建新的数据库连接提供支持 |
| Connection 接口 | 负责连接数据库并担任传送数据的任务 |
| Statement 接口 | 由 Connection 产生,负责执行 SQL 语句 |
| PreparedStatement 接口 | Statement 的子接口,也由 Connection 产生,负责执行 Sql语句 与 Statement 接口的区别:PreparedStatement 借口具有高安全性、 高性能、高可读性和高可维护性等优点 |
| ResultSet 接口 | 负责保存和处理 Statement 执行后产生的查询结果 |
9.2 使用 JDBC 连接数据库
9.2.1 使用 JDBC 连接数据库的方法
1、加载 JDBC 驱动
- JDBC 驱动由数据库厂商或第三方中间件厂商提供,使用 JDBC 连接数据库前要先下载对应版本的驱动
- 可以在 MySQL 广为下载对应的 JDBC 驱动 JAR 包
- 导入 JDBC 的驱动 JAR 包后,需要加载驱动
- 驱动类的类名为 com.mysql.jdbc.Driver
- 通常使用 Class.forName 加载 JDBC 驱动
- 使用 Class.forName 加载驱动 语法
try{Class.forName("JDBC驱动类的名称")
}catch(ClassNotFoundException){//异常输出代码
}
2、与数据库建立连接
- JDBC 驱动类加载后,需要建立与 MySQL 数据库连接
- 建立连接使用 DriverManager 类,DriverManager 类是 JDBC 的管理层,作用于用户和驱动程序之间
- getConnection() 方法用于建立与数据库的连接
- 调用 getConnection() 方法 需要放入参数:数据库连接地址字符串、连接数据库的用户名和密码
- 建立连接数据库 语法
Connection conn=DriverManager.getConnection(数据库连接地址字符串,数据库用户名,密码)
- 数据库连接字符串 语法格式
jdbc:数据库://ip:端口/数据库名称 [?连接参数=参数值]
- 数据库: JDBC 连接的目标数据库,如 MySQL 数据库
- ip:JDBC 所连接的目标数据库地址,如果是本地数据库,则可以使用 localhost。即本地主机名
- 端口:连接数据库的端口号,如果连接 MySQL 数据库,则默认端口号为 3306
- 数据库名称:目标数据库的名称,如 hospital
- 连接参数:连接数据库时的参数配置。
- Connection 接口常用的方法
| 方法名称 | 作用 |
|---|---|
| Statement createStatement() | 创建一个 Statement 对象并将 SQL 语句发送到数据库 |
| PreparedStatement preparedStatement(String sql) | 创建一个 PreparedStatement 对象并将参数化的 SQL 语句发送到数据库 |
| boolean isClosed() | 查询此 Connection 对象是否已经被关闭。若已关闭,返回true |
| void close() | 立即释放此 Connection 对象的数据库和 JDBC 资源 |
9.3 使用 Statement 执行数据库操作
9.3.1 使用 Statement 接口更新数据
-
获取 Connection 对象后,需要使用 Connection 对象的 createStatement() 方法创建 Statement 对象,在通过 Statement 对象 将 SQL 语句发送到 MySQL 服务器中执行操作
-
在 Statement 接口中执行 SQL 命令的 3 种常用方法
| 方法名称 | 作用 |
|---|---|
| ResultSet executeQuery(String sql) | 可以执行 SQL 查询并获取 ResultSet 对象 |
| int executeUpdate(Sting sql) | 可以执行插入、删除、更新等操作,返回值时执行该操作所影响的行数 |
| boolean execute(String sql) | 可以执行任意 SQL 语句。若结果为 Result 对象,则返回 true;若结果为 更新计数或不存在任何结果,则返回 false |
- 使用 Statement 接口更新数据库中数据的步骤,与插入、修改、删除数据类似,都可以使用 executeUpdate() 方法
- 使用Statement执行对象实现新增操作 示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
/* 准备工作:* 1.从官网下载MySql驱动包* 2.将驱动包引入到项目工程中*/
public class LX_insert {public static void main(String[] args) throws ClassNotFoundException, SQLException {Scanner input=new Scanner(System.in);//设置连接数据库需要的参数//获取驱动类String driver="com.mysql.jdbc.Driver";//数据库连接地址String url="jdbc:mysql://localhost:3306/hospital?useUnicode=true&characterEncoding=UTF-8";//数据库用户名String user="root";//数据库密码String password="root";//加载驱动Class.forName(driver);//建立数据库连接Connection conn= DriverManager.getConnection(url,user,password);//创建 Statement 对象Statement statement=conn.createStatement();//获取要添加的数据System.out.print("请输入患者密码:");String patientPassWord=input.next();System.out.print("请输入患者性别:");String patientGender=input.next();System.out.print("请输入患者姓名:");String patientName=input.next();//拼接 SQL 语句StringBuffer sql=new StringBuffer("INSERT INTO patient(password,gender,patientName) VALUES ('");sql.append(patientPassWord);sql.append("','");sql.append(patientGender);sql.append("','");sql.append(patientName);sql.append("');");System.out.println(sql);//发送 SQL 语句,并接收结果int effectRowNum= statement.executeUpdate(sql.toString());//判断是否添加成功if(effectRowNum>0){System.out.println("添加成功");}else{System.out.println("添加失败");}//关闭资源statement.close();conn.close();}
}
运行结果
请输入患者密码:111111
请输入患者性别:男
请输入患者姓名:无名氏
INSERT INTO patient(password,gender,patientName) VALUES ('111111','男','无名氏');
添加成功
9.3.2 使用 Statement 接口和 ResultSet 接口查询数据
-
使用 JDBC 查询数据库中的数据时,需要使用 ResultSet 对象来接收从数据库中返回的数据
-
ResultSet 常用方法
| 方法名 | 说明 |
|---|---|
| boolean next() | 将游标从当前位置向下移动一行 |
| boolean previous() | 游标从当前位置向上移动一行 |
| void close | 关闭 ResultSet 对象 |
| int getInt(int colIndex) | 以 int 形式获取结果集当前行指定列号值 |
| int getInt(String colLabel) | 以 int 形式获取结果集当前行指定列名值 |
| float getFloat(int colIndex) | 以 float 形式获取结果集当前行指定列号值 |
| float getFloat(String colLabel) | 以float形式获取结果集当前行指定列名值 |
| String getString(int colIndex) | 以String形式获取结果集当前行指定列号值 |
| String getString(String colLabel) | 以String形式获取结果集当前行指定列名值 |
- 使用 Statement 接口和 ResultSet 接口查询数据 示例
import java.sql.*;/* 准备工作:* 1.从官网下载MySql驱动包* 2.将驱动包引入到项目工程中*/
public class LX_Select {public static void main(String[] args) throws ClassNotFoundException, SQLException {//设置连接数据库需要的参数//获取驱动类String driver="com.mysql.jdbc.Driver";//数据库连接地址String url="jdbc:mysql://localhost:3306/hospital?useUnicode=true&characterEncoding=UTF-8";//数据库用户名String user="root";//数据库密码String password="root";//加载驱动Class.forName(driver);//建立数据库连接Connection conn= DriverManager.getConnection(url, user, password);//创建 Statement 对象Statement statement=conn.createStatement();//SQL 语句String sql="SELECT * FROM patient";//向 MySQL 发送 SQL 语句,并接收结果ResultSet rs=statement.executeQuery(sql);//输出结果//判断结果是否还有下一个while(rs.next()){//如果有下一个 输出 patientID列、patientName列System.out.println("病人编号:"+rs.getString("patientID")+"病人姓名:"+rs.getString("patientName"));}//关闭资源rs.close();statement.close();conn.close();}
}
运行结果
病人编号:1病人姓名:夏颖
病人编号:2病人姓名:李政
病人编号:3病人姓名:李沁
病人编号:4病人姓名:李思雨
病人编号:5病人姓名:夏天
病人编号:6病人姓名:刘占波
病人编号:7病人姓名:廖慧颖
病人编号:8病人姓名:李伟忠
病人编号:9病人姓名:姚维新
病人编号:10病人姓名:陈建
病人编号:11病人姓名:林永清
病人编号:12病人姓名:李亚
病人编号:13病人姓名:张菲
9.4 使用 PreparedStatement 接口防止 SQL 注入
9.4.1 SQL 注入攻击
- SQL 注入攻击是是一种注入攻击,应用程序没有对用户输入数据的合法性进行判断,导致应用程序存在安全隐患,最终达到欺骗服务器执行恶意的SQL命令
- 用户提交一段 SQL 代码,执行超出其权限的数据操作就被成为 SQL 注入攻击
- 现在为医院管理系统开发登录功能,要求用户输入密码和姓名,判断是否通过验证
代码演示
import java.sql.*;
import java.util.Scanner;
import java.sql.*;/* 准备工作:* 1.从官网下载MySql驱动包* 2.将驱动包引入到项目工程中*/public class LX_SQL {public static void main(String[] args) throws ClassNotFoundException, SQLException {Scanner input=new Scanner(System.in);//设置连接数据库需要的参数//获取驱动类String driver="com.mysql.jdbc.Driver";//数据库连接地址String url="jdbc:mysql://localhost:3306/hospital?useUnicode=true&characterEncoding=UTF-8";//数据库用户名String user="root";//数据库密码String password="root";//接收用户输入的姓名和密码System.out.print("请输入患者姓名:");String patientName=input.next();System.out.print("请输入患者密码:");String patientPassword=input.next();//加载驱动Class.forName(driver);//建立数据库连接Connection conn= DriverManager.getConnection(url, user, password);//创建 Statement 对象Statement statement=conn.createStatement();//SQL 语句StringBuffer sql=new StringBuffer("SELECT * FROM patient where patientName='");sql.append(patientName);sql.append("'and password='");sql.append(patientPassword);sql.append("';");//向 MySQL 发送 SQL 语句,并接收结果ResultSet rs=statement.executeQuery(sql.toString());//判断输入的是否正确if(rs.next()){System.out.println("登录成功");System.out.println("病人姓名:"+rs.getString("patientName"));}else{System.out.println("登录失败");}//关闭资源rs.close();statement.close();conn.close();}}
效果演示
请输入患者姓名:夏颖
请输入患者密码:123456
登录成功
病人姓名:夏颖
使用 SQL注入攻击 效果演示
请输入患者姓名:*-*
请输入患者密码:100'OR'1'='1
登录成功
病人姓名:夏颖
- 由上方演示可看出,这是典型的 SQL 注入攻击
- 原因时在使用 Statement 接口方法时要进行 SQL 语句的拼接。拼接不仅繁琐且容易出错
- 使用 PreparedStatement 可以规避这些问题
9.4.2 使用 PreparedStatement 接口查询数据
- PreparedStatement 接口继承自 Statement 接口
- PreparedStatement 接口的常用方法
| 方法 | 作用 |
|---|---|
| boolean execute() | 执行 SQL 语句,该语句可以是任何 SQL 语句。若结果为 Result 对象, 则返回 true;若结果是更新计数或没有结果,则返回 false |
| ResultSet executeQuery() | 执行 SQL 查询,并返回该查询生成的 ResultSet 对象 |
| int executeUpdate() | 执行 SQL 语句,该语句必须是一个 DML 语句,如 INSERT、UPDATE 或 DELETE 语句;或者是无返回内容的 SQL 语句和 DDL 语句。返回值时执行该操作所影响的行数 |
| void sexXxx(int index,xxx x) | 方法名 Xxx 和第二个参数的 xxx 均表示如 int、float、double 等基本数据类型, 并且两个类型必须一致,参数列表中的 x 表示方法的形式参数。把指定数据类型 (xxx) 的值 x 设置为 index 位置的参数。根据参数类型的不同,常见的方法有 setInt(int index,int x)、setFloat(int index,float x),setDouble(int index,double x) 等 |
| void setObject(int index,Object x) | 除基本数据类型外,参数类型也可以使 Object,可以将 Object 对象 x 设置为 index 位置的参数 |
9.4.3 创建 PreparedStatement 对象
1、创建 PreparedStatement 对象
-
通过 Connection 接口的 prepareStatement (String sql) 方法创建 PreparedStatement 对象
-
在创建 PreparedStatement 对象时应设置号该对象要执行的 SQL 语句
-
SQL 语句可以具有一个或多个输入参数时,这些输入参数的值在 PreparedStatement 创建时违背指定,而
是为每个参数保留一个 ? 作为占位符
-
因为 SQL 语句的参数已经固定,所以不会出现 SQL 注入的漏洞
-
在 SQL 语句中使用 ? 作为占位符 演示
String sql="SELECT * FROM patient where patientName=? and password=?"
2、设置输入参数的值
- 通过调用 setXxx() 方法完成参数赋值
- Xxx 时与该参数类型相应的类型,若参数是 String 类型,则使用方法 setString()
- setXxx() 方法的第一个参数选择设置某个参数 (从1开始计数)
- 第二个参数用于设置该参数的值
- 设置 SQL 语句中参数的值 演示
String sql="SELECT * FROM patient where patientName=? and password=?";
PreparedStatement pps=conn.prepareStatement(sql);
pps.setString(1,"夏颖");
pss.setString(2,"123456")
3、使用 PreparedStatement 升级医院管理系统开发登录功能
- 代码演示
import java.sql.*;
import java.util.Scanner;
import java.sql.*;/* 准备工作:* 1.从官网下载MySql驱动包* 2.将驱动包引入到项目工程中*/public class LX_SQL {public static void main(String[] args) throws ClassNotFoundException, SQLException {Scanner input=new Scanner(System.in);//设置连接数据库需要的参数//获取驱动类String driver="com.mysql.jdbc.Driver";//数据库连接地址String url="jdbc:mysql://localhost:3306/hospital?useUnicode=true&characterEncoding=UTF-8";//数据库用户名String user="root";//数据库密码String password="root";//接收用户输入的姓名和密码System.out.print("请输入患者姓名:");String patientName=input.next();System.out.print("请输入患者密码:");String patientPassword=input.next();//加载驱动Class.forName(driver);//建立数据库连接Connection conn= DriverManager.getConnection(url, user, password);//SQL 语句String sql="SELECT * FROM patient where patientName=? and password=?";//创建 PreparedStatement 对象PreparedStatement pps=conn.prepareStatement(sql);//设置参数值pps.setString(1,patientName);pps.setString(2,patientPassword);//输出 SQL 语句System.out.println(pps.toString());//接收查询数据ResultSet rs=pps.executeQuery();//判断输入的是否正确if(rs.next()){System.out.println("登录成功");System.out.println("病人姓名:"+rs.getString("patientName"));}else{System.out.println("登录失败");}//关闭资源rs.close();pps.close();conn.close();}}
运行效果展示
请输入患者姓名:夏颖
请输入患者密码:123456
com.mysql.jdbc.JDBC4PreparedStatement@20ad9418: SELECT * FROM patient where patientName='夏颖' and password='123456'
登录成功
病人姓名:夏颖
测试 SQL 注入攻击 运行效果展示
请输入患者姓名:夏颖
请输入患者密码:100'OR'1'='1
com.mysql.jdbc.JDBC4PreparedStatement@20ad9418: SELECT * FROM patient where patientName='夏颖' and password='100\\'OR\\'1\\'=\\'1'
登录失败
9.4.4 PreparedStatement 的优势
- 可读性高和可维护性高
- SQL 语句的执行性能高
- 安全性高
十、数据访问和 DAO 模式
10.1 Properties 配置文件
10.1.1 Properties 配置文件简介
- Java 中有一个比较重要的 Properties 类,可以读取 Java 配置文件
- 可以把常用的配置信息写在配置文件中,方便软件工程师进行维护和修改
- 即可以将操作数据库所用的服务器参数写入配置文件中
- Java 配置文件通常是扩展名为 .properties 的文件
- 文件中以 “键=值” 的格式存储数据
- 可以使用 “#” 添加注释
- 为数据库访问添加的配置文件会被命名为 datebase.properties
10.1.2 使用 Properties 配置文件的步骤
1. 添加 properties 文件
- 选中项目下的 src 文件并右击,在弹出的快捷键菜单中执行 “New-File” 命令
- 再打开的 “New File” 创建文件,后缀为 properties
2. 编辑配置文件
-
在 database.properties 文件中添加配置信息
-
在连接数据库时,可能会修改的部分时数据库驱动 (driver)、数据库连接 URL (url)、
连接数据库的用户名 (user) 和密码 (password)
-
按照 Properties 文件格式填写配置文件,如下
dirver=com.mysql.jdbc.Driver;
url=jdbc:mysql://localhost:3306/hospital?useUnicode=ture&characterEncoding=UTF-8
user=root
password=root
- 配置文件中的数据格式和 Java 中的 Map 结构相似,等号之前是 键、等号之后是指
- 配置文件当中,键应该唯一,但值可以不唯一
3. 读取配置信息
- 使用 java.util 包下的 Properties 类读取配置文件,Properties 类继承自 Hashtable 类
- Properties 类的常用方法
| 方法 | 描述 |
|---|---|
| String getProperty(String key) | 用指定的键在此属性列表中搜索属性,通过参数 key 得到其所对应的值 |
| Object serProperty(String key,String value) | 通过调用基类 Hashtable 的 put() 方法设置键-值对 |
| void load(InputStream inStream) | 从输入流中读取属性列表 (键和元素对),通过对指定文件进行装载获取 该文件中所有的键-值对 |
| void clear() | 清除所装载的键-值对,该方法由基类 Hashtable 提供 |
10.1.3 使用 Properties 配置文件来配置文件的参数
- 编写一个 DBUtil 工具类,来方便以后数据库的连接
- 编写 inti() 方法,用来配置连接数据库的参数
public class DBUtil {public static String driver;public static String url;public static String user;public static String password;//静态方法,创建该类时自动调用static{init();}//配置文件public static void init(){String file="database.properties";InputStream in=DBUtil.class.getClassLoader().getResourceAsStream(file);Properties ties=new Properties();try {ties.load(in);} catch (IOException e) {throw new RuntimeException(e);}driver= ties.getProperty("driver");url=ties.getProperty("url");user=ties.getProperty("user");password=ties.getProperty("password");}
- 再次连接数据库时,则不需要在配置 driver 等参数,直接调用该类的静态变量即可
10.2 DAO 模式
10.2.1 DAO 模式 概念
- DAO(Data Access Object)数据访问对象。主要的功能就是用于进行数据操作的,在程序的标准开发架构中属于数据层的操作
- 方便在不同的数据库之间切换
- DAO 模式主要有三个参与者
- 数据访问对象接口: 定义在一个模型对象上要执行的标准操作
- 数据访问对象实体类:实现数据访问对象接口,负责从数据库等存储机制中获取数据
- 模型对象/数值对象:用来存储获取到的数据的类对象
- DAO模式的UML图
- 上图中,Student 为模型对象/数值对象(实体类)
- StudentDao 为数据访问对象接口,规定了对student类型的数据要进行那些操作
- StudentDaoImpl 是数据访问对象实体类的角色,具体实现了如何从数据库获取数据,来进行这些增删改查的操作
10.2.2 实体类
-
Entity(实体类)是在 Java 项目中,与数据表相对应的类
-
实体类特征
- 属性一般使用
private修饰 - 提供public修饰的
getter/setter方法 - 实体类提供无参构造方法,根据业务提供有参构造
- 实现
java.io.Serializable接口,支持序列化机制,可以将该对象转换成字节序列而保存在磁盘上或在网络上传输
- 属性一般使用
-
操作数据库时,会将数据库中的实体及关系以实体类的方式组织起来
-
通常在 Java 工程中,创建一个名为 entity 的 Package 集合保存实体类
-
示例
以下表格为 patient 表中的字段,构造 patient 实体,实体类中的属性与 patient 表中的字段相对应
| 名 | 类型 | 长度 | 小数点 | 不是null | 虚拟 | 键 | 注释 |
|---|---|---|---|---|---|---|---|
| patientID | int | 4 | 0 | ☑ | □ | 主键 | 病人编号 |
| password | varchar | 20 | 0 | ☑ | □ | 登录密码 | |
| birthDate | date | 0 | 0 | □ | □ | 出生日期 | |
| gender | varchar | 4 | 0 | ☑ | □ | 性别 | |
| patirentName | varchar | 50 | 0 | ☑ | □ | 病人姓名 | |
| phoneNum | varchar | 50 | 0 | □ | □ | 联系电话 | |
| varchar | 70 | 0 | □ | □ | 邮箱 | ||
| identityNum | varchar | 20 | 0 | □ | □ | 身份证号 | |
| address | varchar | 255 | 0 | □ | □ | 地址 |
在 Java 项目中构造 patient 表的实体类
package cn.QiaoYun.entity;/ 患者表* */
public class Patient {private int patientId;private String password;private String birthDate;private String gender;private String patientName;private String phoneNum;private String email;private String identityNum;private String address;public int getPatientId() {return patientId;}public void setPatientId(int patientId) {this.patientId = patientId;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getBirthDate() {return birthDate;}public void setBirthDate(String birthDate) {this.birthDate = birthDate;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getPatientName() {return patientName;}public void setPatientName(String patientName) {this.patientName = patientName;}public String getPhoneNum() {return phoneNum;}public void setPhoneNum(String phoneNum) {this.phoneNum = phoneNum;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getIdentityNum() {return identityNum;}public void setIdentityNum(String identityNum) {this.identityNum = identityNum;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Patient() {}public Patient(int patientId, String password, String birthDate, String gender, String patientName, String phoneNum, String email, String identityNum, String address) {this.patientId = patientId;this.password = password;this.birthDate = birthDate;this.gender = gender;this.patientName = patientName;this.phoneNum = phoneNum;this.email = email;this.identityNum = identityNum;this.address = address;}@Overridepublic String toString() {return "Patient{" +"patientId=" + patientId +", password='" + password + '\\'' +", birthDate='" + birthDate + '\\'' +", gender='" + gender + '\\'' +", patientName='" + patientName + '\\'' +", phoneNum='" + phoneNum + '\\'' +", email='" + email + '\\'' +", identityNum='" + identityNum + '\\'' +", address='" + address + '\\'' +'}';}
}
10.2.3 实现 DAO 模式
- 实现 DAO 模式时,首先要定义统一的抽象 API ,将操作数据的代码抽象成接口,只需要调用这些代码就可以实现对数据的访问
- 接口创建完后,通常会创建新接口实现类,考虑不同数据库实现代码的差异性,可以定义实现类,如下
- 在编写实现类的时候,每个操作都需要进行数据库的连接,可以将连接数据库的这些操作,专门写到一个类当中,放到一个专门类---- BaseDao 中
- 同时,也可以在 BaseDao 中编写一种 增、删、改 通用操作,当需要进行操作时,传入不同的参数即可
10.2.4 DAO 模式总结
- DAO 模式的优势在于它实现了两次隔离
- 隔离了数据访问代码和业务逻辑代码,即代码耦合
- 隔离了不同数据库的实现。
- 典型 DAO 模式的主要部分
- 实体类:用于存放传输对象数据
- 数据库操作工具类:即 BaseDao 类,避免数据库连接和关闭代码的重复使用,方便进行修改
- DAO 接口:把对数据库的所有操作定义抽象方法,可以提供多种实现
- DAO 实现类:针对不同数据库给出 DAO 接口定义方法的具体实现
10.3 项目 包命名规范
10.3.1 项目包命名及位置

- entity 包:用于存放实体类
- dao 包:接口类,定义对数据库的数据进行操作的方法
- BaseDao 类:进行连接数据库的操作
- dao 包下的 impl包:用户实现 dao 包下的接口类,基础 BaseDao,实现增删改查
- service 包:接口类,定义项目的功能
- service 包下的 impl包:实现接口类,将多个增删改查操作组合在一起,实现项目的功能
- lib 包:存放连接数据库的依赖包
十一、综合项目实训
通过学习 JDBC 及 Dao 模式,现在通过项目联系,进行对 JDBC 及 Dao 模式的进一步训练
以下是我通过练习,写的一个 理发店项目,仅供参考
11.1 数据库设计
11.1.1 项目需求分析
- 设计数据库之前,首先要对项目的需求进行大概的分析
- 分析自己的项目需要实现哪些业务,根据实现的不同业务来进行数据库的设计
- 以下是我自己所分析的一张大概业务图,比较草率,仅供参考

11.1.2 设计项目 数据库 E-R 图
-
大概需求分析完毕后,需要根据自己所实现的业务需求,来设计数据库的 E-R图
-
以下是我个人绘制的 E-R图,仅供参考

11.1.3 设计项目 数据库模型图
- 设计玩 E-R 图后,应当根据 E-R图,进一步设计 数据库的模型图
- 通过图形化的方式,显示数据库存储的信息,信息的数据类型,以及各表之间的关系
- 以下是我个人设计的数据库模型图

11.1.4 设计项目的数据库
-
根据自己所设计的 数据库模型图,进一步的设计自己项目所需的数据库
-
以下是我自己设计的数据库(仅结构),仅供参考
/*Navicat Premium Data TransferSource Server : LanQiaoerSource Server Type : MySQLSource Server Version : 50740 (5.7.40)Source Host : localhost:3306Source Schema : blockTarget Server Type : MySQLTarget Server Version : 50740 (5.7.40)File Encoding : 65001Date: 03/04/2023 15:50:26
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for blocktype
-- ----------------------------
DROP TABLE IF EXISTS `blocktype`;
CREATE TABLE `blocktype` (`blockTypeID` int(11) NOT NULL AUTO_INCREMENT COMMENT '卡类型ID',`blockTypeName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '卡类型名称',`blockdiscount` double NOT NULL COMMENT '卡折扣',`maxRecharge` double NOT NULL COMMENT '最大充值金额',`minRecharge` double NULL DEFAULT NULL COMMENT '最小充值金额',PRIMARY KEY (`blockTypeID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = DYNAMIC;-- ----------------------------
-- Table structure for consumption
-- ----------------------------
DROP TABLE IF EXISTS `consumption`;
CREATE TABLE `consumption` (`consumptionID` int(11) NOT NULL AUTO_INCREMENT COMMENT '消费记录ID',`consumptionUserID` int(11) NOT NULL COMMENT '消费用户ID',`consumptionProjectID` int(11) NOT NULL COMMENT '消费项目ID',`staffID` int(11) NOT NULL COMMENT '消费时,使用哪位员工的ID',`consumptionBalance` double NOT NULL COMMENT '金额流水',`userBalance` double NOT NULL COMMENT '消费后用户余额余额',`consumptionDatetime` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '消费时间',PRIMARY KEY (`consumptionID`) USING BTREE,INDEX `FK_consumption_user`(`consumptionUserID`) USING BTREE,INDEX `FK_consumption_staff`(`staffID`) USING BTREE,INDEX `FK`(`consumptionProjectID`) USING BTREE,CONSTRAINT `FK` FOREIGN KEY (`consumptionProjectID`) REFERENCES `projecttype` (`projectTypeID`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `FK_consumption_staff` FOREIGN KEY (`staffID`) REFERENCES `staff` (`staffID`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `FK_consumption_user` FOREIGN KEY (`consumptionUserID`) REFERENCES `user` (`userID`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 47 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for manageruser
-- ----------------------------
DROP TABLE IF EXISTS `manageruser`;
CREATE TABLE `manageruser` (`ManagerID` int(11) NOT NULL AUTO_INCREMENT,`ManagerUserName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,`ManagerPassword` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,PRIMARY KEY (`ManagerID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for projecttype
-- ----------------------------
DROP TABLE IF EXISTS `projecttype`;
CREATE TABLE `projecttype` (`projectTypeID` int(11) NOT NULL AUTO_INCREMENT COMMENT '消费类型ID',`projectTypeName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '消费类型名称',`projectTypePrice` double NOT NULL COMMENT '消费项目金额',`staffTypeID` int(11) NULL DEFAULT NULL COMMENT '员工类型ID',PRIMARY KEY (`projectTypeID`) USING BTREE,INDEX `FK_projecttype_stafftype`(`staffTypeID`) USING BTREE,CONSTRAINT `FK_projecttype_stafftype` FOREIGN KEY (`staffTypeID`) REFERENCES `stafftype` (`staffTypeID`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for staff
-- ----------------------------
DROP TABLE IF EXISTS `staff`;
CREATE TABLE `staff` (`staffID` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工ID',`staffName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '员工姓名',`staffTypeID` int(11) NOT NULL COMMENT '员工类型ID',PRIMARY KEY (`staffID`) USING BTREE,INDEX `FK_staff_staffType`(`staffTypeID`) USING BTREE,CONSTRAINT `FK_staff_staffType` FOREIGN KEY (`staffTypeID`) REFERENCES `stafftype` (`staffTypeID`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for stafftype
-- ----------------------------
DROP TABLE IF EXISTS `stafftype`;
CREATE TABLE `stafftype` (`staffTypeID` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工类型ID',`staffTypeName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '员工类型名称',PRIMARY KEY (`staffTypeID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (`userID` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',`userName` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户姓名',`phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '用户电话',`userbalance` double NOT NULL DEFAULT 0 COMMENT '用户余额',`userAccount` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '用户账户',`userPassword` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '用户密码',PRIMARY KEY (`userID`) USING BTREE,UNIQUE INDEX `IN_useraccount`(`userAccount`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Table structure for userblock
-- ----------------------------
DROP TABLE IF EXISTS `userblock`;
CREATE TABLE `userblock` (`userBlockID` int(11) NOT NULL AUTO_INCREMENT COMMENT '开卡记录ID',`userBlockStaffID` int(11) NULL DEFAULT NULL COMMENT '帮用户开卡的员工ID',`rechargeable` double NOT NULL COMMENT '用户首次充值金额',`openBlockTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '开卡时间',`blockTypeID` int(11) NULL DEFAULT NULL COMMENT '卡类型ID',`userID` int(11) NULL DEFAULT NULL COMMENT '开卡用户ID',PRIMARY KEY (`userBlockID`) USING BTREE,UNIQUE INDEX `FK_userblock_user`(`userID`) USING BTREE,INDEX `FK_userblock_staff`(`userBlockStaffID`) USING BTREE,INDEX `FK_userblock_blockType`(`blockTypeID`) USING BTREE,CONSTRAINT `FK_userblock_blockType` FOREIGN KEY (`blockTypeID`) REFERENCES `blocktype` (`blockTypeID`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `FK_userblock_staff` FOREIGN KEY (`userBlockStaffID`) REFERENCES `staff` (`staffID`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `FK_userblock_user` FOREIGN KEY (`userID`) REFERENCES `user` (`userID`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;-- ----------------------------
-- Procedure structure for proc_selectBlockTypeIDByBlockName
-- ----------------------------
DROP PROCEDURE IF EXISTS `proc_selectBlockTypeIDByBlockName`;
delimiter ;;
CREATE PROCEDURE `proc_selectBlockTypeIDByBlockName`(IN money DOUBLE)
BEGIN#Routine body goes here...IF money<200 THENSELECT blockTypeID FROM blocktype WHERE blockTypeName='白银卡';ELSEIF money>500 AND money<1000 THENSELECT blockTypeID FROM blocktype WHERE blockTypeName='白金卡';ELSEIF money>1000 AND money<2000 THENSELECT blockTypeID FROM blocktype WHERE blockTypeName='黄金卡';ELSEIF money>2000 THENSELECT blockTypeID FROM blocktype WHERE blockTypeName='钻石卡';END IF;
END
;;
delimiter ;SET FOREIGN_KEY_CHECKS = 1;
11.2 创建包
11.2.1 理发店项目文件大致结构
- 创建包的大致结构

11.3 entity(实体类)
在 entity 包下,创建自己的实体类
可根据不同的业务功能,在实体类中增加额外的属性,方便自己编写
11.3.1 Blocktype (卡类型) 实体类
package cn.block.entity;public class Blocktype {private int blockTypeId;private String blockTypeName;private double blockdiscount;private double maxRecharge;private double minRecharge;public Blocktype() {}@Overridepublic String toString() {return "Blocktype{" +"blockTypeId=" + blockTypeId +", blockTypeName='" + blockTypeName + '\\'' +", blockdiscount=" + blockdiscount +", maxRecharge=" + maxRecharge +", minRecharge=" + minRecharge +'}';}public Blocktype(int blockTypeId, String blockTypeName, double blockdiscount, double maxRecharge, double minRecharge) {this.blockTypeId = blockTypeId;this.blockTypeName = blockTypeName;this.blockdiscount = blockdiscount;this.maxRecharge = maxRecharge;this.minRecharge = minRecharge;}public int getBlockTypeId() {return blockTypeId;}public void setBlockTypeId(int blockTypeId) {this.blockTypeId = blockTypeId;}public String getBlockTypeName() {return blockTypeName;}public void setBlockTypeName(String blockTypeName) {this.blockTypeName = blockTypeName;}public double getBlockdiscount() {return blockdiscount;}public void setBlockdiscount(double blockdiscount) {this.blockdiscount = blockdiscount;}public double getMaxRecharge() {return maxRecharge;}public void setMaxRecharge(double maxRecharge) {this.maxRecharge = maxRecharge;}public double getMinRecharge() {return minRecharge;}public void setMinRecharge(double minRecharge) {this.minRecharge = minRecharge;}
}
11.3.2 Consumption(消费记录)实体类
package cn.block.entity;public class Consumption {private int consumptionId;private int consumptionUserId;private int consumptionProjectId;private int staffId;private double consumptionBalance;private double userBalance;private String consumptionDatetime;private String userName;private String staffName;private String projectTypeName;private String userAccount;private String userPassword;public Consumption() {}public Consumption(int consumptionId, int consumptionUserId, int consumptionProjectId, int staffId, double consumptionBalance, double userBalance, String consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPassword) {this.consumptionId = consumptionId;this.consumptionUserId = consumptionUserId;this.consumptionProjectId = consumptionProjectId;this.staffId = staffId;this.consumptionBalance = consumptionBalance;this.userBalance = userBalance;this.consumptionDatetime = consumptionDatetime;this.userName = userName;this.staffName = staffName;this.projectTypeName = projectTypeName;this.userAccount = userAccount;this.userPassword= userPassword;}public String getUserAccount() {return userAccount;}public void setUserAccount(String userAccount) {this.userAccount = userAccount;}public int getConsumptionId() {return consumptionId;}public void setConsumptionId(int consumptionId) {this.consumptionId = consumptionId;}public int getConsumptionUserId() {return consumptionUserId;}public void setConsumptionUserId(int consumptionUserId) {this.consumptionUserId = consumptionUserId;}public int getConsumptionProjectId() {return consumptionProjectId;}public void setConsumptionProjectId(int consumptionProjectId) {this.consumptionProjectId = consumptionProjectId;}public int getStaffId() {return staffId;}public void setStaffId(int staffId) {this.staffId = staffId;}public double getConsumptionBalance() {return consumptionBalance;}public void setConsumptionBalance(double consumptionBalance) {this.consumptionBalance = consumptionBalance;}public double getUserBalance() {return userBalance;}public void setUserBalance(double userBalance) {this.userBalance = userBalance;}public String getConsumptionDatetime() {return consumptionDatetime;}public void setConsumptionDatetime(String consumptionDatetime) {this.consumptionDatetime = consumptionDatetime;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getUserPassword() {return userPassword;}public void setUserPassword(String userPassword) {this.userPassword = userPassword;}public String getStaffName() {return staffName;}public void setStaffName(String staffName) {this.staffName = staffName;}public String getProjectTypeName() {return projectTypeName;}public void setProjectTypeName(String projectTypeName) {this.projectTypeName = projectTypeName;}@Overridepublic String toString() {return "Consumption{" +"consumptionId=" + consumptionId +", consumptionUserId=" + consumptionUserId +", consumptionProjectId=" + consumptionProjectId +", staffId=" + staffId +", consumptionBalance=" + consumptionBalance +", userBalance=" + userBalance +", consumptionDatetime='" + consumptionDatetime + '\\'' +", userName='" + userName + '\\'' +", staffName='" + staffName + '\\'' +", projectTypeName='" + projectTypeName + '\\'' +", userAccount='" + userAccount + '\\'' +", userPassword='" + userPassword + '\\'' +'}';}
}
11.3.3 Manageruser(管理员用户)实体类
package cn.block.entity;public class Manageruser {private int managerId;private String managerUserName;private String managerPassword;@Overridepublic String toString() {return "Manageruser{" +"managerId=" + managerId +", managerUserName='" + managerUserName + '\\'' +", managerPassword='" + managerPassword + '\\'' +'}';}public Manageruser(int managerId, String managerUserName, String managerPassword) {this.managerId = managerId;this.managerUserName = managerUserName;this.managerPassword = managerPassword;}public Manageruser() {}public int getManagerId() {return managerId;}public void setManagerId(int managerId) {this.managerId = managerId;}public String getManagerUserName() {return managerUserName;}public void setManagerUserName(String managerUserName) {this.managerUserName = managerUserName;}public String getManagerPassword() {return managerPassword;}public void setManagerPassword(String managerPassword) {this.managerPassword = managerPassword;}
}
11.3.4 Projecttype(消费项目类型)实体类
package cn.block.entity;public class Projecttype {private int projectTypeId;private String projectTypeName;private double projectTypePrice;private int staffTypeId;private String staffTypeName;@Overridepublic String toString() {return "Projecttype{" +"projectTypeId=" + projectTypeId +", projectTypeName='" + projectTypeName + '\\'' +", projectTypePrice=" + projectTypePrice +", staffTypeId=" + staffTypeId +", staffTypeName='" + staffTypeName + '\\'' +'}';}public Projecttype(int projectTypeId, String projectTypeName, double projectTypePrice, int staffTypeId, String staffTypeName) {this.projectTypeId = projectTypeId;this.projectTypeName = projectTypeName;this.projectTypePrice = projectTypePrice;this.staffTypeId = staffTypeId;this.staffTypeName = staffTypeName;}public Projecttype() {}public int getProjectTypeId() {return projectTypeId;}public void setProjectTypeId(int projectTypeId) {this.projectTypeId = projectTypeId;}public String getProjectTypeName() {return projectTypeName;}public void setProjectTypeName(String projectTypeName) {this.projectTypeName = projectTypeName;}public double getProjectTypePrice() {return projectTypePrice;}public void setProjectTypePrice(double projectTypePrice) {this.projectTypePrice = projectTypePrice;}public int getStaffTypeId() {return staffTypeId;}public void setStaffTypeId(int staffTypeId) {this.staffTypeId = staffTypeId;}public String getStaffTypeName() {return staffTypeName;}public void setStaffTypeName(String staffTypeName) {this.staffTypeName = staffTypeName;}
}
11.3.5 Staff(员工)实体类
package cn.block.entity;public class Staff {private int staffId;private String staffName;private int staffTypeId;private String staffTypeName;public String getStaffTypeName() {return staffTypeName;}public void setStaffTypeName(String staffTypeName) {this.staffTypeName = staffTypeName;}public int getStaffId() {return staffId;}public void setStaffId(int staffId) {this.staffId = staffId;}public String getStaffName() {return staffName;}public void setStaffName(String staffName) {this.staffName = staffName;}public int getStaffTypeId() {return staffTypeId;}public void setStaffTypeId(int staffTypeId) {this.staffTypeId = staffTypeId;}public Staff() {}public Staff(int staffId, String staffName, int staffTypeId, String staffTypeName) {this.staffId = staffId;this.staffName = staffName;this.staffTypeId = staffTypeId;this.staffTypeName = staffTypeName;}@Overridepublic String toString() {return "Staff{" +"staffId=" + staffId +", staffName='" + staffName + '\\'' +", staffTypeId=" + staffTypeId +", staffTypeName='" + staffTypeName + '\\'' +'}';}
}
11.3.6 Stafftype(员工类型)实体类
package cn.block.entity;public class Stafftype {private int staffTypeId;private String staffTypeName;public int getStaffTypeId() {return staffTypeId;}public void setStaffTypeId(int staffTypeId) {this.staffTypeId = staffTypeId;}public String getStaffTypeName() {return staffTypeName;}public void setStaffTypeName(String staffTypeName) {this.staffTypeName = staffTypeName;}public Stafftype() {}public Stafftype(int staffTypeId, String staffTypeName) {this.staffTypeId = staffTypeId;this.staffTypeName = staffTypeName;}@Overridepublic String toString() {return "Stafftype{" +"staffTypeId=" + staffTypeId +", staffTypeName='" + staffTypeName + '\\'' +'}';}
}
11.3.7 User(用户类)实体类
package cn.block.entity;public class User {private int userId;private String userName;private String phone;private double userbalance;private String userAccount;private String userPassword;@Overridepublic String toString() {return "User{" +"userId=" + userId +", userName='" + userName + '\\'' +", phone='" + phone + '\\'' +", userbalance=" + userbalance +", userAccount='" + userAccount + '\\'' +", userPassword='" + userPassword + '\\'' +'}';}public User() {}public User(int userId, String userName, String phone, double userbalance, String userAccount, String userPassword) {this.userId = userId;this.userName = userName;this.phone = phone;this.userbalance = userbalance;this.userAccount = userAccount;this.userPassword = userPassword;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public double getUserbalance() {return userbalance;}public void setUserbalance(double userbalance) {this.userbalance = userbalance;}public String getUserAccount() {return userAccount;}public void setUserAccount(String userAccount) {this.userAccount = userAccount;}public String getUserPassword() {return userPassword;}public void setUserPassword(String userPassword) {this.userPassword = userPassword;}
}
11.3.8 Userblock(会员用户)实体类
package cn.block.entity;public class Userblock {private int userBlockId;private int userBlockStaffId;private double rechargeable;private String openBlockTime;private int blockTypeId;private int userId;private String userName;public int getUserBlockId() {return userBlockId;}public void setUserBlockId(int userBlockId) {this.userBlockId = userBlockId;}public int getUserBlockStaffId() {return userBlockStaffId;}public void setUserBlockStaffId(int userBlockStaffId) {this.userBlockStaffId = userBlockStaffId;}public double getRechargeable() {return rechargeable;}public void setRechargeable(double rechargeable) {this.rechargeable = rechargeable;}public String getOpenBlockTime() {return openBlockTime;}public void setOpenBlockTime(String openBlockTime) {this.openBlockTime = openBlockTime;}public int getBlockTypeId() {return blockTypeId;}public void setBlockTypeId(int blockTypeId) {this.blockTypeId = blockTypeId;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}public Userblock() {}@Overridepublic String toString() {return "Userblock{" +"userBlockId=" + userBlockId +", userBlockStaffId=" + userBlockStaffId +", rechargeable=" + rechargeable +", openBlockTime='" + openBlockTime + '\\'' +", blockTypeId=" + blockTypeId +", userId=" + userId +", userName='" + userName + '\\'' +'}';}public Userblock(int userBlockId, int userBlockStaffId, double rechargeable, String openBlockTime, int blockTypeId, int userId, String userName) {this.userBlockId = userBlockId;this.userBlockStaffId = userBlockStaffId;this.rechargeable = rechargeable;this.openBlockTime = openBlockTime;this.blockTypeId = blockTypeId;this.userId = userId;this.userName = userName;}
}
11.4 dao 包 (工具接口)
定义对数据库的增删改查的方法
11.4.1 BaseDao (对数据库进行操作的父类)
package cn.block.dao;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class BaseDao {public static String driver;public static String url;public static String user;public static String password;//静态方法,创建该类时自动调用static {init();}//配置文件public static void init(){String file="database.properties";InputStream in=BaseDao.class.getClassLoader().getResourceAsStream(file);Properties ties=new Properties();try {ties.load(in);} catch (IOException e) {throw new RuntimeException(e);}driver= ties.getProperty("driver");url=ties.getProperty("url");user=ties.getProperty("user");password=ties.getProperty("password");}//建立数据库连接public static Connection getConn(){Connection conn=null;//启动驱动try {Class.forName(driver);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}try {conn= DriverManager.getConnection(url,user,password);} catch (SQLException e) {throw new RuntimeException(e);}return conn;}//关闭资源public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs){if(conn!=null){try {conn.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (ps!=null){try {ps.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(rs!=null){try {rs.close();} catch (SQLException e) {throw new RuntimeException(e);}}}//执行增加,删除,修改操作public static int update(String sql,Object [] objects){Connection conn=getConn();PreparedStatement preparedStatement=null;int a=0;try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}if(objects!=null){for (int i = 0; i < objects.length; i++) {try {preparedStatement.setObject(i+1, objects[i]);} catch (SQLException e) {System.out.println("宝宝出错了哦");e.printStackTrace();}}System.out.println(preparedStatement.toString());}try {a=preparedStatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();}closeAll(conn,preparedStatement,null);return a;}
}
11.4.2 blockTypeDao(接口)
package cn.block.dao;import cn.block.entity.Blocktype;import java.sql.SQLException;
import java.util.List;public interface blockTypeDao {//查询所有会员卡类型的信息public List<Blocktype> getAllBlockType() throws SQLException;//通过充值金额 显示会员卡类型IDpublic Blocktype getBlockTypeIDByPrice(double price) throws SQLException;//通过会员卡 ID 显示会员卡信息public Blocktype getBlockTypeByblockTypeID(int blockTypeID) throws SQLException;}
11.4.3 consumptionDao(接口)
package cn.block.dao;import cn.block.entity.Consumption;import java.sql.SQLException;
import java.util.List;public interface consumptionDao {//修改员工ID 修改外另一位员工IDpublic int updateStaffIDbyStaffID(int staffID);//查询所有用户的消费记录public List<Consumption> getAllConsumption() throws SQLException;public List<Consumption> selectConsumptionByUserID(int UserID);//增加消费记录public int insertConsumption(Consumption consumption);//根据用户的账户和密码 查询自己的消费记录public List<Consumption> getConsumptionByUseraccountANDUserPassword(String userAccount,String userPassword) throws SQLException;//查询刚消费的用户消费记录public Consumption getMaxConsumptionByUserID(int UserID) throws SQLException;
}
11.4.4 managerUserDao(接口类)
package cn.block.dao;import cn.block.entity.Manageruser;import java.sql.SQLException;public interface managerUserDao {//通过账户密码查看用户信息public Manageruser getmanagerUserInfoByManagerUserNameANDManagerPassword(String ManagerUserName, String ManagerPassword) throws SQLException;
}
11.4.5 projectTypeDao(接口)
package cn.block.dao;import cn.block.entity.Projecttype;
import java.sql.SQLException;
import java.util.List;/*
* 项目类型表
* */
public interface projectTypeDao {//查询所有项目类型public List<Projecttype> selectAllProjectTypes() throws SQLException;//通过 projectTypeID 获取 projectTypePricepublic double getProjectTypePriceByprojectTypeID(int projectTypeID) throws SQLException;//增加项目public int insertProjectType(Projecttype projectType) throws SQLException;//通过 projectTypeID 查询项目类型public Projecttype getProjectTypeByprojectTypeID(int projectTypeID) throws SQLException;//查询项目,不显示特殊业务public List<Projecttype> selectAliProjectTypes() throws SQLException;
}
11.4.6 staffDao(接口类)
package cn.block.dao;import cn.block.entity.Staff;import java.sql.SQLException;
import java.util.List;/*
* 员工表
* */
public interface staffDao {//查询所有员工public List<Staff> selectAllStaff() throws SQLException;//通过员工ID查询员工public Staff selectStaffByStaffID (int staffID) throws SQLException;//添加员工public int insertStaff(Staff staff) throws SQLException;//通过员工ID删除员工public int deleteStaff(int staffID) throws SQLException;//通过员工ID查询员工类型IDpublic int getStaffTypeIDByStaffID(int staffID) throws SQLException;
}
11.4.7 staffTypeDao(接口)
package cn.block.dao;import cn.block.entity.Stafftype;import java.sql.SQLException;
import java.util.List;/*
* 员工类型
* */
public interface staffTypeDao {//查询所有员工类型public List<Stafftype> getAllStaffTypes() throws SQLException;//添加员工类型public int insertStaffType(Stafftype staffType) throws SQLException;//通过员工类型ID 查询员工类型信息public Stafftype getStaffTypeInfoByStaffTypeID(int staffTypeID) throws SQLException;
}
11.4.8 userblockDao(接口类)
package cn.block.dao;import cn.block.entity.Userblock;import java.sql.SQLException;/*
* 会员用户
* */
public interface userblockDao {//添加会员用户public int insertUserblock(Userblock userblock);//修改员工ID 修改外另一位员工IDpublic int updateuserBlockStaffIDbyuserBlockStaffID(int staffID);//通过用户账户ID用户会员卡等级public int updateUserblockTyleIDByuserAccount(int blockTypeID,int userID);//通过用户ID 显示会员信息public Userblock getUserblockInfoByUserID(int userID) throws SQLException;//通过用户 ID 修改用户会员等级
}
11.4.9 userDao(接口)
package cn.block.dao;import cn.block.entity.User;import java.sql.SQLException;
import java.util.List;/*
* 用户表
* */
public interface userDao {//添加用户public int insertUser(User user) throws SQLException;//删除用户 根据用户IDpublic int deleteUserbyUserID(int userID) throws SQLException;//根据用户账户 修改用户名称public int updateUserNameByUserID(String userAccount,String userName) throws SQLException;//根据用户账户 修改用户手机号public int updateUserPhoneByUserID(String userAccount,String userPhone);//根据用户账户 修改用户余额public int updateUserbalanceByUserAccount(String userAccount,double userbalance);//查询所有用户public List<User> getAllUser() throws SQLException;//根据用户账户 获取用户余额public double getUserBalanceByUserAccoount(String userAccount) throws SQLException;//通过账户密码查看用户信息public User getUserInfoByUserAccountANDUserPassword(String userAccount,String userPassword) throws SQLException;//通过账户密码查看用户信息public User getUserInfoByUserAccount(String userAccount) throws SQLException;
}
11.5 dao 包下的 impl 包(工具实现类)
实现 dao 包下所定义的接口类,进行对数据库的增删改查
11.5.1 blockTypeDaoMySQLImpl (实现类)
package cn.block.dao.impl;import cn.block.dao.blockTypeDao;
import cn.block.dao.BaseDao;
import cn.block.entity.Blocktype;import java.sql.*;
import java.util.ArrayList;
import java.util.List;public class blockTypeDaoMySQLImpl extends BaseDao implements blockTypeDao {@Overridepublic List<Blocktype> getAllBlockType() throws SQLException {List<Blocktype> listBlocktype=new ArrayList<Blocktype>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from blocktype";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){Blocktype blocktype=new Blocktype(rs.getInt("blockTypeID"),rs.getString("blockTypeName"),rs.getDouble("blockdiscount"),rs.getDouble("maxRecharge"),rs.getDouble("minRecharge"));listBlocktype.add(blocktype);}closeAll(conn,preparedStatement,rs);return listBlocktype;}
/*
*
* */@Overridepublic Blocktype getBlockTypeIDByPrice(double money) throws SQLException {Blocktype blocktype=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="Select * from blocktype WHERE ? BETWEEN minRecharge AND maxRecharge";try {preparedStatement=conn.prepareStatement(sql);preparedStatement.setDouble(1,money);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){blocktype=new Blocktype(rs.getInt("blockTypeID"),rs.getString("blockTypeName"),rs.getDouble("blockdiscount"),rs.getDouble("maxRecharge"),rs.getDouble("minRecharge"));}closeAll(conn,preparedStatement,rs);return blocktype;}@Overridepublic Blocktype getBlockTypeByblockTypeID(int blockTypeID) throws SQLException {Blocktype blocktype=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from blocktype where blockTypeID=?";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {preparedStatement.setInt(1, blockTypeID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordblocktype=new Blocktype(rs.getInt("blockTypeID"),rs.getString("blockTypeName"),rs.getDouble("blockdiscount"),rs.getDouble("maxRecharge"),rs.getDouble("minRecharge"));}closeAll(conn,preparedStatement,rs);return blocktype;}}
11.5.2 consumptionDaoMySQLImpl(实现类)
package cn.block.dao.impl;import cn.block.dao.consumptionDao;
import cn.block.dao.BaseDao;import cn.block.entity.Consumption;import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class consumptionDaoMySQLImpl extends BaseDao implements consumptionDao {@Overridepublic int updateStaffIDbyStaffID(int staffID) {String sql="update consumption set staffID=1 where staffID=?;";Object [] objects={staffID};return update(sql, objects);}@Overridepublic List<Consumption> getAllConsumption() throws SQLException {List<Consumption> listConsumption = new ArrayList<Consumption>();Consumption consumption=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="SELECT consumptionID,user.userName,projecttype.projectTypeName,staff.staffName,consumption.consumptionBalance,consumption.userBalance,consumptionDatetime,user.userAccount,user.userPassword\\n" +"FROM consumption\\n" +"INNER JOIN `user` ON consumption.consumptionUserID=`user`.userID \\n" +"INNER JOIN projecttype ON consumption.consumptionProjectID=projecttype.projectTypeID \\n" +"INNER JOIN staff ON consumption.staffID=staff.staffID ;" ;try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordconsumption=new Consumption(rs.getInt("consumptionID"),0,0,0,rs.getDouble("consumption.consumptionBalance"),rs.getDouble("consumption.userBalance"),rs.getString("consumptionDatetime"),rs.getString("user.userName"),rs.getString("staff.staffName"),rs.getString("projecttype.projectTypeName"),rs.getString("userAccount"),rs.getString("userPassword"));listConsumption.add(consumption);}closeAll(conn,preparedStatement,rs);return listConsumption;}@Overridepublic List<Consumption> selectConsumptionByUserID(int UserID) {return null;}@Overridepublic int insertConsumption(Consumption consumption) {String sql="insert into consumption (consumptionUserID, consumptionProjectID, staffID, consumptionBalance,userBalance)\\n" +"values (?,?,?,?,?);";Object [] objects={consumption.getConsumptionUserId(),consumption.getConsumptionProjectId(),consumption.getStaffId(),consumption.getConsumptionBalance(),consumption.getUserBalance()};//打印发票int result=update(sql, objects);try {daYin(consumption);} catch (IOException e) {e.printStackTrace();System.out.println("出错了哦,宝宝");} catch (InterruptedException e) {e.printStackTrace();System.out.println("出错了哦,宝宝");}//使用 start() 方法启动线程return result;}//打印小票public void daYin(Consumption consumption1) throws IOException, InterruptedException {Consumption consumption=null;try {consumption=getMaxConsumptionByUserID(consumption1.getConsumptionUserId());} catch (SQLException e) {e.printStackTrace();System.out.println("出错了哦,宝宝");}String line="";String Name=consumption.getUserName();int ID=consumption.getConsumptionId();String Pin=Name+ ID+".txt";String fileName="D:\\\\BeiDaQingNiao\\\\S2\\\\MySQL_JDBC\\\\src\\\\cn\\\\block\\\\consumptionPiao\\\\"+Pin;String FileName=fileName.trim();File file=new File(FileName);Writer writer=null;try {writer=new FileWriter(file);} catch (IOException e) {e.printStackTrace();System.out.println("不好意思,出错了哦宝宝");}BufferedWriter bw=new BufferedWriter(writer);System.out.println(Name+":"+ID+":发票");line="消费用户:"+consumption.getUserName();System.out.println(line);bw.write(line);bw.newLine();line="消费项目:"+consumption.getProjectTypeName();System.out.println(line);bw.write(line);bw.newLine();line="服务员工:"+consumption.getStaffName();System.out.println(line);bw.write(line);bw.newLine();line="金额流水:"+consumption.getConsumptionBalance();System.out.println(line);bw.write(line);bw.newLine();line="账户余额:"+consumption.getUserBalance();System.out.println(line);bw.write(line);bw.newLine();line="消费时间:"+consumption.getConsumptionDatetime();System.out.println(line);bw.write(line);bw.flush();bw.close();}@Overridepublic List<Consumption> getConsumptionByUseraccountANDUserPassword(String userAccount, String userPassword) throws SQLException {List<Consumption> listConsumption=new ArrayList<Consumption>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="SELECT consumptionID,user.userName,projecttype.projectTypeName,staff.staffName,consumption.consumptionBalance,consumption.userBalance,consumptionDatetime,user.userAccount,user.userPassword\\n" +"FROM consumption\\n" +"INNER JOIN `user` ON consumption.consumptionUserID=`user`.userID \\n" +"INNER JOIN projecttype ON consumption.consumptionProjectID=projecttype.projectTypeID \\n" +"INNER JOIN staff ON consumption.staffID=staff.staffID \\n" +"WHERE user.userAccount=? AND user.userPassword=? ;";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setString(1,userAccount);preparedStatement.setString(2,userPassword);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while (rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordlistConsumption.add(new Consumption(rs.getInt("consumptionID"),0,0,0,rs.getDouble("consumption.consumptionBalance"),rs.getDouble("consumption.userBalance"),rs.getString("consumptionDatetime"),rs.getString("user.userName"),rs.getString("staff.staffName"),rs.getString("projecttype.projectTypeName"),rs.getString("userAccount"),rs.getString("userPassword")));}closeAll(conn,preparedStatement,rs);return listConsumption;}@Overridepublic Consumption getMaxConsumptionByUserID(int UserID) throws SQLException {Consumption consumption=new Consumption();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="SELECT consumptionID,user.userName,projecttype.projectTypeName,staff.staffName,consumption.consumptionBalance,consumption.userBalance,consumptionDatetime,user.userAccount,user.userPassword\\n" +"FROM consumption\\n" +"INNER JOIN `user` ON consumption.consumptionUserID=`user`.userID\\n" +"INNER JOIN projecttype ON consumption.consumptionProjectID=projecttype.projectTypeID\\n" +"INNER JOIN staff ON consumption.staffID=staff.staffID\\n" +"WHERE consumptionUserID=? AND consumptionDatetime=(SELECT MAX(consumptionDatetime) FROM consumption WHERE consumptionUserID=?);\\n";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {preparedStatement.setInt(1,UserID);preparedStatement.setInt(2,UserID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while (rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordconsumption=new Consumption(rs.getInt("consumptionID"),0,0,0,rs.getDouble("consumption.consumptionBalance"),rs.getDouble("consumption.userBalance"),rs.getString("consumptionDatetime"),rs.getString("user.userName"),rs.getString("staff.staffName"),rs.getString("projecttype.projectTypeName"),rs.getString("userAccount"),rs.getString("userPassword"));}closeAll(conn,preparedStatement,rs);return consumption;}
}
11.5.3 managerUserDaoMySQLImpl(实现类)
package cn.block.dao.impl;import cn.QiaoYun.dao.BaseDao;
import cn.block.dao.managerUserDao;
import cn.block.entity.Manageruser;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import static cn.block.dao.BaseDao.getConn;public class managerUserDaoMySQLImpl extends BaseDao implements managerUserDao {@Overridepublic Manageruser getmanagerUserInfoByManagerUserNameANDManagerPassword(String ManagerUserName, String ManagerPassword) throws SQLException {Manageruser manageruser=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from manageruser where ManagerUserName=? and ManagerPassword=? ";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setString(1, ManagerUserName);preparedStatement.setString(2, ManagerPassword);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordmanageruser =new Manageruser(rs.getInt("ManagerID"),rs.getString("ManagerUserName"),rs.getString("ManagerPassword"));}closeAll(conn,preparedStatement,rs);return manageruser;}
}
11.5.4 projectTypeDaoMySQLImpl(实现类)
package cn.block.dao.impl;import cn.block.dao.projectTypeDao;
import cn.block.dao.BaseDao;import cn.block.entity.Projecttype;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/ 项目类型表* */
public class projectTypeDaoMySQLImpl extends BaseDao implements projectTypeDao {@Overridepublic List<Projecttype> selectAllProjectTypes() throws SQLException {List<Projecttype> listProjectTypes=new ArrayList<Projecttype>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select projectTypeID,projectTypeName,projectTypePrice,staffTypeName from projecttype INNER JOIN stafftype ON projecttype.staffTypeID=stafftype.staffTypeID";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){Projecttype projectType=new Projecttype(rs.getInt("projectTypeID"),rs.getString("projectTypeName"),rs.getDouble("projectTypePrice"),rs.getInt("projectTypeID"),rs.getString("staffTypeName"));listProjectTypes.add(projectType);}closeAll(conn,preparedStatement,rs);return listProjectTypes;}public List<Projecttype> selectAliProjectTypes() throws SQLException {List<Projecttype> listProjectTypes=new ArrayList<Projecttype>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select projectTypeID,projectTypeName,projectTypePrice,staffTypeName from projecttype INNER JOIN stafftype ON projecttype.staffTypeID=stafftype.staffTypeID WHERE NOT projecttype.staffTypeID=1";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){Projecttype projectType=new Projecttype(rs.getInt("projectTypeID"),rs.getString("projectTypeName"),rs.getDouble("projectTypePrice"),rs.getInt("projectTypeID"),rs.getString("staffTypeName"));listProjectTypes.add(projectType);}closeAll(conn,preparedStatement,rs);return listProjectTypes;}@Overridepublic double getProjectTypePriceByprojectTypeID(int projectTypeID) throws SQLException {double i=0;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from projecttype where projectTypeID=?";try {preparedStatement=conn.prepareStatement(sql);preparedStatement.setInt(1,projectTypeID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){i=rs.getInt("projectTypePrice");}closeAll(conn,preparedStatement,rs);return i;}@Overridepublic int insertProjectType(Projecttype projectType) throws SQLException {String sql="insert into projecttype (projectTypeName, projectTypePrice, staffTypeID)\\n" +"values (?,?,?);";Object [] objects={projectType.getProjectTypeName(),projectType.getProjectTypePrice(),projectType.getStaffTypeId()};return update(sql, objects);}@Overridepublic Projecttype getProjectTypeByprojectTypeID(int projectTypeID) throws SQLException {Projecttype projecttype=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from projecttype where projectTypeID=?";try {preparedStatement=conn.prepareStatement(sql);preparedStatement.setInt(1,projectTypeID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){projecttype=new Projecttype(rs.getInt("projectTypeID"),rs.getString("projectTypeName"),rs.getDouble("projectTypePrice"),rs.getInt("staffTypeID"),"1");}closeAll(conn,preparedStatement,rs);return projecttype;}
}
11.5.5 staffDaoMySQLImpl(实现类)
package cn.block.dao.Impl;import cn.block.dao.staffDao;
import cn.block.dao.BaseDao;
import cn.block.entity.Staff;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class staffDaoMySQLImpl extends BaseDao implements staffDao {@Overridepublic List<Staff> selectAllStaff() throws SQLException {List<Staff> listStaffs=new ArrayList<Staff>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="SELECT staffID,staffName,stafftype.staffTypeID,staffTypeName from staff INNER JOIN stafftype ON staff.staffTypeID=stafftype.staffTypeID";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){Staff staff=new Staff(rs.getInt("staffID"),rs.getString("staffName"),rs.getInt(3),rs.getString("staffTypeName"));listStaffs.add(staff);}closeAll(conn,preparedStatement,rs);return listStaffs;}@Overridepublic Staff selectStaffByStaffID(int staffID) throws SQLException {Staff staff=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from staff where staffID=? ";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setInt(1, staffID);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPasswordstaff=new Staff(rs.getInt("staffID"),rs.getString("staffName"),rs.getInt("staffTypeID"),"");}closeAll(conn,preparedStatement,rs);return staff;}@Overridepublic int insertStaff(Staff staff) throws SQLException {String sql="insert into staff (staffName, staffTypeID)\\n" +"values (?,?);";Object [] objects={staff.getStaffName(),staff.getStaffTypeId()};return update(sql, objects);}@Overridepublic int deleteStaff(int staffID) throws SQLException {String sql="delete\\n" +"from staff\\n" +"where staffID=?;";Object [] objects={staffID};return update(sql, objects);}@Overridepublic int getStaffTypeIDByStaffID(int staffID) throws SQLException {int i=0;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select staffTypeID from staff where staffID=?";try {preparedStatement=conn.prepareStatement(sql);preparedStatement.setInt(1,staffID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){i=rs.getInt("staffTypeID");}closeAll(conn,preparedStatement,rs);return i;}
}
11.5.6 staffTypeDaoMySQLImpl (实现类)
package cn.block.dao.impl;import cn.block.dao.staffTypeDao;
import cn.block.dao.BaseDao;import cn.block.entity.Stafftype;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class staffTypeDaoMySQLImpl extends BaseDao implements staffTypeDao {@Overridepublic List<Stafftype> getAllStaffTypes() throws SQLException {List<Stafftype> listStafftype=new ArrayList<Stafftype>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from stafftype";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){Stafftype stafftype=new Stafftype(rs.getInt("staffTypeID"),rs.getString("staffTypeName"));listStafftype.add(stafftype);}closeAll(conn,preparedStatement,rs);return listStafftype;}@Overridepublic int insertStaffType(Stafftype staffType) throws SQLException {String sql="insert into stafftype (staffTypeName)\\n" +"values (?);";Object [] objects={staffType.getStaffTypeName()};return update(sql, objects);}@Overridepublic Stafftype getStaffTypeInfoByStaffTypeID(int staffTypeID) throws SQLException {Stafftype stafftype=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from stafftype where staffTypeID=?";try {preparedStatement=conn.prepareStatement(sql);preparedStatement.setInt(1,staffTypeID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){stafftype=new Stafftype(rs.getInt("staffTypeID"),rs.getString("staffTypeName"));}closeAll(conn,preparedStatement,rs);return stafftype;}
}
11.5.7 userblockDaoMySQLImpl(实现类)
package cn.block.dao.impl;import cn.block.dao.userblockDao;
import cn.block.dao.BaseDao;import cn.block.entity.Userblock;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class userblockDaoMySQLImpl extends BaseDao implements userblockDao {@Overridepublic int insertUserblock(Userblock userblock) {String sql="insert into userblock (userBlockStaffID, rechargeable, blockTypeID, userID)\\n" +"values (?,?,?,?);";Object [] objects={userblock.getUserBlockStaffId(),userblock.getRechargeable(),userblock.getBlockTypeId(),userblock.getUserId()};return update(sql, objects);}@Overridepublic int updateuserBlockStaffIDbyuserBlockStaffID(int staffID) {String sql="update userblock set userBlockStaffID=1 where userBlockStaffID=?;";Object [] objects={staffID};return update(sql, objects);}@Overridepublic int updateUserblockTyleIDByuserAccount(int blockTypeID,int userID) {String sql="update userblock\\n" +"set blockTypeID=? \\n" +"where userID=? ;";Object [] objects={blockTypeID,userID};return update(sql, objects);}@Overridepublic Userblock getUserblockInfoByUserID(int userID) throws SQLException {Userblock userblock=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from userblock where userID=?";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {preparedStatement.setInt(1, userID);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPassworduserblock=new Userblock(rs.getInt("userBlockID"),rs.getInt("userBlockStaffID"),rs.getDouble("rechargeable"),"",rs.getInt("blockTypeID"),rs.getInt("userID"),"");}closeAll(conn,preparedStatement,rs);return userblock;}
}
11.5.8 userDaoMySQLImpl(实现类)
package cn.block.dao.impl;import cn.block.dao.userDao;
import cn.block.dao.BaseDao;import cn.block.entity.User;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;/*
* 用户表的实现类
* */
public class userDaoMySQLImpl extends BaseDao implements userDao {@Overridepublic int insertUser(User user) throws SQLException {String sql="insert into block.user (userName, phone, userbalance,userAccount,userPassword) values (?,?,?,?,?);";Object [] objects={user.getUserName(), user.getPhone(), user.getUserbalance(),user.getUserAccount(),user.getUserPassword()};return update(sql, objects);}@Overridepublic int deleteUserbyUserID(int userID) throws SQLException {String sql="delete from block.user where userID=?;";Object [] objects={userID};return update(sql, objects);}@Overridepublic int updateUserNameByUserID(String userAccount, String userName) throws SQLException {String sql="update block.user set userName=? where userAccount=?;";Object [] objects={userName,userAccount};return update(sql, objects);}@Overridepublic int updateUserPhoneByUserID(String userAccount, String userPhone) {String sql="update block.user set phone=? where userAccount=?;";Object [] objects={userPhone,userAccount};return update(sql, objects);}@Overridepublic int updateUserbalanceByUserAccount(String userAccount, double userbalance) {String sql="update block.user set userbalance=? where userAccount=?;";Object [] objects={userbalance,userAccount};return update(sql, objects);}@Overridepublic List<User> getAllUser() throws SQLException {List<User> listUsers=new ArrayList<User>();PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from user";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}while(rs.next()){User user=new User(rs.getInt("userID"),rs.getString("userName"),rs.getString("phone"),rs.getDouble("userbalance"),rs.getString("userAccount"),rs.getString("userPassword"));listUsers.add(user);}closeAll(conn,preparedStatement,rs);return listUsers;}@Overridepublic double getUserBalanceByUserAccoount(String userAccount) throws SQLException {double userbalance=0;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select userbalance from user where userAccount=? ";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setString(1, userAccount);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPassworduserbalance=rs.getDouble("userbalance");}closeAll(conn,preparedStatement,rs);return userbalance;}@Overridepublic User getUserInfoByUserAccountANDUserPassword(String userAccount, String userPassword) throws SQLException {User user=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from user where userAccount=? and userPassword=? ";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setString(1, userAccount);preparedStatement.setString(2, userPassword);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPassworduser=new User(rs.getInt("userID"),rs.getString("userName"),rs.getString("phone"),rs.getDouble("userbalance"),rs.getString("userAccount"),rs.getString("userPassword"));}closeAll(conn,preparedStatement,rs);return user;}@Overridepublic User getUserInfoByUserAccount(String userAccount) throws SQLException {User user=null;PreparedStatement preparedStatement=null;ResultSet rs=null;Connection conn=getConn();String sql="select * from user where userAccount=?";try {preparedStatement=conn.prepareStatement(sql);} catch (SQLException e) {throw new RuntimeException(e);}preparedStatement.setString(1, userAccount);try {rs=preparedStatement.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}if(rs.next()){//consumptionDatetime, String userName, String staffName, String projectTypeName, String userAccount,String userPassworduser=new User(rs.getInt("userID"),rs.getString("userName"),rs.getString("phone"),rs.getDouble("userbalance"),rs.getString("userAccount"),rs.getString("userPassword"));}closeAll(conn,preparedStatement,rs);return user;}
}
11.6 Service 包(服务接口)
定义各种业务的方法
11.6.1 clientManagerService (接口)
负责服务客户的接口
package cn.block.service;import java.sql.SQLException;
/*
* 客户端
* */
public interface clientManagerService {//用户消费/ 查询所有的项目类型* 查询项目类型价格* 查询工作人员* 修改用户余额* 增加消费记录* */public void userConsume(String userAccount,String userPassword) throws SQLException;//用户登录系统,判断用户是否登录成功public boolean userLogin(String userAccount,String userPassword);//获取用户消费记录public void getUserConsumption(String userAccount,String userPassword);//查看用户信息(余额)public void getUserInfo(String userAccount,String userPassword);//查看所有类型卡的信息public void getAllBlockType();
}
11.6.2 ServiceManagerService(接口)
负责服务管理员的接口
package cn.block.service;import cn.block.entity.User;import java.sql.SQLException;
import java.util.List;/*
* 服务端
* */
public interface ServiceManagerService {//查看所有用户信息public void getAllUserInfo() throws SQLException;//添加用户 注册账号void register() throws SQLException;//根据用户账户 添加用户为会员用户void setUserBlockByUserAccount() throws SQLException;//查看所有员工void selectAllStaff() throws SQLException;//查看所有员工类型void selectAllStaffType() throws SQLException;//查询所有用户消费记录public void SelectAllUserConsumption();//充值业务public void updateUserbalance() throws SQLException;//升级用户会员等级public void updateUserBlock() throws SQLException;//增加项目public void insertProject() throws SQLException;//添加员工public void insertStaff() throws SQLException;//添加员工类型public void insertStaffType();//删除员工public void deleteStaff() throws SQLException;//管理员登录public boolean ManagerLogin(String ManagerUserName,String ManagerPassword);
}
11.7 Service 包下的 impl 包(服务实现类)
实现 Service 包中定义的接口,重新各种方法
通过调用各种 Dao 中的方法,来实现各种业务的完成
11.7.1 clientManagerServiceImpl (实现类)
提供给客户使用的类
package cn.block.service.Impl;import cn.block.dao.Impl.*;
import cn.block.dao.*;
import cn.block.entity.*;
import cn.block.service.clientManagerService;import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class clientManagerServiceImpl implements clientManagerService {Scanner input=new Scanner(System.in);blockTypeDao blockTypeDao=new blockTypeDaoMySQLImpl();consumptionDaoMySQLImpl consumptionDao=new consumptionDaoMySQLImpl();projectTypeDao projectTypeDao=new projectTypeDaoMySQLImpl();staffDao staffDao=new staffDaoMySQLImpl();staffTypeDao staffTypeDao=new staffTypeDaoMySQLImpl();userblockDao userblockDao=new userblockDaoMySQLImpl();userDaoMySQLImpl userDao=new userDaoMySQLImpl();/ 查询所有的项目类型* 查询项目类型价格* 查询工作人员* 修改用户余额* 增加消费记录*///用户消费@Overridepublic void userConsume(String userAccount,String userPassword) throws SQLException {//用户折扣double userDiscount=0;//用户原余额double userYuanBalance=0;//消费后的金额double userHouBalance=0;//项目类型IDint projectTypeID=0;//项目类型价格double projectTypePrice=0;//工作人员IDint choiceStaffID=0;//工作人员类型IDint staffTypeID=0;//用户名String userName="";//流水double LiuShui=0;//用户IDint userID=0;Projecttype projecttype=null;//存储集合List<Projecttype> listProjtcType=null;//通过账户密码获得用户IDUser user=userDao.getUserInfoByUserAccountANDUserPassword(userAccount,userPassword);userID=user.getUserId();userName=user.getUserName();System.out.println("项目编号ID\\t项目名称\\t\\t项目价格\\t项目员工类型");//查询所有项目类型try {listProjtcType=projectTypeDao.selectAliProjectTypes();for (Projecttype projecttype2 : listProjtcType) {System.out.println(projecttype2.getProjectTypeId()+"\\t\\t\\t"+projecttype2.getProjectTypeName()+"\\t\\t"+projecttype2.getProjectTypePrice()+"\\t"+projecttype2.getStaffTypeName());}} catch (SQLException e) {throw new RuntimeException(e);}System.out.print("请选择您要消费的项目编号:");try{projectTypeID=input.nextInt();}catch (Exception e){System.out.println("宝宝不要随便输入哦~");}//判断项目是否存在boolean iss=false;for(Projecttype p:listProjtcType){if(p.getProjectTypeId()==projectTypeID){iss=true;}}if(iss){//员工类型对象//判断输入的项目是否存在try {//获取项目价格Projecttype ppp=projectTypeDao.getProjectTypeByprojectTypeID(projectTypeID);projectTypePrice=ppp.getProjectTypePrice();//获取服务的工作人员类型idstaffTypeID=ppp.getStaffTypeId();} catch (Exception e) {e.printStackTrace();System.out.println("出错了哦宝宝");}//选择服务用户的工作人员System.out.println("工作人员编号\\t工作人员姓名\\t工作人员类型");for (Staff staff : staffDao.selectAllStaff()) {System.out.println(staff.getStaffId()+"\\t\\t"+staff.getStaffName()+"\\t\\t\\t"+staff.getStaffTypeName());}System.out.print("请选择服务的员工编号:");choiceStaffID=0;try{choiceStaffID=input.nextInt();}catch (Exception e){System.out.println("宝宝不要随便输入哦~");}//获取选择的工作人员的类型IDint choiceStaffTypeID=staffDao.getStaffTypeIDByStaffID(choiceStaffID);//判断是否有此员工if(choiceStaffTypeID<=0){System.out.println("选择失败,没有此员工");}else{//判断 如果选择的服务项目员工类型 与 选择工作人员的员工类型if(staffTypeID!=choiceStaffTypeID){System.out.println("选择失败");System.out.println("体验项目的员工类型与您选择服务人员的类型不匹配");}else{//获取用户原金额userYuanBalance=userDao.getUserBalanceByUserAccoount(userAccount);if(userYuanBalance<projectTypePrice){System.out.println("Sorry,您的余额不足");}else {//判断这个人是否有会员,进行打折Userblock userblock=userblockDao.getUserblockInfoByUserID(userID);if(userblock!=null){Blocktype blocktype=blockTypeDao.getBlockTypeByblockTypeID(userblock.getBlockTypeId());System.out.println("发现您的该用户是:"+blocktype.getBlockTypeName());System.out.println("折扣额度为"+(blocktype.getBlockdiscount()*100)+"折");projectTypePrice =projectTypePrice*blocktype.getBlockdiscount();LiuShui=0-projectTypePrice;System.out.println("实际消费为:"+projectTypePrice);userHouBalance=userYuanBalance-projectTypePrice;}else {LiuShui=0-projectTypePrice;userHouBalance=userYuanBalance-projectTypePrice;}//消费后的金额//修改用户的金额int a=userDao.updateUserbalanceByUserAccount(userAccount, userHouBalance);if(a>0){System.out.println("金额已扣除,本次消费"+projectTypePrice+"元");System.out.println("流水:"+LiuShui);}//增加消费记录int b=consumptionDao.insertConsumption(new Consumption(0,userID,projectTypeID,choiceStaffID,LiuShui,userHouBalance,"0","","","","",""));if(a>0){System.out.println("用户:"+userName+"已成功添加消费记录");}}}}}else {System.out.println("选择失败,没有此项目");}}//用户登录系统,判断用户是否登录成功public boolean userLogin(String userAccount,String userPassword){boolean result=false;User user=null;try {user=userDao.getUserInfoByUserAccountANDUserPassword(userAccount,userPassword);} catch (SQLException e) {System.out.println("宝宝出错了哦,不好意思奥!");e.printStackTrace();}if(user!=null){System.out.println("登录成功,欢迎你"+user.getUserName());result=true;}else{result=false;}return result;}//获取用户消费记录public void getUserConsumption(String userAccount,String userPassword){List<Consumption> listConsumption=new ArrayList<Consumption>();try {listConsumption=consumptionDao.getConsumptionByUseraccountANDUserPassword(userAccount,userPassword);} catch (SQLException e) {System.out.println("宝宝出错了哦,不好意思奥!");e.printStackTrace();}System.out.println("消费记录编号\\t消费用户\\t消费项目\\t服务员工\\t金额流水\\t\\t账户余额\\t消费时间");for (Consumption consumption : listConsumption) {System.out.println(consumption.getConsumptionId()+"\\t\\t\\t"+consumption.getUserName()+"\\t\\t"+consumption.getProjectTypeName()+"\\t"+consumption.getStaffName()+"\\t\\t"+consumption.getConsumptionBalance()+"\\t"+consumption.getUserBalance()+"\\t\\t"+consumption.getConsumptionDatetime());}}//获取用户信息@Overridepublic void getUserInfo(String userAccount, String userPassword) {//用户对象User user=null;//try {user=userDao.getUserInfoByUserAccountANDUserPassword(userAccount,userPassword);} catch (SQLException e) {System.out.println("宝宝出错了哦,不好意思奥!");e.printStackTrace();}System.out.println("用户编号\\t用户姓名\\t用户电话\\t用户余额");System.out.println(user.getUserId()+"\\t\\t"+user.getUserName()+"\\t\\t"+user.getPhone()+"\\t\\t"+user.getUserbalance());}@Overridepublic void getAllBlockType() {List<Blocktype> listBlockTypes = new ArrayList<Blocktype>();try {listBlockTypes=blockTypeDao.getAllBlockType();} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("会员卡编号\\t会员卡类型\\t会员卡打折额度\\t充值最大额度\\t充值最小额度");for (Blocktype blockType : listBlockTypes) {System.out.println(blockType.getBlockTypeId()+"\\t\\t\\t"+blockType.getBlockTypeName()+"\\t\\t"+blockType.getBlockdiscount()+"\\t\\t\\t"+blockType.getMaxRecharge()+"\\t\\t"+blockType.getMinRecharge());}}
}
11.7.2 ServiceManagerServiceImpl (实现类)
提供给管理员使用的类
package cn.block.service.Impl;import cn.block.dao.Impl.*;
import cn.block.dao.*;
import cn.block.entity.*;
import cn.block.service.ServiceManagerService;import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class ServiceManagerServiceImpl implements ServiceManagerService {managerUserDao managerUserDao=new managerUserDaoMySQLImpl();userDao userDao=new userDaoMySQLImpl();consumptionDao consumptionDao=new consumptionDaoMySQLImpl();userblockDao userblockDao=new userblockDaoMySQLImpl();blockTypeDao blockTypeDao=new blockTypeDaoMySQLImpl();Scanner input=new Scanner(System.in);staffDao staffDao=new staffDaoMySQLImpl();staffTypeDao staffTypeDao=new staffTypeDaoMySQLImpl();projectTypeDao projectTypeDao=new projectTypeDaoMySQLImpl();@Overridepublic void getAllUserInfo() throws SQLException {System.out.println("用户编号\\t用户姓名\\t用户电话\\t用户余额\\t用户账户\\t用户密码");for (User user : userDao.getAllUser()) {System.out.println(user.getUserId()+"\\t"+user.getUserName()+"\\t"+user.getPhone()+"\\t"+user.getUserbalance()+"\\t"+user.getUserAccount()+"\\t"+user.getUserPassword());}}@Override//用户注册public void register() throws SQLException {//流水double LiuShui=0;//卡类型对象Blocktype blockType1=null;//用户对象User user=null;//办卡员工IDint BlockStaffID=0;//用户首次充值金额double rechargeable=0;//卡类型IDint blockTypeID=0;//用户IDint userID=0;//余额double userbalance=0;String userPassword=null;System.out.print("请输入用户名:");String userName=input.next();System.out.print("请输入用户手机号:");String userPhone=input.next();System.out.print("请设置登录账号:");String userAccount=input.next();//判断账号是否重复try {user=userDao.getUserInfoByUserAccount(userAccount);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}//如果没有 则执行if(user==null){System.out.print("请设置登录密码:");userPassword=input.next();System.out.println("新人充值金额送会员");List<Blocktype> listBlockTypes = new ArrayList<Blocktype>();try {listBlockTypes=blockTypeDao.getAllBlockType();} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("会员卡编号\\t会员卡类型\\t会员卡打折额度\\t充值最大额度\\t充值最小额度");for (Blocktype blockType : listBlockTypes) {System.out.println(blockType.getBlockTypeId()+"\\t\\t\\t"+blockType.getBlockTypeName()+"\\t\\t"+blockType.getBlockdiscount()+"\\t\\t\\t"+blockType.getMaxRecharge()+"\\t\\t"+blockType.getMinRecharge());}System.out.print("是否需要充值(Y/N):");String isChongZhi=input.next();if(isChongZhi.equalsIgnoreCase("y")){System.out.print("请输入充值金额(最低200):");rechargeable=input.nextDouble();if(rechargeable<200){System.out.println("充值失败,金额最低200");}else {//根据充值金额 判断卡的类型try {blockType1=blockTypeDao.getBlockTypeIDByPrice(rechargeable);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("恭喜您,你获得了:"+blockType1.getBlockTypeName());blockTypeID=blockType1.getBlockTypeId();System.out.println("工作人员编号\\t工作人员姓名\\t工作人员类型");for (Staff staff : staffDao.selectAllStaff()) {System.out.println(staff.getStaffId()+"\\t\\t"+staff.getStaffName()+"\\t\\t\\t"+staff.getStaffTypeName());}System.out.print("请选择服务的员工编号:");BlockStaffID=0;try{BlockStaffID=input.nextInt();}catch (Exception e){System.out.println("宝宝不要随便输入哦~");}//获取选择的工作人员的类型IDint choiceStaffTypeID= 0;try {choiceStaffTypeID = staffDao.getStaffTypeIDByStaffID(BlockStaffID);} catch (SQLException e) {throw new RuntimeException(e);}//判断是否有此员工if(choiceStaffTypeID<=0){System.out.println("选择失败,没有此员工");}else{//添加用户信息int a=0;try {a=userDao.insertUser(new User(0,userName,userPhone,rechargeable,userAccount,userPassword));} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}if(a>0){System.out.println("用户注册成功");//获取用户I User user2=new User();System.out.println(userDao.getUserInfoByUserAccountANDUserPassword(userAccount, userPassword));//获取用户IDUser u1=userDao.getUserInfoByUserAccountANDUserPassword(userAccount, userPassword);int userID1=u1.getUserId();//添加会员信息int b=userblockDao.insertUserblock(new Userblock(0,BlockStaffID,rechargeable,"",blockTypeID,userID1,"0"));if(b>0){System.out.println("用户会员添加成功");//添加消费记录int c=consumptionDao.insertConsumption(new Consumption(0,userID1,5,BlockStaffID,rechargeable,rechargeable,"0","","","","",""));if(c>0){System.out.println("消费记录添加成功");}else {System.out.println("消费记录添加失败");}}else {System.out.println("用户会员添加失败");}}else {System.out.println("注册失败");}}}}else {}}else{System.out.println("已存在的用户,注册失败");}}//根据用户账户 添加用户为会员用户@Overridepublic void setUserBlockByUserAccount() throws SQLException {//流水double LiuSHui=0;//用户IDint userID=0;//办卡员工int BlockStaffID;//卡类型对象Blocktype blockType1=null;//卡IDint blockTypeID=0;//原余额double userYuanBalance=0;//充值后余额double userHouBalance=0;//用户对象User user=null;//用户第一次充值金额double rechargeable=0;System.out.print("请输入用户账户:");String userAccount=input.next();//判断是否有此用户try {user=userDao.getUserInfoByUserAccount(userAccount);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}if(user!=null) {//获取用户IDUser user2 = userDao.getUserInfoByUserAccount(userAccount);userID = user2.getUserId();//判断用户是否有会员Userblock Userblock=userblockDao.getUserblockInfoByUserID(userID);if(Userblock==null){List<Blocktype> listBlockTypes = new ArrayList<Blocktype>();try {listBlockTypes = blockTypeDao.getAllBlockType();} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("会员卡编号\\t会员卡类型\\t会员卡打折额度\\t充值最大额度\\t充值最小额度");for (Blocktype blockType : listBlockTypes) {System.out.println(blockType.getBlockTypeId() + "\\t\\t\\t" + blockType.getBlockTypeName() + "\\t\\t" + blockType.getBlockdiscount() + "\\t\\t\\t" + blockType.getMaxRecharge() + "\\t\\t" + blockType.getMinRecharge());}System.out.print("请输入充值金额(最低200):");rechargeable = input.nextDouble();if (rechargeable < 200) {System.out.println("充值失败,金额最低200");} else {//根据充值金额 判断卡的类型try {blockType1 = blockTypeDao.getBlockTypeIDByPrice(rechargeable);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("恭喜您,你获得了:" + blockType1.getBlockTypeName());blockTypeID = blockType1.getBlockTypeId();System.out.println("工作人员编号\\t工作人员姓名\\t工作人员类型");for (Staff staff : staffDao.selectAllStaff()) {System.out.println(staff.getStaffId() + "\\t\\t" + staff.getStaffName() + "\\t\\t\\t" + staff.getStaffTypeName());}System.out.print("请选择服务的员工编号:");BlockStaffID = 0;try {BlockStaffID = input.nextInt();} catch (Exception e) {System.out.println("宝宝不要随便输入哦~");}//获取选择的工作人员的类型IDint choiceStaffTypeID = 0;try {choiceStaffTypeID = staffDao.getStaffTypeIDByStaffID(BlockStaffID);} catch (SQLException e) {throw new RuntimeException(e);}//判断是否有此员工if (choiceStaffTypeID <= 0) {System.out.println("选择失败,没有此员工");} else {//添加会员信息int b = userblockDao.insertUserblock(new Userblock(0, BlockStaffID, rechargeable, "", blockTypeID, userID, "0"));if (b > 0) {System.out.println("用户会员添加成功");//添加消费记录int c = consumptionDao.insertConsumption(new Consumption(0, userID, 5, BlockStaffID, rechargeable, rechargeable, "0", "", "", "", "", ""));if (c > 0) {System.out.println("消费记录添加成功");//修改用户余额userYuanBalance=userDao.getUserBalanceByUserAccoount(userAccount);//消费后的金额userHouBalance=userYuanBalance+rechargeable;System.out.println(userHouBalance);//修改用户的金额int a=userDao.updateUserbalanceByUserAccount(userAccount, userHouBalance);if(a>0) {System.out.println("开通会员成功,账户余额" + userHouBalance + "元");}else {System.out.println("开通会员失败");}} else {System.out.println("消费记录添加失败");}} else {System.out.println("用户会员添加失败");}}}}else {System.out.println("用户"+user2.getUserName()+"已有会员卡");}}else {System.out.println("没有找到此用户");}}@Overridepublic void selectAllStaff() throws SQLException {System.out.println("员工编号\\t\\t员工姓名\\t员工类型");for (Staff staff : staffDao.selectAllStaff()) {System.out.println(staff.getStaffId()+"\\t"+staff.getStaffName()+"\\t"+staff.getStaffTypeName());}}@Overridepublic void selectAllStaffType() throws SQLException {System.out.println("员工类型编号\\t员工类型名称");for (Stafftype staffType : staffTypeDao.getAllStaffTypes()) {System.out.println(staffType.getStaffTypeId()+"\\t"+staffType.getStaffTypeName());}}//查询所有用户消费记录@Overridepublic void SelectAllUserConsumption() {List<Consumption> listConsumption=new ArrayList<Consumption>();try {listConsumption=consumptionDao.getAllConsumption();} catch (SQLException e) {System.out.println("宝宝出错了哦,不好意思奥!");e.printStackTrace();}System.out.println("消费记录编号\\t消费用户\\t消费项目\\t服务员工\\t金额流水\\t\\t账户余额\\t消费时间");for (Consumption consumption : listConsumption) {System.out.println(consumption.getConsumptionId()+"\\t\\t\\t"+consumption.getUserName()+"\\t\\t"+consumption.getProjectTypeName()+"\\t"+consumption.getStaffName()+"\\t\\t"+consumption.getConsumptionBalance()+"\\t"+consumption.getUserBalance()+"\\t\\t"+consumption.getConsumptionDatetime());}}@Overridepublic void updateUserbalance() throws SQLException {getAllUserInfo();//用户原余额double userYuanBalance=0;//用户充值后余额double userHouBanlance=0;//充值金额double chongZhi=0;//用户对象User user=null;System.out.print("请输入用户账户:");String userAccount=input.next();//判断是否有此用户try {user=userDao.getUserInfoByUserAccount(userAccount);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}if(user!=null) {System.out.print("请输入您要充值的金额:");try {chongZhi=input.nextDouble();}catch (Exception e){System.out.println("请输入正确金额");}//获取账户原余额try {userYuanBalance=userDao.getUserBalanceByUserAccoount(userAccount);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦");}//充值后余额userHouBanlance=userYuanBalance+chongZhi;//修改用户余额int a=userDao.updateUserbalanceByUserAccount(userAccount,userHouBanlance);if(a>0){System.out.println("用户:"+user.getUserName()+"充值成功,请及时查看");//增加消费记录int b=consumptionDao.insertConsumption(new Consumption(0,user.getUserId(),8,1,chongZhi,userHouBanlance,"0","","","","",""));if(b>0){System.out.println("消费记录添加成功");}else {System.out.println("消费记录添加失败");}}else {System.out.println("用户:"+user.getUserName()+"充值失败");}}}@Overridepublic void updateUserBlock() throws SQLException {//流水double LiuSHui=0;//会员卡对象Blocktype blocktype;//会员卡编号int BlockID=0;//用户IDint userID=0;//判断用户是否有会员Userblock Userblock= null;//用户对象User user=null;//用户的会员卡IDint userBlockID=0;//升级用户会员等级System.out.print("请输入用户账户:");String userAccount=input.next();//判断是否有此用户try {user=userDao.getUserInfoByUserAccount(userAccount);} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}if(user!=null) {//获取用户IDUser user2 = null;try {user2 = userDao.getUserInfoByUserAccount(userAccount);} catch (SQLException e) {throw new RuntimeException(e);}userID = user2.getUserId();try {Userblock = userblockDao.getUserblockInfoByUserID(userID);} catch (SQLException e) {throw new RuntimeException(e);}if(Userblock!=null){userBlockID=Userblock.getBlockTypeId();//获取用户的会员卡等级Blocktype blocktype1=blockTypeDao.getBlockTypeByblockTypeID(userBlockID);//用户会员卡的最小值Double userMin=blocktype1.getMinRecharge();//显示用户所要修改的会员等级List<Blocktype> listBlockTypes = new ArrayList<Blocktype>();try {listBlockTypes = blockTypeDao.getAllBlockType();} catch (SQLException e) {e.printStackTrace();System.out.println("宝宝出错了哦,不好意思奥!");}System.out.println("会员卡编号\\t会员卡类型\\t会员卡打折额度\\t充值最大额度\\t充值最小额度");for (Blocktype blockType : listBlockTypes) {System.out.println(blockType.getBlockTypeId() + "\\t\\t\\t" + blockType.getBlockTypeName() + "\\t\\t" + blockType.getBlockdiscount() + "\\t\\t\\t" + blockType.getMaxRecharge() + "\\t\\t" + blockType.getMinRecharge());}System.out.print("请选择要修改的会员卡编号(升级支付最小费用,降级不收费):");BlockID=input.nextInt();//判断是否选择了正确的blocktype= blockTypeDao.getBlockTypeByblockTypeID(BlockID);if(blocktype!=null) {//判断会员等级是否低级if(BlockID==blocktype1.getBlockTypeId()){System.out.println("您已经是"+blocktype1.getBlockTypeName()+",无需升级");}else {if(userMin>blocktype.getMaxRecharge()){System.out.println("你的会员卡"+blocktype1.getBlockTypeName()+"转换为"+blocktype.getBlockTypeName()+",高级转为低级,无需费用");int a=userblockDao.updateUserblockTyleIDByuserAccount(BlockID,userID);if(a>0){System.out.println("修改成功");}//获取原余额double userYuanBalance=userDao.getUserBalanceByUserAccoount(userAccount);int c = consumptionDao.insertConsumption(new Consumption(0, userID, 6, 1, 0, userYuanBalance, "0", "", "", "", "", ""));if(c>0){System.out.println("消费记录增加成功");}else {System.out.println("消费记录增加失败");}}else{System.out.println("你的会员卡"+blocktype1.getBlockTypeName()+"转换为"+blocktype.getBlockTypeName()+",低级卡转为高级卡,需要费用");double min=blocktype.getMinRecharge();System.out.println("支付费用"+min+"元");int b=userblockDao.updateUserblockTyleIDByuserAccount(BlockID,userID);if(b>0){System.out.println("修改成功,您以成功升级为"+blocktype.getBlockTypeName());//获取原余额double userYuanBalance=userDao.getUserBalanceByUserAccoount(userAccount);//消费后余额double userHouBalance=userYuanBalance+min;LiuSHui=0-min;//增加消费记录int c = consumptionDao.insertConsumption(new Consumption(0, userID, 6, 1, LiuSHui, userHouBalance, "0", "", "", "", "", ""));if(c>0){System.out.println("消费记录增加成功");//修改用户的金额int a=userDao.updateUserbalanceByUserAccount(userAccount, userHouBalance);if(a>0){System.out.println("金额已修改");}else {System.out.println("金额修改失败");}}else {System.out.println("消费记录增加失败");}}}}}else {System.out.println("没有此类型的卡哦");}}}else {System.out.println("此用户不存在");}}@Overridepublic void insertProject() throws SQLException {Scanner input=new Scanner(System.in);;System.out.print("请输入项目名称:");String projectName=input.nextLine();System.out.print("请输入项目价格:");double projectPrice=input.nextDouble();System.out.println("请选择项目的服务员工类型");System.out.println("员工类型编号\\t员工类型名称");for (Stafftype staffType : staffTypeDao.getAllStaffTypes()) {System.out.println(staffType.getStaffTypeId()+"\\t"+staffType.getStaffTypeName());}System.out.print("请输入您选择的员工类型编号:");int staffTypeID=input.nextInt();//判断是否存在Stafftype stafftype=staffTypeDao.getStaffTypeInfoByStaffTypeID(staffTypeID);if(stafftype==null){System.out.println("您选择的员工类型不存在哦");}else {try {int a=projectTypeDao.insertProjectType(new Projecttype(0,projectName,projectPrice,staffTypeID,""));if(a>0){System.out.println("服务项目添加成功");}else {System.out.println("服务项目添加失败");}} catch (SQLException e) {e.printStackTrace();System.out.println("出错了哦,宝宝");}}}@Overridepublic void insertStaff() throws SQLException {Scanner input=new Scanner(System.in);;System.out.print("请输入员工姓名:");String staffName=input.nextLine();System.out.println("请选择员工类型");System.out.println("员工类型编号\\t员工类型名称");for (Stafftype staffType : staffTypeDao.getAllStaffTypes()) {System.out.println(staffType.getStaffTypeId()+"\\t"+staffType.getStaffTypeName());}System.out.print("请输入您选择的员工类型编号:");int staffTypeID=input.nextInt();//判断是否存在Stafftype stafftype=staffTypeDao.getStaffTypeInfoByStaffTypeID(staffTypeID);if(stafftype==null){System.out.println("您选择的员工类型不存在哦");}else {//添加员工int a= staffDao.insertStaff(new Staff(0,staffName,staffTypeID,""));if(a>0){System.out.println("员工添加成功");}else {System.out.println("员工添加失败");}}}@Overridepublic void insertStaffType() {Scanner input=new Scanner(System.in);;System.out.print("请输入员工类型名称:");String staffTypeName=input.next();int a=0;try {a=staffTypeDao.insertStaffType(new Stafftype(0,staffTypeName));} catch (SQLException e) {e.printStackTrace();System.out.println("出错了哦,宝宝");}if(a>0){System.out.println("员工类型添加成功");}else {System.out.println("员工类型添加失败");}}@Overridepublic void deleteStaff() throws SQLException {System.out.println("工作人员编号\\t工作人员姓名\\t工作人员类型");for (Staff staff : staffDao.selectAllStaff()) {System.out.println(staff.getStaffId() + "\\t\\t" + staff.getStaffName() + "\\t\\t\\t" + staff.getStaffTypeName());}System.out.print("请选择要删除的员工编号:");int BlockStaffID = 0;try {BlockStaffID = input.nextInt();} catch (Exception e) {System.out.println("宝宝不要随便输入哦~");}//工作人员对象Staff staff = null;try {staff = staffDao.selectStaffByStaffID(BlockStaffID);} catch (SQLException e) {throw new RuntimeException(e);}//判断是否有此员工if (staff ==null) {System.out.println("选择失败,没有此员工");}else {//修改要删除的员工 的名下业务 全为老板的业务int a=consumptionDao.updateStaffIDbyStaffID(BlockStaffID);if(a>0){System.out.println("员工"+staff.getStaffName()+"名下消费记录业务已被删除");}else {System.out.println("删除员工"+staff.getStaffName()+"名下消费记录业务失败");}int b=userblockDao.updateuserBlockStaffIDbyuserBlockStaffID(BlockStaffID);if(a>0){System.out.println("员工"+staff.getStaffName()+"名下办卡业务已被删除");}else {System.out.println("删除员工"+staff.getStaffName()+"名下办卡业务失败");}//执行删除int c=staffDao.deleteStaff(BlockStaffID);if(c>0){System.out.println("员工"+staff.getStaffName()+"成功删除");}else {System.out.println("员工"+staff.getStaffName()+"删除失败");}}}@Overridepublic boolean ManagerLogin(String ManagerUserName, String ManagerPassword) {boolean result=false;Manageruser manageruser=null;try {manageruser=managerUserDao.getmanagerUserInfoByManagerUserNameANDManagerPassword(ManagerUserName,ManagerPassword);} catch (SQLException e) {System.out.println("宝宝出错了哦,不好意思奥!");e.printStackTrace();}if(manageruser!=null){System.out.println("管理员登录成功"+manageruser.getManagerUserName());result=true;}else{result=false;}return result;}
}
11.8 Main 方法
通过在 Main 方法中调用各种服务类,来完成项目的各种需求
11.8.1 MainBlock (主方法类)
import cn.block.service.Impl.ServiceManagerServiceImpl;
import cn.block.service.Impl.clientManagerServiceImpl;
import cn.block.service.ServiceManagerService;
import cn.block.service.clientManagerService;import java.sql.SQLException;
import java.util.Scanner;public class MainBlock {static String userAccount;static String userPassword;static String ManagerUserName;static String ManagerPassword;static clientManagerService cm=new clientManagerServiceImpl();static ServiceManagerService sms=new ServiceManagerServiceImpl();public static void main(String[] args) throws SQLException {Scanner input=new Scanner(System.in);System.out.println("1.客户登录");System.out.println("2.管理员登录");System.out.println("3.注册客户登录账户");System.out.print("请选择登录身份:");String choice=input.next();switch (choice){case "1":System.out.print("请输入用户账户:");userAccount=input.next();System.out.print("请输入用户密码:");userPassword=input.next();//判断是否登录成功boolean isUserLogin=cm.userLogin(userAccount,userPassword);if(isUserLogin){System.out.println("欢迎进入客户端服务:");boolean tiao=false;String iss="Y";while(iss.equalsIgnoreCase("y")){System.out.println("1.消费业务");System.out.println("2.查看自己的消费记录");System.out.println("3.查看自己的信息(余额)");System.out.println("4.查看不同会员卡的信息");System.out.println("5.退出登录");System.out.print("请选择执行项目:");String isUserChoice=input.next();switch (isUserChoice){case "1"://执行消费业务cm.userConsume(userAccount,userPassword);break;case "2"://查看自己的消费记录cm.getUserConsumption(userAccount,userPassword);break;case "3"://查看自己信息(余额)cm.getUserInfo(userAccount,userPassword);break;case "4"://查看不同会员卡的信息cm.getAllBlockType();break;case "5":System.out.println("谢谢使用");tiao=true;break;default:System.out.println("没有此选项");break;}if(tiao){break;}System.out.println("是否继续(Y/N)");iss=input.next();}}else {System.out.println("用户名、密码错误或不存在,登录失败");}break;case "2":System.out.print("请输入管理员账户:");ManagerUserName=input.next();System.out.print("请输入管理员密码:");ManagerPassword=input.next();//判断是否登录成功boolean isManagerLogin= sms.ManagerLogin(ManagerUserName,ManagerPassword);if(isManagerLogin){System.out.println("欢迎进入管理员服务:");boolean tiao=false;String iss="Y";while(iss.equalsIgnoreCase("y")){System.out.println("1.查看所有用户信息");System.out.println("2.注册用户账户");System.out.println("3.升级会员用户");System.out.println("4.查看所有用户消费记录");System.out.println("5.用户充值业务");System.out.println("6.增加服务项目");System.out.println("7.添加新会员用户");System.out.println("8.查看所有员工");System.out.println("9.查看所有员工类型");System.out.println("10.添加员工");System.out.println("11.添加员工类型");System.out.println("12.删除员工");System.out.println("退出登录");System.out.print("请选择执行项目:");String isUserChoice=input.next();switch (isUserChoice){case "1"://查看所有用户信息sms.getAllUserInfo();break;case "2"://注册用户账户sms.register();break;case "3"://添加会员用户sms.updateUserBlock();break;case "4"://查看所有用户消费记录sms.SelectAllUserConsumption();break;case "5"://用户充值业务sms.updateUserbalance();break;case "6"://增加服务项目sms.insertProject();break;case "7"://添加新会员用户 setUserBlockByUserAccountsms.setUserBlockByUserAccount();break;case "8"://查看所有员工sms.selectAllStaff();break;case "9"://查看所有员工类型sms.selectAllStaffType();break;case "10"://添加员工sms.insertStaff();break;case "11"://添加员工类型sms.insertStaffType();break;case "12"://删除员工sms.deleteStaff();break;default:tiao=true;System.out.println("没有此选项");break;}if(tiao){break;}System.out.println("是否继续(Y/N)");iss=input.next();}}else {System.out.println("用户名、密码错误或不存在,登录失败");}break;case "3":sms.register();break;default:System.out.println("没有此选项");break;}}
}System.out.println("1.消费业务");System.out.println("2.查看自己的消费记录");System.out.println("3.查看自己的信息(余额)");System.out.println("4.查看不同会员卡的信息");System.out.println("5.退出登录");System.out.print("请选择执行项目:");String isUserChoice=input.next();switch (isUserChoice){case "1"://执行消费业务cm.userConsume(userAccount,userPassword);break;case "2"://查看自己的消费记录cm.getUserConsumption(userAccount,userPassword);break;case "3"://查看自己信息(余额)cm.getUserInfo(userAccount,userPassword);break;case "4"://查看不同会员卡的信息cm.getAllBlockType();break;case "5":System.out.println("谢谢使用");tiao=true;break;default:System.out.println("没有此选项");break;}if(tiao){break;}System.out.println("是否继续(Y/N)");iss=input.next();}}else {System.out.println("用户名、密码错误或不存在,登录失败");}break;case "2":System.out.print("请输入管理员账户:");ManagerUserName=input.next();System.out.print("请输入管理员密码:");ManagerPassword=input.next();//判断是否登录成功boolean isManagerLogin= sms.ManagerLogin(ManagerUserName,ManagerPassword);if(isManagerLogin){System.out.println("欢迎进入管理员服务:");boolean tiao=false;String iss="Y";while(iss.equalsIgnoreCase("y")){System.out.println("1.查看所有用户信息");System.out.println("2.注册用户账户");System.out.println("3.升级会员用户");System.out.println("4.查看所有用户消费记录");System.out.println("5.用户充值业务");System.out.println("6.增加服务项目");System.out.println("7.添加新会员用户");System.out.println("8.查看所有员工");System.out.println("9.查看所有员工类型");System.out.println("10.添加员工");System.out.println("11.添加员工类型");System.out.println("12.删除员工");System.out.println("退出登录");System.out.print("请选择执行项目:");String isUserChoice=input.next();switch (isUserChoice){case "1"://查看所有用户信息sms.getAllUserInfo();break;case "2"://注册用户账户sms.register();break;case "3"://添加会员用户sms.updateUserBlock();break;case "4"://查看所有用户消费记录sms.SelectAllUserConsumption();break;case "5"://用户充值业务sms.updateUserbalance();break;case "6"://增加服务项目sms.insertProject();break;case "7"://添加新会员用户 setUserBlockByUserAccountsms.setUserBlockByUserAccount();break;case "8"://查看所有员工sms.selectAllStaff();break;case "9"://查看所有员工类型sms.selectAllStaffType();break;case "10"://添加员工sms.insertStaff();break;case "11"://添加员工类型sms.insertStaffType();break;case "12"://删除员工sms.deleteStaff();break;default:tiao=true;System.out.println("没有此选项");break;}if(tiao){break;}System.out.println("是否继续(Y/N)");iss=input.next();}}else {System.out.println("用户名、密码错误或不存在,登录失败");}break;case "3":sms.register();break;default:System.out.println("没有此选项");break;}}
}


