用于存储和管理数据的仓库。 特色: 一、持久化存储数据的,就是一个文件系统。 二、方便存储和管理数据 三、方便了统一的方式操做数据库---SQLjava
使用管理员打开cmd net start mysql 启动MySQL服务器 net stop mysql 关闭MySQL服务器 MySQL登陆; mysql -uroot -proot -p链接的密码 mysql -uIP地址 -p链接目标密码 mysql --host=ip --user=root --password=链接目标的密码 MySQL退出; exit quitmysql
什么是SQL: Structured Query Language 结构化查询语言 其实就是定义了操做全部关系型数据库的规则。每一种数据库操做的方式存在不同的地方,称为“方言”。sql
SQl分类数据库
DDL(Data Definition Language)数据定义语言安全
用来定义数据库对象:数据库,表,列表。关键字:create,drop,alter等服务器
操做数据库:CRUDapp
C(create)建立框架
建立数据库格式: create database 数据库名称; 建立数据库,判断不存在,在建立: create database if not exists 数据库名称; 建立数据库,并指定字符集: create database 数据库名称 character set 字符集名;数据库设计
R(retrieve)查询ide
查询全部数据库的名称: show databases; 查询某个数据库的字符集:查询某个数据库的建立语句 show create database 数据库名称;
U(update)修改
修改数据库的字符集: alter database 数据库名称 character set 字符集名称;
D(delete)删除
删除数据库: drop database 数据库名称; 判断数据库存在,存在再删除: drop database if exists 数据库名称;
使用数据库
查询当前正在使用的数据库名称: select database(); 使用数据库: use 数据库名称;
代码示例
-- 建立数据库 CREATE DATABASE db2;
-- 查询全部数据库 SHOW DATABASES;
-- 查询某个数据库的字符集 SHOW CREATE DATABASE db2;
-- 修改数据库的字符集 ALTER DATABASE db2 CHARACTER SET gbk; SHOW CREATE DATABASE db2;
-- 删除数据库 DROP DATABASE db2; SHOW DATABASES;
-- 使用数据库 USE db1;
-- 查询当前使用的数据库 SELECT DATABASE();
操做表
C(create)建立
格式 : create table 表名( 列表1 数据类型1, 列表2 数据类型2, ... 列表n 数据类型n ); 注意:最后一列,不须要加逗号,符号都是英文
数据库数据类型: 一、int :整数类型 age int 二、double :小数类型 score double 三、date:日期,只包含年月日,yyy-MM-dd 四、datetime:日期,包含年月日时分秒,yyy-MM-dd HH:mm:ss 五、timestamp:时间错类型,包含年月日时分秒,yyy-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 列名 数据类型;
D(delete)删除
删除列: alter table 表名 drop 列名; 删除表: drop table 表名; drop table if exists 表名;
代码示例
-- 新建表 CREATE TABLE teacher( NAME VARCHAR(32), age INT, birthday DATE );
-- 复制表 CREATE TABLE teachers LIKE teacher;
-- 查询数据库中全部表的名称 SHOW TABLES;
-- 查询表格结构 DESC teacher;
-- 修改表名 ALTER TABLE teacher RENAME TO student;
-- 修改表的字符集 ALTER TABLE student CHARACTER SET gbk; ALTER TABLE student CHARACTER SET utf8;
-- 添加一列 DESC student; ALTER TABLE student ADD ids INT; ALTER TABLE student ADD score DOUBLE;
-- 修改列的名称 类型 ALTER TABLE student CHANGE ids id INT; ALTER TABLE student MODIFY id VARCHAR(18);
-- 删除列 ALTER TABLE student DROP id;
-- 删除表 DROP TABLE teachers;
约束
概述
对表中的数据进行限定,保证数据的正确性、有效性和完整性。
非空约束 not null
代码示例
-- 建立表时,添加非空约束 CREATE TABLE stu( id INT, NAME VARCHAR(32) NOT NULL );
-- 删除name的非空约束 ALTER TABLE stu MODIFY NAME VARCHAR(20);
-- 建立表完成后,添加非空约束 ALTER TABLE stu MODIFY NAME VARCHAR(20) NOT NULL;
惟一约束 unique
代码示例
-- 建立表时,添加惟一约束 CREATE TABLE stu( id INT, phone_number VARCHAR(20) UNIQUE );
-- 删除惟一约束 ALTER TABLE stu DROP INDEX phone_number;
-- 建立表完成后,添加惟一约束
ALTER TABLE stu MODIFY id INT UNIQUE;
主键约束 primary key
注意: 含义,非空惟一 一张表只能有一个字段为主键 主键就是表中记录的惟一标识 主键自动增加: 若是某一列是数值类型的,使用auto_increment
代码示例
-- 建立表的时候,添加主键 CREATE TABLE stu( id INT PRIMARY KEY, NAME VARCHAR(20) );
-- 删除主键 ALTER TABLE stu DROP PRIMARY KEY;
-- 建立完表后,添加主键 ALTER TABLE stu MODIFY id INT PRIMARY KEY;
-- 建立表的时候,添加主键自动增加 CREATE TABLE stu( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) );
-- 删除主键自动增加 ALTER TABLE stu MODIFY id INT;
-- 建立表完成后,添加主键自动增加 ALTER TABLE stu MODIFY id INT AUTO_INCREMENT;
外键约束 foreign key
代码示例
-- 建立表的时候,添加外键约束 -- 建立部门表(id,dep_name,dep_location) -- 一方,主表 CREATE TABLE department( id INT PRIMARY KEY AUTO_INCREMENT, dep_name VARCHAR(20), dep_location VARCHAR(20) );
-- 建立员工表(id,name,age,dep_id) -- 多方,从表 CREATE TABLE employee( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20), age INT, dep_id INT, -- 外键对应主表的主键 CONSTRAINT emp_depid_fk FOREIGN KEY (dep_id) REFERENCES department(id) ) ;
-- 删除外键 ALTER TABLE employee DROP FOREIGN KEY emp_dept_fk;
-- 建立完成表后,添加外键 格式: ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称); ALTER TABLE employee ADD CONSTRAINT emp_dept_fk FOREIGN KEY (dep_id) REFERENCES department(id);
级联操做
概述: 在修改和删除主表的主键时,同时更新或删除副表的外键值,称为级联操做 格式: alter table 表名 add constraint 外键名称 foreign key (外键字段名称) references 主表名称(主表列名称) on update cascade on delete cascade; 一、级联更新 : on update cascade 二、级联删除 : on delete cascade
DML(Data Manipulation Language)数据操做语言
用来对数据库中表的数据进行增删改。关键字:insert,delete,update等
增删该表中数据
添加数据
格式: insert into 表名(列名1,列名2,...列名n) values(值1,值2,...,值n); 注意: 一、列名和值要意义对应。 二、若是表名后,不定义列名,则默认给全部列添加值 insert into 表名 values(值1,值2,...,值n);
删除数据
格式: delete from 表名 where 条件; 注意: 一、若是不添加条件,则删除表中全部记录 二、若是删除全部记录 一、delete from 表名;不推荐使用,由于该方式为由多少条记录就执行多少次删除操做 二、truncate table 表名;推荐使用,效率高,先删除表,再建立一张表。
修改数据
格式: update 表名 set 列名1 = 值1,列名2 = 值2,...where 条件; 注意:若是不加任何条件,则会将列表中全部记录所有修改。
代码示例
添加数据 INSERT INTO student(NAME,age)VALUES('张三',18); INSERT INTO student(NAME,age)VALUES('张三',18); INSERT INTO student(NAME,age)VALUES('张三',18); INSERT INTO student VALUES('李四',20,'1994-10-10',99.0); INSERT INTO student VALUES('李四',20,'1994-10-10',99.0);
-- 查询表中全部数据 SELECT * FROM student;
-- 删除数据 DELETE FROM student WHERE NAME='张三';
-- 修改数据 UPDATE student SET birthday = '1986-12-20',score = 98 WHERE NAME='张三';
-- 删除全部数据 DELETE FROM student; TRUNCATE TABLE student;
DQL(Data Query Language) 数据查询语言
用来查询数据库中表的记录(数据)。关键字:select,where等
查询表中的记录(数据)
标准格式
select 字段列表 from 表名列表 where 条件列表 group by 分组字段 having 分组以后的条件 order by 排序 limit 分页限定
基础查询
多个字段的查询
格式: select 字段名1,字段名2,... from 表名; 注意:若是查询全部字段,则能够用*来替代字段列表。
取别名
as 能够省略
计算列
通常可使用四则运算计算一些列的值。(通常只会进行数值型的计算) ifnull(表达式1,表达式2) null参与的运算,通常结果都为null,表达式1:那个字段须要判断是否为null;表达式2:若是字段1为null则用表达式2替换掉。
去除重复
格式: select distinct 字段名1,字段名2,... from 表名;
代码示例
-- 查询表中全部数据 SELECT * FROM student;
-- 去重查询 SELECT DISTINCT address FROM student;
-- 查询年龄大于18小于25 SELECT * FROM student WHERE age BETWEEN 18 AND 25;
-- 查询英语成绩为null SELECT * FROM student WHERE english IS NULL;
-- 查询英语成绩不为null SELECT * FROM student WHERE english IS NOT NULL;
-- 查询姓马的 SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询名字中有德的 SELECT * FROM student WHERE NAME LIKE '%德%';
-- 查询第二个字是化的 SELECT * FROM student WHERE NAME LIKE '_化%';
条件查询
where子句后面跟条件
运算符
<<=>=\=<>(!=) between...and in(集合) like模糊查询 占位符: “_”单个任意字符 “%”多个任意字符 is null and 或 && or 或 || not 或 !
group by分组查询
注意事项
分组语句中,select后面必须跟共性(分组字段,聚合函数)
代码示例
代码示例:
-- 按照性别分组,分别查询男、女同窗的数学平均分 SELECT sex,AVG(math) FROM student GROUP BY sex;
-- 按照性别分组,分别查询男、女同窗的数学平均分,人数 SELECT sex,AVG(math),COUNT(id) FROM student GROUP BY sex;
-- 按照性别分组,分别查询男、女同窗的数学平均分,人数.要求分数低于70不参与 SELECT sex ,AVG(math),COUNT(id) FROM student WHERE math>70 GROUP BY sex;
-- 按照性别分组,分别查询男、女同窗的数学平均分,人数.要求分数低于70不参与,分组后,显示人数大于2的组 SELECT sex,AVG(math),COUNT(id) FROM student WHERE math>70 GROUP BY sex HAVING COUNT(id)>2;
having后面跟条件语句
对分组后数据进行筛选
order by后面跟排序条件字段
代码示例: -- 数学成绩升序(默认) SELECT * FROM student ORDER BY math ASC;
-- 数学成绩升序,而后英语成绩降序 SELECT * FROM student ORDER BY math ASC , english DESC;
-- 总分降序 SELECT * ,math+IFNULL(english,0) AS 总分 FROM student ORDER BY 总分 DESC;
limit分页
limit 索引,每页显示的条数; limit (currentPage - 1) * pageSize;
聚合函数
注意:聚合函数的计算,排除null值。 解决方案: 1. 选择不包含非空的列进行计算 2. IFNULL函数
count 计算个数
max 计算最大值
min 计算最小值
sum 计算和
avg 计算平均值
代码示例
SELECT COUNT(id) FROM student;
多表查询
显示内链接查询
仅能查询有关联的数据(交集)
示例代码
格式: 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/right] outer join 表2 on 条件
/-- 查询全部员工信息,若是员工由部门,则查询部门名称,没有部门,则不显示部门名称/
左外链接(显示左表全部数据、左表和右表有关联的数据): SELECT * FROM emp t1 LEFT OUTER JOIN dept t2 ON t1.dept_id
= t2.id
;
右外链接(显示右表全部数据、右表和左表有关联的数据): SELECT * FROM emp t1 RIGHT OUTER JOIN dept t2 ON t1.dept_id
= t2.id
;
子查询
查询中嵌套查询,称嵌套查询为子查询。
单行单列
代码示例: -- 查询员工工资小于平均工资的人 SELECT * FROM emp WHERE emp.salary < (SELECT AVG(salary) FROM emp);
多行单列
代码示例:
-- 查询'财务部'和'市场部'全部的员工信息 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.dept_id;
-- 普通内链接 SELECT * FROM emp t1,dept t2 WHERE t1.dept_id
= t2.id
AND t1.join_date
> '2011-11-11'
笛卡尔积
有两个集合A,B .取这两个集合的全部组成状况。 要完成多表查询,须要消除无用的数据
DCL(Data Control Language)数据控制语言
用来定义数据库的访问权限和安全级别,及建立用户。关键字:GRANT,REVOKE等
分配不一样用户对数据库操做的不一样权限
建立用户
格式: create user '用户名'@'主机名' identified by '密码';
格式解析: 用户名:将建立的用户名 主机名:指定该用户再那个主机上能够登录,若是是本地用户能够用localhost,若是想让该用户能够从任意远程主机登录,可使用通配符% 密码:该用户的登录密码,密码能够为空,若是为空则该用户能够不须要密码登录服务器
代码示例: 建立user1用户,只能localhost这个服务器登录mysql服务器,密码为123 create user 'user1'@'localhost' identified by '123'; 建立user2用户能够在任何电脑上登录mysql服务器,密码为123 create user 'user2'@'%' identified by '123';
注: 建立的用户名都在mysql数据库中的user表中能够查看到,密码通过了加密。
给用户受权
格式: grant 权限1,权限2...on 数据库名.表名 to '用户名'@'主机名'; 格式解析: grant...on...to受权关键字 权限:授予用户的权限,如:GREATE\ALTER\SELECT\INSERT\UPDATE等,若是要授予全部的权限则使用ALL 数据库名.表名:该用户能够操做那个数控的那些表,若是要授予该用户对全部数据库和表的相应操做权限则能够用*表示 '用户名'@'主机名':给那个用户受权
代码示例: 给user1用户分配对test这个数据库操做的权限:建立表,修改表,插入记录,更新记录,查询 grant create,alter,insert,update,select on test.* to 'user1'@'localhost'; 给user2用户分配全部权限,对数据库的做用表 grant all on . to 'user2'@'%';
撤销权限
格式: revoke 权限1,权限2,... on 数据库.表名 revoke all on test.*from '用户名'@'主机名';
格式解析: revoke...on...from:撤销受权的关键字 权限:用户的权限,如:create\alter\select\insert\update等,全部的权限则用ALL 数据库.表名:对那些数据库的哪些表,若是要取消该用户对全部数据库和表的操做受权则可用*表示 '用户名'@'主机名':给那个用户撤销
代码示例: 撤销user1用户对test数据库全部表的操做的权限 revoke all on test.* from 'user1'@'localhost';
查看权限
格式: show grants for '用户名'@'主机名'; 注:usage是指链接(登录)权限,创建一个用户,就会自动授予其usage权限(默认授予)。
删除用户
格式: drop user '用户名'@'主机名';
修改管理员密码
格式: mysqladmin -uroot -p password 新密码 注:须要在未登录MySQL的状况下操做,新密码不须要加上引号
操做步骤: 一、将 root 管理员的新密码改为 123456 mysqladmin -uroot -p password 123456 二、 要求输入旧密码 Enter password: 三、 使用新密码登陆 mysql -uroot -p123456
修改普通用户密码
格式: set password for '用户名'@'主机名' = password('新密码'); 注意:须要在登录MySQL的状况下操做,新密码要加单引号。
操做步骤: 一、 将'user1'@'localhost'的密码改为'666666' set password for 'user1'@'localhost'=passworld('666666'); 二、使用新密码登陆,老密码登陆不了
忘记了root密码
mysql中忘记了root用户的密码? 1. cmd -- > net stop mysql 中止mysql服务 【 须要管理员运行该cmd 】 2. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables 3. 打开新的cmd窗口,直接输入mysql命令,敲回车。就能够登陆成功 4. use mysql; 5. update user set password = password('你的新密码') where user = 'root'; 6. 关闭两个窗口 7. 打开任务管理器,手动结束mysqld.exe 的进程 8. 启动mysql服务 9. 使用新密码登陆。
SQL通用语法
一、SQl语句能够单行或多行书写,以分号结尾。 二、可使用空格和缩进来加强语句的可读性。 三、MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。 四、3种注释 单行注释:-- 注释内容 或 # 注释内容(MySQL特有)。 多行注释: /* 注释 */
多表之间的的关系
一对一
如:人和身份证 一我的只能由一个身份证,一个身份证只能对应一我的 实现方式: 一对一关系实现,能够在任意一方添加惟一外键指向另外一方的主键。
一对多
如: 部门和员工 一个部门由多个员工,一个员工只能对应一个部门 实现方式: 在多的一方创建外键,指向一的一方的主键
多对多
如:学生与课程 一个学生能够由多门课程,一门课程对应多名学生 实现方式: 多对多关系实现须要借助第三张中间表。中间表至少包含两个字段,这两个字段做为第三张表的外键,分别指向两张表的主键
数据库设计的范式
概念
设计数据库时,须要遵循的一些规范,要遵循后边的范式要求,必须先遵循前边的全部范式要求 设计关系数据库时,听从不一样的规范要求,设计出合理的关系型数据库,这些不一样的规范要求被称为不一样的范式,各类范式呈递次规范,越高的范式数据库冗余越小。 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
第一范式
每一列都是不可分割的原子数据项
第二范式
在1NF的基础上,非码属性必须彻底依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
* 几个概念:
1. 函数依赖:A-->B,若是经过A属性(属性组)的值,能够肯定惟一B属性的值。则称B依赖于A
例如:学号-->姓名。 (学号,课程名称) --> 分数
2. 彻底函数依赖:A-->B, 若是A是一个属性组,则B属性值得肯定须要依赖于A属性组中全部的属性值。
例如:(学号,课程名称) --> 分数
3. 部分函数依赖:A-->B, 若是A是一个属性组,则B属性值得肯定只须要依赖于A属性组中某一些值便可。
例如:(学号,课程名称) -- > 姓名
4. 传递函数依赖:A-->B, B -- >C . 若是经过A属性(属性组)的值,能够肯定惟一B属性的值,在经过B属性(属性组)的值能够肯定惟一C属性的值,则称 C 传递函数依赖于A
例如:学号-->系名,系名-->系主任
5. 码:若是在一张表中,一个属性或属性组,被其余全部属性所彻底依赖,则称这个属性(属性组)为该表的码
例如:该表中码为:(学号,课程名称)
* 主属性:码属性组中的全部属性
* 非主属性:除过码属性组的属性
第三范式
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
命令行
备份: MySQLdump -u用户名 -p密码 数据库名称>保存路径 还原: 一、登陆数据库 二、建立数据库 三、使用数据库 四、执行:source 文件路径
图形化工具
若是一个包含多个步骤的业务操做,被事务管理,那么这些操做要么同时成功,要么同时失败。
事务原理
事务开启以后,全部的操做都会临时保存到事务日志中,事务日志只有在获得commit命令才会去同步到数据表中,其余状况都会清空事务日志(rollback,断开链接)
原理图
事务步骤
一、客服端链接数据库服务器,建立链接时建立此用户临时日志文件。 二、开启事务之后,全部操做都会先写入到临时日志文件中。 三、全部的查询操做从表中查询,但会通过日志文件加工后才返回。 四、若是事务提交则将日志文件中的数据写到表中,不然清空日志文件。
回滚点
在某些成功的操做完成以后,后续的操做有可能成功有可能失败,可是无论成功仍是失败,前面操做都已经成功,能够在当前成功的位置设置一个回滚点。能够供后续失败操做返回到该位置,而不是返回全部操做,这个点称之为回滚点。
设置回滚点
设置回滚点:savepoint 名字 回到回滚点:rollback to 名字
自动提交
mysql就是自动提交的 一条DML(增删改)语句会自动提交一次事务。
开启事务 start transaction
若是出错就,回滚 rollback
提交事务 commit
手动提交
Oracle 数据库默认是手动提交事务 须要先开启事务,再提交 执行过程: 成功:开启事务->执行多条SQL语句->成功提交事务 失败:开启事务->执行多条SQL语句->事务回滚
修改事务的默认提交方法
查看事务的默认提交方式: SELECT @@autocommit; -- 1 表明自动提交 0 表明手动提交 修改默认提交方式: set @@autocommit = 0;
事务的四大特征(ACID)
原子性
是不可分割的最小操做单位,要么同时成功,要么同时失败。
持久性
当事务提交或回滚后,数据库会持久化的保存数据。
隔离性
多个事务之间。相互独立。
一致性
事务操做先后,数据总量不变
事务的隔离级别
多个事务之间隔离的,相互独立的。可是若是多个事务操做同一批数据,则会引起一些问题,设置不一样的隔离级别就能够解决这些问题。
问题
脏读
一个事务,读取到另外一个事务中没有提交的数据
虚读(不可重复读)
在同一个事务中,两次读到的数据不同
幻读
一个事务操做(DML)数据表中全部记录,另外一个事务添加了一条数据,则第一个事务查询不到本身的修改。
read uncommitted:读未提交
存在问题:脏读、虚读、幻读
read committed:读已提交(Oracle)
存在问题:虚读、幻读
repeatable read : 可重复读(MySQL)
存在问题:幻读
serializable : 串行化
解决全部问题
设置隔离级别
查询数据库隔离级别: select @@tx_isolation 数据库设置隔离级别: set global transcation isolation level 级别字符串;
设置事务隔离级别,须要退出MySQL再从新登陆才能看到隔离级别的变化
隔离级别越高,性能越差,安全性越高
概念
JDBC 是 Java 访问数据库的标准规范,真正怎么操做数据库还须要具体的实现类,也就是数据库驱动。每一个 数据库厂商根据自家数据库的通讯格式编写好本身数据库的驱动。因此咱们只须要会调用 JDBC 接口中的方法即 可,数据库驱动由数据库厂商提供。
JDBC经常使用包
java.sql
全部与 JDBC 访问数据库相关的接口和类
javax.sql
数据库扩展包,提供数据库额外的功能。如:链接池
数据库的驱动
由各大数据库厂商提供,须要额外去下载,是对 JDBC 接口实现的类
JDBC访问数据库的步骤
一、注册和加载驱动() 二、获取链接 三、Connection获取Statement对象 四、使用Statement对象执行SQL语句 五、返回结果集 六、释放资源
JDBC的核心API
Class.forName(数据库驱动实现类)
加载和注册数据库驱动,数据库驱动由 mysql 厂商 "com.mysql.jdbc.Driver" 注: 从 JDBC3 开始,目前已经广泛使用的版本。能够不用注册驱动而直接使用。Class.forName 这句话能够省略
DriverManager 类
做用: 一、 管理和注册数据库驱动 二、获得数据库链接对象
经常使用方法
Connection getConnection (String url,String user,String password) 经过链接字符串,用户名,密码来获得数据库的链接对象 Connection getConnection (String url,Properties info) 经过链接字符串,属性对象来获得链接对象
代码示例
代码示例: //获取数据库的链接对象 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
url格式解析: 协议名:子协议://服务器名或 IP 地址:端口号/数据库名?参数=参数值
Connection 接口
具体的实现类由数据库厂家提供,表明一个链接对象,可用于建立 Statement 和 PreparedStatement 对象
经常使用方法
Statement createSteatment() 建立一条SQL语句 PrepareStatement prepareStatement(String sql) 指定预编译的SQL语句,SQL语句中使用占位符? 建立一个语句对象
Statement 接口
表明一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象
经常使用方法
int executeUpdate(String sql) 用于发送DML语句,增删改的操做:insert、update、delete 参数:SQL语句 返回值:返回对数据库影响的行数 ResultSet executeQuery(String sql) 用于发送DQL语句,执行查询的操做,select 参数:SQL语句 返回值:查询的结果集
PreparedStatemen 接口
PreparedStatement 是 Statement 接口的子接口,继承于父接口中全部的方法。它是一个预编译的 SQL 语句
Statement对象每执行一条SQL语句都会先将SQL语句发送给数据库,数据库先编译SQL,再执行。若是有一万条相似的SQL语句,数据库要编译一万次,执行一万次,效率低。
PrepareStatement会先将SQL语句发送给数据库预编译。PrepareStatement会引用预编译后的结果能够屡次传入不一样的参数给’PrepareStatement‘对象并执行。若是有一万条相似的插入数据的语句。数据库只须要预编译一次,传入一万次不一样的参数并执行。减小了SQL语句的编译次数,提升了执行效率。
一、由于有预先编译的功能,提升 SQL 的执行效率。
二、 能够有效的防止 SQL 注入的问题,安全性更高。
三、提升了程序的可读性
使用步骤
一、编写 SQL 语句,未知内容使用?占位:"SELECT * FROM user WHERE name=? AND password=?"; 二、 得到 PreparedStatement 对象 三、 设置实际参数:setXxx(占位符的位置, 真实的值) 四、 执行参数化 SQL 语句 五、 关闭资源
经常使用方法
int executeUpdate() 执行DML,增删改的操做,返回影响的行数 ResultSet executeQuery() 执行DQL,查询的操做,返回结果集
设置参数的方法
void setDouble(int parameterIndex, double x) 将指定参数设置为给定 Java double 值。 void setFloat(int parameterIndex, float x) 将指定参数设置为给定 Java REAL 值。 void setInt(int parameterIndex, int x) 将指定参数设置为给定 Java int 值。 void setLong(int parameterIndex, long x) 将指定参数设置为给定 Java long 值。 void setObject(int parameterIndex, Object x) 使用给定对象设置指定参数的值。 void setString(int parameterIndex, String x) 将指定参数设置为给定 Java String 值。
ResultSet 接口
用于封装数据库查询的结果集,返回给客户端 Java 程序
经常使用方法
Boolean next() 一、游标向下移动1行 二、返回boolean 类型,若是还有下一条记录,返回true,不然返回false 数据类型 getXxx() 一、经过字段名,参数是String类型。返回不一样的类型 二、经过列号,参数是整数,从1开始,返回不一样的类型
getXxx() 方法对应的经常使用数据类型转换
SQL类型 Jdbc对应方法 返回类型 BIT(1) bit(n) getBoolean() boolean TINYINT getByte() byte SMALLINT getShort() short INT getInt() int BIGINT getLong() long CHAR,VARCHAR getString() string Text(Clob) Blob getClob getBlob() Clod Blob DATE getDate() java.sql.Date 只表明日期 TIME getTime() java.sql.Time 只表明时间 TIMESTAMP getTimestamp() java.sql.Timestamp 同时有日期和时间 注意: java.sql.Date、Time、Timestamp(时间戳),三个共同父类是;java.util.Date
常见报错
一、若是光标在第一行以前,使用 rs.getXX()获取列值,报错:Before start of result set 二、 若是光标在最后一行以后,使用 rs.getXX()获取列值,报错:After end of result set 三、 使用完毕之后要关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection
JDBC事务处理
一、获取链接 二、开启事务 三、获取到PrepardStatement 四、使用PreparedStatement执行SQL语句 五、正常,就提交事务 六、出现异常回滚事务 七、最后关闭资源
API
void setAutoCommit(boolean autoCommit) 参数是true或false 若是设置为false,表示关闭自动提交,至关于开启事务(放在执行SQL语句以前) void commit() 提交事务(放在SQL语句执行完成以后) void rollback() 回滚事务(通常放在catch里面)
工具类
public class JDBCUtils { private static String url; private static String user; private static String password; private static String driver; static { try { //建立Properties 集合,是Map的子类,key-value都是字符串 Properties pro = new Properties(); ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL resource = classLoader.getResource("jdbc.properties"); String path = resource.getPath(); pro.load(new FileReader(path)); /* //经过类加载器 加载src/目录下的 datasource.properties文件,返回流 InputStream inputStream = JDBCUtils.class.getClassLoader().getResourceAsStream("datasource.properties"); //把流里的键值对加载到props对象中 pro.load(inputStream); */ //获取配置文件在的value内容 url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); //注册驱动 Class.forName(driver); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, user, password); } 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(); } } } public static void close(Statement stmt, ResultSet rs, 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(); } } } }
概念
其实就是一个容器(集合),存放数据库链接的容器。 当系统初始化好后,容器被建立,容器中会申请一些链接对象,当用户来访问数据库时,从容器中获取链接对象,用户访问完以后,会将链接对象归还给容器。
好处: 节约资源 提升效率(用户访问高效)
c3p0
实现javax.sql包下的DateSource 接口
使用: 一、导入jar包( c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar )和数据库驱动包 二、定义配置文件(文件名: c3p0.properties 或者 c3p0-config.xml) 三、建立对象(数据库链接对象 ComboPooledDataSource) 四、获取链接 getConnection
代码示例
//一、建立数据链接对象 DateSource ds = new ComboPooledDataSource(); //二、获取链接对象 Connection conn = ds.getConnection();
druid
使用步骤: 一、导入jar包(druid-1.0.9.jar) 二、定义配置文件(文件名后缀为:Properties) 三、加载配置文件 (Properties) 四、获取数据库链接池对象:经过工厂类来获取 (DruidDataSourceFactory) 五、获取链接(getConnection)
代码示例
//加载配置文件 Properties pro = new Properties(); InputStream is = DruidDemo.class.getClassLodaer().getRespurceAsStream("druid.properties"); pro.load(is); //获取链接池对象 DataSource ds = DruidDataSourceFactory.createDateSource(pro); //获取链接 Connection conn = ds.getConnection();
工具类
一、定义一个类 JDBCUtils 二、提供静态代码块加载配置文件,初始化链接对象 三、提供方法: 一、快速链接方法:经过数据库链接池获取链接 二、释放资源 三、获取链接池的方法
代码示例
public class JDBCUtils { private static DataSource ds; static { Properties pro = new Properties(); try { pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); 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 getDataSource() { return ds; } }
Spring JDBC
Spring框架对JDBC的简单封装,提供了一个JDBCTemplate对象简化JDBC的开发
使用步骤
一、导入jar包 二、建立JDBCTemplate对象。依赖于数据源DataSource(JdbcTemplate trmplate = new JdbcTemplate(ds)); 三、调用JdbcTemplate的方法来完成CRUD的操做
经常使用方法
update(String sql, Object... args) 执行DML语句,增、删、改 queryForMap() 将查询的结果封装为map集合,将列做为key,将值做为value,将这条记录封装为一个map集合(查询的结果集长度只能是1) queryForList() 查询结果将结果封装为list集合(将每一条记录封装为一个map集合,再将map集合封装到List集合中) query(String sql, new BeanPropertyRowMapper<T>(T.class), Object... args) 返回的对象的集合,适合返回多行多列的状况 queryForObject(String sql, new BeanPropertyRowMapper<T>(T.class), Object... args) 返回的单个对象, 适合查询一条记录的状况 queryForObject(String sql, 包装类型.class, Object... args) 返回的单行单列的包装类型,适合聚合函数状况
代码示例
public class JdbcTemplateDemo02 { //获取JdbcTemplate对象 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //修改id1001的salary数据 @Test public void test1() { String sql = "update emp set salary = 8000 where id = 1001"; int count = template.update(sql); System.out.println(count); } //添加id1015记录 @Test public void test2(){ String sql = "insert into emp(id,name,dept_id) values(?,?,?)"; int count = template.update(sql, 1015, "郭靖", 10); System.out.println(count); } //删除id为1015的记录 @Test public void test3(){ String sql = "delete from emp where id =?"; int update = template.update(sql, 1015); System.out.println(update); } //queryForMap()查询的结果只能为1条 @Test public void test4(){ String sql = "select * from emp where id = ?"; Map<String, Object> map = template.queryForMap(sql, 1001); System.out.println(map); } //查询全部记录,将其封装为LIst @Test public void test5(){ String sql = "select * from emp"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> map : list) { System.out.println(map); } } //查询全部记录,将其封装为Emp对象的list集合 @Test public void test6(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : list) { System.out.println(emp); } } //查询总记录数 @Test public void test7(){ String sql = "select count(id) from emp"; Long aLong = template.queryForObject(sql, long.class); System.out.println(aLong); } //查询id1001的信息。使用queryForObject(sql, new BeanPropertyRowMapper<Emp>(Emp.class), 1001)方法 @Test public void test8(){ String sql = "select * from emp where id = ?"; Emp emp = template.queryForObject(sql, new BeanPropertyRowMapper<Emp>(Emp.class), 1001); System.out.println(emp); } //查询id1002的信息。使用query(sql, new BeanPropertyRowMapper<>(Emp.class), 1002)方法 @Test public void test9(){ String sql = "select * from emp where id = ?"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<>(Emp.class), 1002); System.out.println(list.size()); System.out.println(list); } }