文章目录
数据库的学习以及JDBC的基础知识
主要用到MySQL、sqlyog图形化工具、idae、以及一些jar包,初步了解了MySQL的增删改查(CRUD)等。
数据库的学习
一. 数据库的基本概念
-
1 数据库的英文单词:Database 简称:DB
1.2 什么是数据库?
- 用于存储和管理数据库的仓库。
1.3 数据库的特点:
- 持久化存储数据的。其实数据库就是一个文件系统
- 方便存储和管理数据
- 使用了统一的方式操作数据库 —— SQL
二. MySQL数据库软件
-
安装
-
卸载
-
- 去mysql的安装目录找到 my.ini 文件
- 复制 datadir = “C:\ProgramData\MySQL\MySQL Server 5.5\data”
-
- 卸载MySQL
-
- 删除C:\ProgramData目录下的MySQL文件夹
- 配置
** MySQL服务启动
-
- 手动
-
- cmd --> services.msc 打开服务的窗口
-
- 使用管理员打开cmd
- net start mysql : 启动MySQL的服务
- net stop mysql : 关闭MySQL服务
** MySQL登录
-
- mysql -uroot -p 密码
-
- mysql -hip -uroot -p 连接目标的密码
-
- mysql --host=ip --user=root --passworld=连接目标的密码
** MySQL退出
-
- exit
-
- quit
** MySQL目录结构
-
- MySQL的安装目录
- 配置文件 my.ini
- MySQL的安装目录
-
-
MySQL的数据目录
几个概念:
- 数据库:文件夹
- 表:文件
- 数据:数据
-
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-87WLEI0p-1573824169845)(C:\Users\Think-Pad\Desktop\数据库\MySQL目录结构.jpg)]
SQL
2.1. 什么是SQL?
Structured Query Language : 结构化查询语言
其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在币一样的地方,称为“方言”。
2.2. SQL通用语法
- SQL语句可以使用单行或多行书写,以分号结尾
- 可使用空格和缩进进行增强语句的可读性
- MySQL 数据库的 SQL 语句不区分大小写,关键字建议使用小写
- 3 种注释
- 单行注释:-- 注释内容 或 # 注释内容(MySQL 特有)
- 多行注释:/* 注释 */
三. SQL分类
1) DDL(Data Definition Language)数据库定义语言
用来定义数据库对象:数据库,表,列等。关键字:create,drop,alter等
2) DML(Data Mainplution Language)数据库操作语言
用来对数据库中的表的数据进行增删改。关键字:insert,delete,update等
3) DQL(Data Query Language)数据查询语言
用来查询数据库中的表的记录(数据)。关键字:select,where等
4) DCL(Data Control Language)数据控制语言(了解)
用来定义数据库的访问权限和安全级别,及创建用户。关键字:GRANT, REMOVE等
3.1 DDL:操作数据库、表
一、 操作数据库
-
C(Create):创建
-
创建数据库:
- create database 数据库名称;
-
创建数据库,判断不存在,再创建:
- create database if not exists 数据库名称;
-
创建数据库,并指定字符集
- create database 数据库名称 character set 字符集名;
-
练习: 创建db4数据库,判断是否存在,并制定字符集为gbk
- create database if not exists db4 character set gbk;
- R(Retrieve) : 查询
-
* 查询所有数据库的名称:
* show databases;
* 查询某个数据库的字符集:查询某个数据库的创建语句
* show create database 数据库名称;
3. U(Update) : 修改
* 修改数据库的字符集
* alter database 数据库名称 character set 字符集名称;
4. D(Delete): 删除
* 删除数据库
* drop database 数据库名称;
* 判断数据库存在,存在再删除
* drop database if exists 数据库名称;
5. 使用数据库
* 查询当前正在使用的数据库名称
* select database();
* 使用数据库
* use 数据库名称;
二、 操作表
-
C(Create):创建
-
语法:
create table 表名(
列名1 数据类型1,
列名2 数据类型2,
。。。
列名n 数据类型n
);
-
注意:最后一列,不需要加逗号(,)
-
数据库类型:
-
int :整数类型
- age int,
-
double : 小数类型
- score double(5,2)
-
date : 日期,只包含年月日,yyyy - MM -dd
-
datatime : 日期,包含年月日时分秒 yyyy -MM -dd
-
timestamp : 时间错类型 包含年月日时分秒 yyyy - MM - dd
HH:mm:ss
- 如果将来不给这个字段赋值,或赋值为null,则默认使用当前的系统时间,来自动赋值
-
varchar : 字符串
- name varchar(20) : 姓名最大20个字符
- zhangsan 8个字符 张三 2个字符
-
-
创建表
-
create table student(
id int,
name varchar(32),
age int ,
score double(4,1),
birthday date,
insert_time timestamp
);
-
-
复制表 :
- create table 表名 like 被复制的表名;
-
-
-
R(Retrieve) : 查询
- 查询某个数据库中的所有的表的名称
- show tables;
- 查询表结构
- desc 表名;
- 查询某个数据库中的所有的表的名称
-
U(Update) : 修改
- 修改表名
- alter table 表名 rename to 新的表名;
- 修改表的字符集
- alter table 表名 character set 字符集名称;
- 添加一列
- alter table 表名 add 列名 数据类型;
- 修改列名称 类型
- alter table 表名 change 列名 新列名 数据类型;
- alter table 表名 modify 列名 新数据类型;
- 删除列
- alter table 表名 drop 列名;
- 修改表名
-
D(Delete): 删除
- drop table 表名;
- drop table if exists 表名;
客户端图形化工具:SQLYog
3.2 DML:增删改表中数据
-
添加数据:
-
语法:
- insert into 表名(列名1,列名2,…列名n) values (值1,值2,…值n);
-
注意:
-
列名和值要一一对应。
-
如果列名后,不定义列名,则默认给所有列添加值
insert into 表名 values(值1,值2,…值n);
-
除了数字类型,其他类型需要使用引号(单双都可以)引起来
-
-
删除数据:
- 语法:
- delete from 表名 [where 条件]
- 注意:
- 如果不加条件,则删除表中所有记录。
- 如果要删除所有记录
- deletet from 表名; – 不推荐使用。有多少条记录就会执行多少次删除操作
- truncate table 表名; – 推荐使用,效率更高 先删除表,然后再创建一张一样的表。
- 语法:
-
修改数据:
- 语法:
- update 表名 set 列名1 = 值1,列名2 = 值2, … [where 条件];
- 注意:
- 如果不加任何条件,则会将表中所有记录全部修改。
- 语法:
-
3.3 DQL : 查询表中的记录(查询语句)
-
select * from 表名;
-
语法:
-
select
字段列表
from
表名列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页限定
-
-
基础查询
-
多个字段的查询
select 字段名1,字段名2…from 表名;
注意:
如果查询所有字段,则可以使用 * 来代字段列表。
-
去除重复:
distinct
– select distinct 列名 from 表名;
-
计算列
一般可以使用四则运算计算一些列的值。(一般只会进行值型的计算)
ifnull (表达式1,表达式2) :null 参与的运算,计算结果都为null
表达式1 :哪个字段需要判断是否为null
表达式2 :如果该字段为null后的替换值
-
起别名:
as : as 也可以省略
- select 列名1,列名2 +ifnull(列名,0) as 总分 from 表名;
- 排序查询
- 语法: order by 子句
- order by 排序字段1 排序方式1, 排序字段2 排序方式2…
- 排序方式:
- ASC : 升序,默认的
- DESC : 降序
- 注意 :
- 如果有多个排序条件,则当前边的条件值一样时,才会判断第二种条件
-
-
select * from 表名 order by 列名 ASC;
- 聚合函数 :将一列数据作为一个整体,进行纵向的计算。
- count : 计算个数
- 一般选择非空的列 :主键
- max : 计算最大值
- min :计算最小值
- sum : 计算和
- avg : 计算平均值
-
select count(列名) from 表名;
-
注意:聚合函数的计算,排除null值
解决方案:
- 选择非空的列进行计算
- IFNULL函数
-
分组查询
- 语法 : group by 分组字段;
- 注意:
- 分组之后查询的字段:分组字段 、聚合函数
- where 和 having 的区别?
- where 在分组之前进行限定,如果不满足条件,则不参与分组。having 在分组之后进行限定,如果不满足结果,则不会被查询出来。
- where 后不可能跟聚合函数,having 可以进行聚合函数的判断。
- select 分组列名, AVG(列名) from 表名 group by 分组列名;
-
分页查询
- 语法:limit 开始的索引,每页查询的条数;
- 公式:开始的索引 = (当前的页码 - 1 )* 每页显示的条数
- 每页显示3条记录
- select * from 表名 limit 0,3; --第1页
- select * from 表名 limit 3,3; --第2页
- select * from 表名 limit 6,3; --第3页
- limit 是一个MySQL“方言”
5. 条件查询
- where子句后跟条件
- 运算符
- < 、>、<= 、>= 、= 、<>
- between…and
- in(集合)
- like :模糊查询
- 占位符:
- _ : 单个任意字符
- % :多个任意字符
- 占位符:
- is null
- and 或 &&
- or 或 ||
- not 或 !
-
– 查询年龄大于20岁
select * from student where age > 20;
-
– 查询年龄不大于20岁
select * from student where age != 20;
select * from student where age <> 20;
-
– 查询年龄大于等于20岁 小于等于30
select * from student where age >= 20 && age <= 30;
select * from student where age >= 20 and age <= 30;
select * from student where between 20 and 30;
-
– 查询年龄 22岁, 18岁, 25岁的信息
select * from student where age = 22 or age = 18 or age = 25;
select * from student where age in(22,18,15);
-
– 查询英语成绩为null
select * from student where english = null; – 不对的。
null 不能使用 = (!=) 判断
select * from student where english is null;
– 查询英语成绩不为null
select * from student where english is not null;
– 查询姓马的有哪些? like
select * from student where name like ‘马%’;
– 查询第二个字是化的人
select * from student where name like ‘_化%’;
– 查询姓名是3个字的人
select * from student where name like ‘___’;
– 查询姓名中包含德的人
select * from student where name like ‘%德%’;
3.4 DCL :管理用户,授权
-
DBA:数据库管理员
-
DCL:管理用户,授权
-
添加用户:
- 语法:creat user ‘用户名’@‘主机名’ indentified by ‘密码’;
-
删除用户:
- 语法:drop user ‘用户名’@‘主机名’;
-
修改用户密码:
update user set password = password(‘新密码’) where user = (‘用户名’);
set password for ‘用户名’@‘主机名’ = password(‘新密码’);
- mysql 中忘记了root用户的密码?
- cmd --> net stop mysql 停止MySQL服务
- 需要管理员运行该cmd
- 使用无验证方式启动MySQL服务:MySQL --skip-grant-tables
- 打开新的cmd窗口,直接输入MySQL命令,敲回车键。就可以登录成功
- use mysql;
- update user set password = (‘你的新密码’) where user = ‘root’;
- 关闭两个窗口
- 打开任务管理器,手动结束mysql.exe 的进程
- 启动MySQL服务
- 使用新密码登录
- cmd --> net stop mysql 停止MySQL服务
- mysql 中忘记了root用户的密码?
-
查询用户:
– 1. 切换到MySQL数据库
use mysql;.
– 2. 查询user表
select * from user;
-
-
权限管理:
- 通配符:% 表示可以在任意主机使用用户登录
-
查询权限:
– 查询权限:
show grants for ‘用户名’@‘主机名’;
-
授予权限:
– 授予权限
grant 权限列表 on 数据库名,表名 to ‘用户名’@‘主机名’;
– 给张三用户授予所有权限,在任意数据库任意表上
grant all on * . * to ‘zhangsan’@‘localhost’;
-
撤销权限:
– 撤销权限:
revoke 权限列表 on 数据库名,表名 from ‘用户名’@‘主机名’;
四、约束
4.1 概念:对表中的数据进行限定,保证数据的正确性、有效性和完整性。
4.2 分类:
- 主键约束:primary ley
- 非空约束: not null
- 唯一约束: unique
- 外键约束: foreign key
4.3 非空约束: not null
-
创建表时添加约束
creat table stu(
id int,
name varchar(20) not null ; – name为非空
);
-
创建表完后,添加非空约束
alter table stu modify name varchar(20) not null;
-
删除name的非空约束
alter table stu modify name varchar(20);
4.4 唯一约束: unique,值不能重复
-
CREATE TABLE stu(
id INT,
phone_number VARCHAR(20) UNIQUE – 添加了唯一约束
);
– 注意MySQL中,唯一约束限定的列的值可以有多个null -
– 删除唯一约束
ALTER TABLE stu MODIFY phone_number VARCHAR(20); -
– 在创建表后,添加唯一约束
alter table stu modify phone_number varchar(20) unique;
4.5 主键约束 : primary key
-
注意:
- 含义:非空且唯一
- 一张表只能有一个字段为主键
3. 主键就是表中记录的唯一标识
-
在创建表时,添加主键约束
CREATE TABLE stu(
id INT PRIMARY KEY, – 给id添加主键约束
NAME VARCHAR(20)
);– 删除主键
– 错误 alter table stu modify id int;
ALTER TABLE stu DROP PRIMARY KEY;– 创建完表后,添加主键
ALTER TABLE stu MODIFY id INT PRIMARY KEY; -
主键约束——自动增长
CREATE TABLE stu (
id INT PRIMARY KEY AUTO_INCREMENT, – 给id添加主键约束
NAME VARCHAR(20)
);INSERT INTO stu VALUES(NULL,‘fff’);
– 删除自动增长
ALTER TABLE stu MODIFY id INT;
– 添加自动增长
ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;4.6 外键约束:foreign key ,让表与表产生关系,从而保证数据的正确性。
-
在创建表时,可以添加外键
语法:
create table 表名(
…
外键列
constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称)
);
-
删除外键
alter table 表名 drop foreign key 外键名称;
-
创建表之后,添加外键
alter table 表名 add constraint 外键名称 foreign key(外键列名称) references 主表名称(主表列名称);
-
级联操作
-
添加级联操作
语法:
alter table 表名 add constraint 外键名称 foreign key(外键字段名称) references 主表名称(主列表名称) on update on delete cascade;
-
分类:
级联更新:on update cascade
级联删除:on delete cascade
-
-
-
五、 数据库的设计
5.1 多表之间的关系
-
分类:
-
一对一(了解):
- 如:人和身份证
- 分析:一个人只有一个身份证,一个身份证只能对应一个人
- 一对多(多对一):
- 如:部门和员工
- 分析:一个部门有多个员工,一个员工只能对应一个部门
3. 多对多: - 如:学生和课程
- 分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
-
-
实现关系:
- 一对多(多对一):
- 如:部门和员工
- 实现方式:在多的一方建立外键,指向一的一方的主键。
- 多对多:
- 如:学生和课程
- 实现方式:多对多关系需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键。
- 一对一(了解):
- 如:人和身份证
- 实现方式:一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。
- 一对多(多对一):
5.2 数据库设计的范式
-
概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求。
- 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式,数据库冗余越小。
- 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称为完美范式)。
-
分类:
-
第一范式(1NF):每一列都是不可分割的原子数据项
-
第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
-
几个概念:
-
函数依赖:A–> B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
例如:学号–>姓名。(学号,课程名称)–>分数
-
完全函数依赖:A–>B,如果A是一个属性组,则B属性值的确认需要依赖于A属性组中所有的属性值。
例如:(学号,课程名称)–>分数
-
部分函数依赖:A–>B,如果A是一个属性组,则B属性值的确认只需要依赖于A属性组中某一些值即可。
例如:(学号,课程名称)–>姓名
-
传递函数依赖:A–>B,B–>C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性值)的值可以确定唯一C属性的值,则称C传递函数依赖以A
例如:学号–>系名,系名–>系主任
-
码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则这个属性(属性组)为该表的码。
例如:该表中码为:(学号,课程名称)
- 主属性:码属性组中的所有属性
- 非主属性:除过马属性组的属性
-
-
-
第三范式(3NF):在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)
-
5.3 数据库的备份与还原
- 语法:
- 备份:mysqldump -u用户名 -p密码 > 保存的路径
- 还原:
- 登录数据库
- 创建数据库
- 使用数据库
- 执行文件。source文件路径
六、 多表查询:
6.1 查询语法:
select
列名列表
from
表名列表
where...
6.2 笛卡尔积:
- 有两个集合A,B 取这两个集合的所有组成情况。
- 要完成多表查询,需要消除无用的数据
6.3 多表查询的分类
-
内连接查询:
-
隐式内连接:使用where条件消除无用数据
例子:
– 查询所有员工信息和对应的部门信息
select * from emp,dept where emp.‘dept_id’ = dept.‘id’;
-
显示内连接:
语法:select 字段列表 from 表名1 [inner] join 表名2 on 条件
select * from emp inner join dept on emp.‘dept_id’ = dept.‘id’;
select * from emp join dept on emp.‘dept_id’ = dept.‘id’;
-
-
外连接查询:
- 左外连接:
- 语法: select 字段列表 from 表1 left [outer] join 表2 on 条件;
- 查询的是左表所有数据以及其交集部分。
- 右外连接:
- 语法:select 字段列表 from 表1 right [outer] join 表2 on 条件;
- 查询的是右表所有数据以及其交集部分。
- 左外连接:
-
子查询:
-
概念:查询中嵌套查询,称嵌套查询为子查询。
– 查询工资最高的员工信息
– 1. 查询最高的工资是多少? 9000
select max(salary) from emp;– 2. 查询员工信息,并且工资等于9000的
select * from emp where emp.salary = 9000;– 一条SQL就完成这个操作。子查询
select * from emp where emp.salary = (select max(salary) from emp); -
子查询不同情况
-
子查询的结果是单行单列的:
- 子查询可以作为条件,使用运算符去判断。运算符: > >= < <= =
- – 查询员工工资小于平均工资的人
select * from emp where emp.salary < (select avg(salary) from emp);
-
子查询的结果是多行单列的:
-
子查询可以作为条件,使用运算符in来判断
-
– 查询‘财务部’和‘市场部’所有的员工信息
SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’;
SELECT * FROM emp WHERE dept_id = 3 OR dept_id = 2;SELECT * FROM emp WHERE dept_id IN(SELECT id FROM dept WHERE NAME = ‘财务部’ OR NAME = ‘市场部’);
-
-
子查询的结果是多行多列的:
-
子查询可以作为一张虚拟表参与查询
– 查询员工入职日期是2011-11-11日之后的员工信息和部门信息
– 子查询
SELECT * FROM dept t1,(SELECT * FROM emp WHERE emp.join_date > ‘2011-11-11’)
t2 WHERE t1.id = t2.id;– 普通内连接
SELECT * FROM emp t1,dept t2 WHERE t1.dept_id = t2.id AND t1.join_date > ‘2011-11-11’;
-
-
-
七、 事务
7.1. 事务的基本介绍:
-
概念:
- 如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
-
操作:
-
开启事务:start transaction;
-
回滚:rollback;
-
提交:commit;
-
MySQL数据库中事务默认自动提交
-
事务提交的两种方式:
-
自动提交:
- MySQL就是自动提交的
- 一条DML(增删改)语句会自动提交一次事务。
-
手动提交:
- Oracle 数据库默认是手动提交事务
- 需要先开启事务,再提交
-
修改事务的默认提交方式:
-
查看事务的默认提交方式:
select @@autocommit; – 1 代表自动提交, 0 代表手动提交
-
修改默认提交方式:set @@autocommit = 0;
-
-
-
-
7.2 事务的四大特征:
- 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
- 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
- 隔离性:多个事务之间,相互独立
- 一致性:当事务操作前后,数据总量不变
7.3 事务的隔离级别(了解)
-
概念:多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
-
存在问题:
- 脏读:一个事务,读取到另一个事务中没有提交的数据
- 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
- 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
-
隔离级别:
- read uncommitted : 读未提交
- 产生问题:脏读、不可重复读、幻读
- read committed: 读已提交(Oracle)
- 产生的问题:不可重复读、幻读
- repeatable read : 可重复读(MySQL默认)
- 产生的问题:幻读
- serializable : 串行化
- 可以解决所有的问题
- 注意: 隔离级别从小到大安全性越来越高,但是效率越来越低
- 数据库查询隔离级别:
- Select @@tx_isolation;
- 数据库设置隔离级别:
- set global transaction isolation leve 级别字符串;
- read uncommitted : 读未提交
八、 JDBC
8.1 JDBC的基本概念
- 概念:Java databases connectivity Java 数据库连接,Java语言操作数据库
- JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动 jar 包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动 jar 包中的实现类。
8.2 jdbc的分包、分层
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CthKIR9w-1573824169888)(C:\Users\Think-Pad\Desktop\JDBC的学习\jdbc的分层.jpg)]
分层、分包:(MVC三层架构)
View(视图层)
Control(控制层)
Model(模型层)
DB(数据库)
- view层作用:视图层,即项目中的界面
- controller层作用:控制层,获取界面上的数据,为界面设置数据;将要实现的功能交给业务层处理
- service层作用:业务层,功能的实现,与controller控制层和数据访问层DAO交互,将对数据库的操作交给DAO数据访问层处理
- dao层作用:数据访问层,用来操作数据库表的数据
- db数据库:这里指MySQL
- domain 实体包:存放 JavaBean
- tools 工具包:存放项目中使用到的工具类
- test 测试包:存放项目功能测试的代码
8.3 快速入门
-
步骤:
- 导入驱动jar包,mysql-connector-java-8.0.13.jar
- 复制mysql-connector-java-8.0.13.jar到项目的libs目录下
- 右键 --> Add As Library
- 注册驱动
- 获取数据库连接对象 Connection
- 定义SQL
- 获取执行SQL语句的对象 Statement
- 执行SQL,接受返回结果
- 处理结果
- 释放资源
- 导入驱动jar包,mysql-connector-java-8.0.13.jar
-
package cn.cehcloud; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; /* JDBC快速入门 */ public class JdbcDemo01 { public static void main(String[] args) throws Exception { // 1. 导入驱动jar包 // 2. 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 3. 获取数据库连接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456"); // 4. 定义sql语句 String sql = "update zlp set phone = '13838895935' where name = 'lisi'"; // 5. 获取执行SQL的对象 Statement Statement stmt = conn.createStatement(); // 6. 执行SQL long count = stmt.executeLargeUpdate(sql); // 7. 处理结果 System.out.println(count); // 8. 释放资源 stmt.close(); conn.close(); } }
8.4 详解各个对象
-
DriverManager : 驱动管理对象
-
功能:
-
注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver) : 注册与给定的驱动程序 DriverManager
写代码使用:Class.forName(“com.mysql.jdbc.Driver”);
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
注意:MySQL5之后的驱动jar包可以省略注册驱动的步骤。
-
获取数据库连接:
- 方法: static Connection getConnection(String url,String user, String password)
- 参数:
- url:指定连接的路径
- 语法: jdbc:mysql://ip地址(域名):端口号/数据库名称
- 例子:jdbc:mysql://localhost:3306/db3
- 细节:如果连接的是本机MySQL服务器,并且MySQL服务器默认端口是3306,则url可以简写为: jdbc:mysql:///数据库名称
- user:用户名
- password:密码
- url:指定连接的路径
-
-
Connection : 数据库连接对象
- 功能:
- 获取执行SQL的对象
- Statement createStatement()
- PreparedStatement prepareStatement(String sql)
- 管理事务:
- 开启事务:setAutocommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务
- 提交事务: commit()
- 回滚事务: rollback()
-
Statement : 执行SQL的对象
- 执行SQL
- boolean execute(String sql) :可以执行任意的SQL 了解
2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
- boolean execute(String sql) :可以执行任意的SQL 了解
- 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功,返回值 >0 的则执行成功,反之,则失效。
3. ResultSet executeQuery(String sql) : 执行DQL(select)语句
- 案例:
package cn.cehcloud.Jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; /* zlp表添加一条记录 insert 语句 */ public class JdbcDemo02 { public static void main(String[] args) { Statement stmt = null; Connection conn = null; // 1.注册驱动 try { Class.forName("com.mysql.jdbc.Driver"); // 2.定义SQL String sql = "insert into zlp values('wangwu','15090163395','2000-05-14')"; // 3.获取Connection 对象 conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456"); // 4.获取执行SQL的对象 Statement stmt = conn.createStatement(); // 5.执行SQL int count = stmt.executeUpdate(sql);// 影响的行数 // 6.处理结果 System.out.println(count); if (count > 0){ System.out.println("添加成功!"); } else{ System.out.println("添加成功!"); } }catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { // 7.释放资源 // 避免空指针异常 if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
- 执行SQL
-
ResultSet : 结果集对象,封装查询结果
- next() : 游标向下移动一行
-
boolean next() : 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
- getXxx(参数):获取数据
-
Xxx :代表数据类型 如: int getInt() , String getSteing()
-
参数:
- int :代表列的编号,从1开始 如:getString(1)
- String:代表列名称。如: getDouble(“name”)
- 案例:
package cn.cehcloud.Jdbc; import java.sql.*; public class JdbcDemo03 { public static void main(String[] args) { Statement stmt = null; Connection conn = null; ResultSet rs = null; try { // 1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2.定义SQL String sql = "select * from zlp"; // 3.获取Connection 对象 conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456"); // 4.获取执行SQL的对象 Statement stmt = conn.createStatement(); // 5.执行SQL rs = stmt.executeQuery(sql); // 6.处理结果 // 6.1 让游标向下移动一行 rs.next(); rs.next(); rs.next(); // 6.2 获取数据 String name = rs.getString("name"); String phone = rs.getString("phone"); Date birthday = rs.getDate("birthday"); System.out.println(name + "-----" + phone + "-----" + birthday); }catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { // 7.释放资源 // 避免空指针异常 if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } if (rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
-
注意:
-
使用步骤:
- 游标向下移动一行
- 判断是否有数据
- 获取数据
-
-
// 循环判断游标是否是最后一行 while(rs.next()){ // 6.2 获取数据 String name = rs.getString("name"); String phone = rs.getString("phone"); Date birthday = rs.getDate("birthday"); System.out.println(name + "-----" + phone + "-----" + birthday); }
练习:
package cn.cehcloud.Jdbc; import java.util.Date; /* 封装Zlp表数据的JavaBean */ public class Zlp { private String name; private String phone; private Date birthday; public String getName(String name) { return this.name; } public void setName(String name) { this.name = name; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "Zlp{" + "name='" + name + '\'' + ", phone='" + phone + '\'' + ", birthday=" + birthday + '}'; } }
package cn.cehcloud.Jdbc; import java.sql.*; import java.util.ArrayList; import java.util.List; /* 定义一个方法,查询Zlp表的数据将其封装为对象,然后装载集合,返回。 */ public class JdbcDemo04 { public static void main(String[] args) { List<Zlp> list = new JdbcDemo04().findAll(); /*for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }*/ System.out.println(list); } /* 查询所有Zlp对象 */ public List<Zlp> findAll(){ Statement stmt = null; ResultSet rs = null; Connection conn = null; List<Zlp> list = null; try { // 1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 2.获取连接 conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456"); // 3.定义SQL String sql = "select * from zlp"; // 4.获取执行SQL的对象 stmt = conn.createStatement(); // 5.执行SQL rs = stmt.executeQuery(sql); // 6.遍历结果,封装对象,装载集合 Zlp zlp = null; list = new ArrayList<Zlp>(); while(rs.next()){ // 获取数据 String name = rs.getString("name"); String phone = rs.getString("phone"); Date birthday = rs.getDate("birthday"); zlp = new Zlp(); zlp.setName(name); zlp.setPhone(phone); zlp.setBirthday(birthday); // 装载集合 list.add(zlp); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); }finally { if (rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } return list; } }
5.PreparedStatement : 执行SQL的对象
-
SQL注入问题:在拼接SQL时,有一些SQL的特殊关键字参与字符串的拼接。会造成安全性问题。
-
输入用户随便,输入密码:a’ or ‘a’ = 'a
-
sql : select * from user where username = ‘hgsi’ and password = ‘a’ or ‘a’ = ‘a’
-
解决SQL注入问题:使用preparedStatement对象来解决
-
预编译的SQL:参数使用?作为站位符
-
步骤:
-
导入驱动jar包 mysql-connector-java-8.0.13.jar
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义SQL
- 注意:SQL的参数使用?作为占位符。如:Select * from user where username = ? and password = ?;
- 获取执行SQL语句的对象 preparedStatement Connection.prepareStament(String sql)
6. 给?赋值
- 方法:setXxx(参数1,参数2)
- 参数1 :?的位置编号 从1开始
- 参数2 :?的值
- 执行SQL,接受返回结果,不需要传递SQL语句
- 处理结果
- 释放资源
- 注意:后期会使用PreparedStatement来完成增删改查的所有操作。
- 可以防止SQL注入
- 效率更高
-
-
package cn.cehcloud.Jdbc; import Utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Scanner; /* 登录方法 需求: 1. 通过键盘录入用户名和密码 2. 判断用户是否登录成功 */ public class JdbcDemo05 { public static void main(String[] args) { // 1.键盘录入,接受用户名和密码 Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String username = sc.next(); System.out.println("请输入密码:"); String password = sc.next(); // 2.调用方法 boolean flag = new JdbcDemo05().login2(username, password); // 3.判断结果,输出不同语句 if (flag){ // 登录成功 System.out.println("登录成功!"); }else { System.out.println("用户名或密码错误!"); } } public boolean login2(String username,String password){ if (username == null || password == null){ return false; } // 连接数据库判断是否登录成功 Connection conn = null; ResultSet rs =null; PreparedStatement pstmt =null; // 1.获取连接 try { conn = JdbcUtils.getConnection(); // 2.定义SQL String sql = "select * from user where username = ? and password = ?"; // 3.获取执行SQL的对象 pstmt = conn.prepareStatement(sql); // 给?赋值 pstmt.setString(1,username); pstmt.setString(2,password); // 4.执行查询,不需要传递SQL rs = pstmt.executeQuery(); // 5.判断 return rs.next(); // 如果有下一行,则返回true } catch (Exception e) { e.printStackTrace(); }finally { JdbcUtils.close(rs,pstmt,conn); } return false; } }
-
8.5 抽取JDBC工具类 :JDBCUtils
-
目的:简化书写
-
分析:
-
注册驱动也抽取
-
抽取一个方法获取连接对象
-
需求:不想传递参数(麻烦),还得保证工具类的通用性。
-
解决:配置文件
jdbc.properties
url =
user =
password =
-
url = jdbc:mysql://localhost:3306/test?characterEncoding = utf8 & useSSL = false & serverTimezone = UTC & rewriteBatchedStatements = true user = root password = 123456 driver = com.mysql.jdbc.Driver
-
-
package Utils; import com.mysql.cj.protocol.Resultset; import javax.xml.transform.Result; import java.io.FileReader; import java.io.IOException; import java.net.URL; import java.sql.*; import java.util.Properties; /* JDBC工具类 */ public class JdbcUtils { private static String url; private static String user; private static String password; private static String driver; /* 文件的读取,只需要读取一次即可拿到这些值。使用静态代码块 */ static { // 1.创建Properties集合类 Properties pro = new Properties(); // 获取src路径下的文件的方式--> ClassLoader 类加载器 ClassLoader classLoader = JdbcUtils.class.getClassLoader(); URL res = classLoader.getResource("jdbc.zlp.properties"); String path = res.getPath(); System.out.println(path); // 2.加载文件 try { pro.load(new FileReader(path)); } catch (IOException e) { e.printStackTrace(); } // 3.获取数据,赋值 url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); // 4.注册驱动 try { Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } } /* 获取连接 */ public static Connection getConnection() throws Exception { return DriverManager.getConnection(url, user, password); } /* 释放资源 */ public static void close(ResultSet rs, Statement stmt, Connection conn) { if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
-
-
package cn.cehcloud.Jdbc; import Utils.JdbcUtils; import com.mysql.cj.protocol.Resultset; import javax.xml.transform.Result; import java.sql.*; import java.util.ArrayList; import java.util.List; /* 演示JDBC工具类 */ public class JdbcDemo04 { public static void main(String[] args) { List<Zlp> list = new JdbcDemo04().findAll2(); /*for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }*/ System.out.println(list); } /* 查询所有Zlp对象 */ public List<Zlp> findAll2(){ Statement stmt = null; ResultSet rs = null; Connection conn = null; List<Zlp> list = null; try { // // 1.注册驱动 // Class.forName("com.mysql.jdbc.Driver"); // // 2.获取连接 // conn = DriverManager.getConnection("jdbc:mysql:///test", "root", "123456"); conn = JdbcUtils.getConnection(); // 3.定义SQL String sql = "select * from zlp"; // 4.获取执行SQL的对象 stmt = conn.createStatement(); // 5.执行SQL rs = stmt.executeQuery(sql); // 6.遍历结果,封装对象,装载集合 Zlp zlp = null; list = new ArrayList<Zlp>(); while(rs.next()){ // 获取数据 String name = rs.getString("name"); String phone = rs.getString("phone"); Date birthday = rs.getDate("birthday"); zlp = new Zlp(); zlp.setName(name); zlp.setPhone(phone); zlp.setBirthday(birthday); // 装载集合 list.add(zlp); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } /*finally { if (rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }*/ JdbcUtils.close(rs,stmt,conn); return list; } }
-
练习:
-
需求: 1. 通过键盘录入用户名和密码 2. 判断用户是否登录成功 * select * from user where username = '" + username + "'and password = '"+ password+"'; * 如果这个是SQL有查询结果,则成功,反之,则失败
-
-
步骤:
-
创建数据库表 user
create table user(id int primary key auto_increment,username varchar(32),password varchar(32));
insert into user values(null,‘zhangsan’,‘123’);
insert into user values(null,‘lisi’,‘456’);
-
url = jdbc:mysql:///test
user = root
password = 123456
driver = com.mysql.jdbc.Driver
package cn.cehcloud.Jdbc;
import Utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
/*
登录方法
需求:
1. 通过键盘录入用户名和密码
2. 判断用户是否登录成功
*/
public class JdbcDemo05 {
public static void main(String[] args) {
// 1.键盘录入,接受用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.next();
System.out.println("请输入密码:");
String password = sc.next();
// 2.调用方法
boolean flag = new JdbcDemo05().login(username, password);
// 3.判断结果,输出不同语句
if (flag){
// 登录成功
System.out.println("登录成功!");
}else {
System.out.println("用户名或密码错误!");
}
}
public boolean login(String username,String password){
if (username == null || password == null){
return false;
}
// 连接数据库判断是否登录成功
Connection conn = null;
Statement stmt = null;
ResultSet rs =null;
// 1.获取连接
try {
conn = JdbcUtils.getConnection();
// 2.定义SQL
String sql = "select * from user where username = '" + username + "'and password = '"+ password+"'";
// 3.获取执行SQL的对象
stmt = conn.createStatement();
// 4.执行查询
rs = stmt.executeQuery(sql);
// 5.判断
return rs.next(); // 如果有下一行,则返回true
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.close(rs,stmt,conn);
}
return false;
}
}
8.6 JDBC控制事务
- 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
- 操作:
- 开启事务
2. 提交事务
3. 回滚事务 - 使用Connection对象来管理事务
- 开启事务
* 开启事务:setAutoCommit(boolean autoCommit) : 调用该方法设置参数为false,即开启事务
* 在执行SQL之前开启事务
* 提交事务:commit()
* 当所有SQL都执行完提交事务
* 回滚事务:rollback()
* 在catch中回滚事务
8.7 数据库连接池
-
概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
-
好处:
- 节约资源
- 用户访问高效
-
实现:
- 标准接口:DataSource javax.sql包下的
- 方法:
- 获取连接:getConnection()
- 归还连接:Connection.close() 如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接
- 方法:
- 一般我们不去实现它,有数据库厂商来实现
- C3P0 : 数据库连接池技术
- Druid : 数据库连接池实现技术,由阿里巴巴提供的
- 标准接口:DataSource javax.sql包下的
-
C3P0 : 数据库连接池技术
- 步骤:
- 导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
- 不要忘记导入数据库驱动jar包
- 定义配置文件:
- 名称:c3p0.properties 或者 c3p0-config.xml
- 路径:直接将文件放在src目录下即可。
- 创建核心对象 数据库连接池对象 ComboPooledDataSource
- 获取连接:getConnection
- 导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
-
c3p0配置的演示
<?xml version="1.0" encoding="utf-8"?> <c3p0-config> <!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?characterEncoding = utf8&useSSL = false&serverTimezone = UTC&rewriteBatchedStatements = true</property> <property name="user">root</property> <property name="password">123456</property> <!-- 连接参数 --> <!-- 初始化申请的连接数量 --> <property name="initialPoolSize">5</property> <!-- 最大的连接数量 --> <property name="maxPoolSize">10</property> <!-- 超时时间--> <property name="checkoutTimeout">3000</property> </default-config> <named-config name="otherc3p0"> </named-config> </c3p0-config>
package cn.cehcloud.Jdbc; import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; /* c3p0的演示 */ public class C3P0Demo01 { public static void main(String[] args) throws Exception { // 1.创建数据库连接池对象,获取DataSource,使用默认配置 DataSource ds = new ComboPooledDataSource(); for (int i = 0; i < 11; i++) { // 2.获取连接 Connection conn = ds.getConnection(); // 3.打印 System.out.println(i + ":" + conn); if (i == 5){ conn.close(); } } } }
-
Druid :数据库连接池实现技术,由阿里巴巴提供的
-
步骤:
-
导入jar包 druid-1.0.9.jar
-
定义配置文件:
- 是properties 形式的
- 可以叫任意名称,可以放在任意目录下
-
获取数据库连接池对象:通过工厂来获取 DruidDataSourceFactory
-
获取连接 : getConnection
driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/test?characterEncoding = utf8 & useSSL = false & serverTimezone = UTC & rewriteBatchedStatements = true username=root password=123456 # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最长等待时间 maxWait=3000 maxIdle=8 minIdle=3
package cn.cehcloud.Jdbc; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.util.Properties; /* Druid演示 */ public class DruidDemo01 { public static void main(String[] args) throws Exception { // 1.导入jar包 // 2.定义配置文件 // 3.加载配置文件 Properties pro = new Properties(); InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); // 4.获取连接池对象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); // 5.获取连接 Connection conn = ds.getConnection(); System.out.println(conn); } }
-
-
-
定义工具类:
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法:
- 获取连接方法: 通过数据库连接池获取连接
- 释放资源
- 获取连接池的方法
-
package Utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /* Druid连接池的工具类 */ public class JDBCUtil { // 1.定义成员变量 DataSource private static DataSource ds; static { try { // 1.加载配置文件 Properties pro = new Properties(); pro.load(JDBCUtil.class.getClassLoader().getResourceAsStream("druid.properties")); // 2.获取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /* 获取连接 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /* 释放资源 */ public static void close(Statement stmt,Connection conn){ /*if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); // 归还连接 } catch (SQLException e) { e.printStackTrace(); } }*/ close(null,stmt,conn); } public static void close(ResultSet rs,Statement stmt, Connection conn){ if (rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null){ try { conn.close(); // 归还连接 } catch (SQLException e) { e.printStackTrace(); } } } /* 获取连接池的方法 */ public static DataSource getDatabaSource(){ return ds; } }
package cn.cehcloud.Jdbc; import Utils.JDBCUtil; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /* 使用新的工具类 */ public class DruidDemo02 { public static void main(String[] args) { /* 完成添加操作,给stu表添加一条记录 */ Connection conn = null; PreparedStatement pstmt = null; try { // 1.获取连接 conn = JDBCUtil.getConnection(); // 2.定义SQL String sql = "insert into stu values(null,?,?)"; // 3.获取pstmt对象 pstmt = conn.prepareStatement(sql); // 4.给?赋值 pstmt.setString(1,"刘七"); pstmt.setString(2,"2000-01-01 00:00:00"); // 5.执行SQL int i = pstmt.executeUpdate(); System.out.println(i); } catch (SQLException e) { e.printStackTrace(); } finally { // 6.释放资源 JDBCUtil.close(pstmt,conn); } } }
8.8 Spring JDBC
-
Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
-
步骤:
- 导入jar包
- 创建JDBCTemplate对象,依赖于数据源DataSource
- JdbcTemple temple = new JdbcTemple(ds);
- 调用JDBCTemplate的方法来完成CRUD的操作
- update() : 执行DML语句。增、删、改语句
- queryForMap() : 查询结果将结果封装为Map集合,将列名作为key,将值作为values 将这条记录封装为一个map集合
- 注意: 这个方法查询的结果集长度只能是1
- queryForList() : 查询结果,将结果封装为 list集合
- 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
- query() : 查询结果,将结果封装为 JavaBean对象
- query的参数:RowMapper
- 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到 JavaBean 的自动封装
- new BeanPropertyRowMapper<类型>(类型.class)
- query的参数:RowMapper
- queryForObject : 查询结果,将结果封装为对象
- 一般用于聚合函数的查询
-
package cn.cehcloud.Jdbc; import Utils.JDBCUtil; import org.springframework.jdbc.core.JdbcTemplate; /* JdbcTemplate入门 */ public class JdbcTemplateDemo01 { public static void main(String[] args) { // 1.导入jar包 // 2.创建JDBCTemplate对象 JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDatabaSource()); // 3.调用方法 String sql = "update stu set name = ? where id = ?"; int count = template.update(sql,"王一" ,3); System.out.println(count); } }